MLE 存储程序的输入和输出参数以及返回数据类型支持大多数 MySQL 数据类型。数据类型如下所示:
整数:支持 MySQL 整数数据类型的所有变体和别名,包括
TINYINT、SMALLINT、MEDIUMINT、INT和BIGINT。所有这些类型都支持
SIGNED和UNSIGNED。字符串:支持
CHAR、VARCHAR、TEXT和BLOB字符串类型。除以下情况外,这些类型在 MySQL 服务器中的支持方式相同:
字符串参数和返回类型必须使用
utf8mb4字符集;对这些类型使用任何其他字符集都会引发错误。此限制适用于参数和返回类型声明;服务器会尝试在必要时使用其他字符集将参数值转换为utfmb4,就像使用 SQL 存储程序一样。LONGTEXT值支持的最大长度为 1073741799 个字符。
对
BLOB类型的支持包括对BINARY和VARBINARY的支持。还支持 MySQL
JSON数据类型。浮点数:支持
FLOAT和DOUBLE及其别名。REAL也被视为浮点数,但UNSIGNED FLOAT和UNSIGNED DOUBLE在 MySQL 中已弃用,MLE 不支持。时间类型:支持
DATE、DATETIME和TIMESTAMP,并将其转换为 JavaScriptDate值。TIME值被视为字符串;YEAR值被视为数字。第一次执行给定的 JavaScript 存储过程时,它会与当前 MySQL 会话时区相关联,并且该时区会继续被存储程序使用,即使 MySQL 会话时区同时发生更改,在 MLE 组件会话期间或直到调用
mle_session_reset()。有关更多信息,请参阅本节后面的时区支持。
输入参数(IN 和 INOUT 参数)会根据下表所示的映射自动转换为 JavaScript 类型:
表 27.1 类型转换:MySQL 到 JavaScript
| MySQL 类型 | JavaScript 类型 |
|---|---|
TINYINT、SMALLINT、MEDIUMINT、INT、BOOL、BIGINT 或 SERIAL | 如果安全:Number;否则:String |
FLOAT 或 DOUBLE | Number |
CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT 或 LONGTEXT | String |
TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB、BINARY 或 VARBINARY | Uint8Array |
DATE、DATETIME 或 TIMESTAMP | Date |
TIME | String |
YEAR | Number |
转换为或来自 MySQL 整数(其值超出 -(253-1) (-9007199254740991) 到 253-1 (9007199254740991) 范围)的转换是有损的。可以使用 mle_set_session_state() 更改当前会话将 MySQL 整数转换为 JavaScript 的方式;默认行为等效于使用 UNSAFE_STRING 作为 integer_type 的值调用此函数。有关更多信息,请参阅该函数的说明。
所有列出的类型都支持 SQL NULL,并在需要时与 JavaScript null 相互转换。
JavaScript(与 SQL 不同)是一种动态类型语言,这意味着返回类型仅在执行时才知道。JavaScript 返回值和输出参数(OUT 和 INOUT 参数)会根据下表所示的映射自动转换回预期的 MySQL 类型:
表 27.2 类型转换:JavaScript 到 MySQL
| 从 JavaScript 类型 | 到 MySQL TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT、BOOLEAN 或 SERIAL | 到 MySQL CHAR 或 VARCHAR | 到 MySQL FLOAT 或 DOUBLE | 到 MySQL TINYTEXT、TEXT、MEDIUMTEXT 或 LONGTEXT | 到 MySQL MySQL TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB、BINARY、VARBINARY |
|---|---|---|---|---|---|
Boolean | 强制转换为整数 | 转换为字符串;检查结果长度是否在预期范围内 | 强制转换为浮点数 | 如果 JavaScript 布尔值为 true:转换为 “true”;如果 JavaScript 布尔值为 false:转换为 “false” | 错误 |
Number | 将值舍入为 Integer;检查值是否超出范围 [a] [b] [c] | 转换为 String;检查结果长度是否在预期范围内 | 保留值;检查这是否超出范围 [a] [b] | 转换为 String;检查结果长度是否在预期范围内 | 错误 |
BigInteger | 保留值;检查是否超出范围 [a] [b] | 转换为 String;检查结果长度是否在预期范围内 | 强制转换为 Float;检查结果是否超出范围 [d] | 转换为 String;检查结果长度是否在预期范围内 | 错误 |
String | 解析为数字并舍入为整数;检查值是否超出范围 | 保留值;检查长度是否在范围内 | 将值解析为 Float,检查值是否超出范围值 [d] | 使用现有的字符串值;检查字符串的长度是否在预期范围内 | 错误 |
Symbol 或 Object | 引发无效类型转换错误 | 转换为 String;检查结果长度是否在预期范围内 | 引发无效类型转换错误 | 转换为 String;检查结果长度是否在预期范围内 [e] | 错误 |
数组 | 引发无效类型转换错误 | 转换为 String;检查结果长度是否在预期范围内 | 引发无效类型转换错误 | 转换为 String;检查结果长度是否在预期范围内 [e] | 转换为字节数组;检查结果是否在预期大小内 |
null 或 undefined | NULL | NULL | NULL | NULL | NULL |
表 27.3 类型转换:JavaScript 日期到 MySQL
| JavaScript 类型 | MySQL DATE | MySQL DATETIME, TIMESTAMP | MySQL YEAR |
|---|---|---|---|
null 或 undefined | NULL | NULL | NULL |
Date | 保留值不变,将任何时间部分舍入到最接近的秒。 | 保留值不变。 | 从 Date 中提取年份 |
可转换为 JavaScript Date 的类型(格式化字符串) | 将值强制转换为 JavaScript Date 并进行相应处理 | 将值强制转换为 JavaScript Date 并进行相应处理 | 如果值包含 4 位数年份,则使用它。 |
不可转换为 JavaScript Date 的类型 | 无效类型转换错误 | 无效类型转换错误 | 如果值包含 4 位数年份,则使用它。 |
传递 MySQL 零日期 (00-00-0000) 或日期中的零值(例如 00-01-2023)会导致创建 Date 的 Invalid Date 实例。 当传递无效的 MySQL 日期(例如 2 月 31 日)时,MLE 会使用无效的日期和时间组件值调用 JavaScript Date 构造函数。
MySQL TIME 类型作为字符串处理,并在 MySQL 内部进行验证。有关详细信息,请参阅 第 13.2.3 节“TIME 类型”。
表 27.5 类型转换:JavaScript 到 MySQL JSON
可能可以也可能无法将 Javascript Object 转换为 MySQL JSON,具体取决于如何为相关对象实现 toJSON()。这里列出了一些示例
JavaScript
Date类的toJSON()方法将Date转换为具有无效 JSON 语法的字符串,从而引发转换错误。对于
Set类,toJSON()返回"{}",这是一个有效的 JSON 字符串。对于类似 JSON 的对象,
toJSON()返回有效的 JSON 字符串。
时区支持。 JavaScript 存储程序使用在其首次调用时生效的 MySQL 会话时区。此存储程序在此会话期间将一直使用此时区。
更改 MySQL 会话时区不会自动反映在已使用并因此已缓存的存储程序中。要使它们使用新的时区,请调用 mle_session_reset() 清除缓存;在此之后,存储程序将使用新的时区。
支持的时区类型如下所示
与 UTC 的时区偏移量,例如
+11:00或-07:15。支持在 IANA 时区数据库 中定义的时区,但使用闰秒的配置除外。例如,支持
Pacific/Nauru、Japan和MET,但不支持leap/Pacific/Nauru和right/Pacific/Nauru。
在存储程序执行后执行范围检查和无效类型转换检查。强制转换在 JavaScript 内部使用类型构造函数(例如 Number() 和 String())完成;使用 Math.round() 执行舍入到 Integer 的操作。
可以使用相同的参数标识符从例程主体内部访问 JavaScript 存储程序定义中命名的输入参数(IN 或 INOUT 参数)。输出参数(INOUT 和 OUT 参数)也可在 JavaScript 存储过程中使用。可以使用相同的参数标识符通过 JavaScript 赋值 (=) 运算符设置值。与 SQL 存储过程的 OUT 参数一样,初始值设置为 JavaScript null。
您不应使用 JavaScript 存储程序内部的 let、var 或 const 覆盖程序参数。这样做会将它们转换为程序本地的变量,并使使用同名参数传递到程序中的任何值都无法访问。
示例
mysql> CREATE FUNCTION myfunc(x INT)
-> RETURNS INT LANGUAGE JAVASCRIPT AS
-> $$
$> var x
$>
$> return 2*x
$> $$
-> ;
Query OK, 0 rows affected (0.03 sec)
mysql> SELECT myfunc(10);
ERROR 6000 (HY000): MLE-Type> Cannot convert value 'NaN' to INT
from MLE in 'myfunc(10)'
JavaScript return 语句应用于在存储函数中返回标量值。在存储过程中,此语句不返回值,仅退出代码块(这可能会也可能不会退出例程,具体取决于程序流程)。return 不能用于设置存储过程的 OUT 或 INOUT 参数值;这些值必须在例程中显式设置。