文档主页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  JavaScript 存储程序数据类型和参数处理

27.3.4 JavaScript 存储程序数据类型和参数处理

MLE 存储程序的输入和输出参数以及返回数据类型支持大多数 MySQL 数据类型。数据类型如下所示:

  • 整数:支持 MySQL 整数数据类型的所有变体和别名,包括 TINYINTSMALLINTMEDIUMINTINTBIGINT

    所有这些类型都支持 SIGNEDUNSIGNED

    还支持 BOOLSERIAL,并将其视为整数类型。

  • 字符串:支持 CHARVARCHARTEXTBLOB 字符串类型。

    除以下情况外,这些类型在 MySQL 服务器中的支持方式相同:

    1. 字符串参数和返回类型必须使用 utf8mb4 字符集;对这些类型使用任何其他字符集都会引发错误。此限制适用于参数和返回类型声明;服务器会尝试在必要时使用其他字符集将参数转换为 utfmb4,就像使用 SQL 存储程序一样。

    2. LONGTEXT 值支持的最大长度为 1073741799 个字符。

    BLOB 类型的支持包括对 BINARYVARBINARY 的支持。

    还支持 MySQL JSON 数据类型。

  • 浮点数:支持 FLOATDOUBLE 及其别名。 REAL 也被视为浮点数,但 UNSIGNED FLOATUNSIGNED DOUBLE 在 MySQL 中已弃用,MLE 不支持。

  • 时间类型:支持 DATEDATETIMETIMESTAMP,并将其转换为 JavaScript Date 值。 TIME 值被视为字符串;YEAR 值被视为数字。

    第一次执行给定的 JavaScript 存储过程时,它会与当前 MySQL 会话时区相关联,并且该时区会继续被存储程序使用,即使 MySQL 会话时区同时发生更改,在 MLE 组件会话期间或直到调用 mle_session_reset()。有关更多信息,请参阅本节后面的时区支持

输入参数(ININOUT 参数)会根据下表所示的映射自动转换为 JavaScript 类型:

表 27.1 类型转换:MySQL 到 JavaScript

MySQL 类型JavaScript 类型
TINYINTSMALLINTMEDIUMINTINTBOOLBIGINTSERIAL如果安全:Number;否则:String
FLOATDOUBLENumber
CHARVARCHARTINYTEXTTEXTMEDIUMTEXTLONGTEXTString
TINYBLOBBLOBMEDIUMBLOBLONGBLOBBINARYVARBINARYUint8Array
DATEDATETIMETIMESTAMPDate
TIMEString
YEARNumber

转换为或来自 MySQL 整数(其值超出 -(253-1) (-9007199254740991) 到 253-1 (9007199254740991) 范围)的转换是有损的。可以使用 mle_set_session_state() 更改当前会话将 MySQL 整数转换为 JavaScript 的方式;默认行为等效于使用 UNSAFE_STRING 作为 integer_type 的值调用此函数。有关更多信息,请参阅该函数的说明。

所有列出的类型都支持 SQL NULL,并在需要时与 JavaScript null 相互转换。

JavaScript(与 SQL 不同)是一种动态类型语言,这意味着返回类型仅在执行时才知道。JavaScript 返回值和输出参数(OUTINOUT 参数)会根据下表所示的映射自动转换回预期的 MySQL 类型:

表 27.2 类型转换:JavaScript 到 MySQL

从 JavaScript 类型到 MySQL TINYINTSMALLINTMEDIUMINTINTBIGINTBOOLEANSERIAL到 MySQL CHARVARCHAR到 MySQL FLOATDOUBLE到 MySQL TINYTEXTTEXTMEDIUMTEXTLONGTEXT到 MySQL MySQL TINYBLOBBLOBMEDIUMBLOBLONGBLOBBINARYVARBINARY
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]使用现有的字符串值;检查字符串的长度是否在预期范围内错误
SymbolObject引发无效类型转换错误转换为 String;检查结果长度是否在预期范围内引发无效类型转换错误转换为 String;检查结果长度是否在预期范围内 [e]错误
数组引发无效类型转换错误转换为 String;检查结果长度是否在预期范围内引发无效类型转换错误转换为 String;检查结果长度是否在预期范围内 [e]转换为字节数组;检查结果是否在预期大小内
nullundefinedNULLNULLNULLNULLNULL

[a] JavaScript 中的 Infinity-Infinity 被视为超出范围的值。

[b] JavaScript 中的 NaN 会引发无效类型转换错误。

[c] 这是使用 Math.round() 完成的。

[d] 非数值会引发无效类型转换错误

[e] 支持的最大字符串长度为 1073741799


表 27.3 类型转换:JavaScript 日期到 MySQL

JavaScript 类型MySQL DATEMySQL DATETIME, TIMESTAMPMySQL YEAR
nullundefinedNULLNULLNULL
Date保留值不变,将任何时间部分舍入到最接近的秒。保留值不变。Date 中提取年份
可转换为 JavaScript Date 的类型(格式化字符串)将值强制转换为 JavaScript Date 并进行相应处理将值强制转换为 JavaScript Date 并进行相应处理如果值包含 4 位数年份,则使用它。
不可转换为 JavaScript Date 的类型无效类型转换错误无效类型转换错误如果值包含 4 位数年份,则使用它。

传递 MySQL 零日期 (00-00-0000) 或日期中的零值(例如 00-01-2023)会导致创建 DateInvalid Date 实例。 当传递无效的 MySQL 日期(例如 2 月 31 日)时,MLE 会使用无效的日期和时间组件值调用 JavaScript Date 构造函数。

MySQL TIME 类型作为字符串处理,并在 MySQL 内部进行验证。有关详细信息,请参阅 第 13.2.3 节“TIME 类型”

表 27.4 类型转换:MySQL JSON 到 JavaScript

MySQL JSON 类型JavaScript 类型
NULL, JSON NULLnull
JSON 对象对象
JSON 数组数组
JSON 布尔值Boolean
JSON INTEGER, JSON DOUBLE, JSON DECIMALNumber
JSON 字符串String [a]
JSON DATETIME, JSON DATE, JSON TIMEString
JSON BLOB, JSON OPAQUEString

[a] MySQL JSON 字符串在转换为 Javascript 字符串时将变为未加引号的字符串。


表 27.5 类型转换:JavaScript 到 MySQL JSON

JavaScript 类型MySQL JSON 类型
null, undefinedNULL
Boolean错误 [a]
Number错误 [a]
String
  • 可以解析为 JSON:JSON 字符串、JSON 对象或 JSON 数组

  • 无法解析为 JSON:错误

  • 'null': JSON null

BigInt错误 [b]
对象JSON 对象或错误(请参阅表后文本)
数组JSON 数组
Symbol
  • 在对象内部:忽略

  • 在数组内部:JSON null

标量值:错误

[a] 容器(例如 JSON 数组或 JSON 对象)内的值将被转换(Number 值可能会丢失精度)。标量值会引发错误。

[b] JavaScript BigInt 值不能转换为 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/NauruJapanMET,但不支持 leap/Pacific/Naururight/Pacific/Nauru

在存储程序执行后执行范围检查和无效类型转换检查。强制转换在 JavaScript 内部使用类型构造函数(例如 Number()String())完成;使用 Math.round() 执行舍入到 Integer 的操作。

可以使用相同的参数标识符从例程主体内部访问 JavaScript 存储程序定义中命名的输入参数(ININOUT 参数)。输出参数(INOUTOUT 参数)也可在 JavaScript 存储过程中使用。可以使用相同的参数标识符通过 JavaScript 赋值 (=) 运算符设置值。与 SQL 存储过程的 OUT 参数一样,初始值设置为 JavaScript null

注意

不应使用 JavaScript 存储程序内部的 letvarconst 覆盖程序参数。这样做会将它们转换为程序本地的变量,并使使用同名参数传递到程序中的任何值都无法访问。

示例

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 不能用于设置存储过程的 OUTINOUT 参数值;这些值必须在例程中显式设置。