SQL 与处理程序语言之间的数据类型映射¶
本主题内容:
您编写的存储过程或用户定义函数是从 SQL 调用的,因此,它们接收和返回 SQL 数据类型的值。但是,其基础处理程序将使用处理程序语言(例如 Java、Python 或 Scala)的数据类型。在运行时,Snowflake 会在 SQL 类型与处理程序类型之间转换实参和返回值。
请注意,Snowflake 也会在以下情况下进行这些转换:
动态构造使用处理程序变量值的 SQL 语句时。
将处理程序变量的值绑定到预编译语句时。
本主题介绍 SQL 数据和类型与受支持的处理程序语言的数据和类型之间的有效映射。编写处理程序时,请参考以下内容选择数据类型。
有关 Snowflake SQL 数据类型的信息,请参阅 数据类型摘要。
SQL-Java 数据类型映射¶
下表显示了 SQL 与 Java 之间的类型映射。这些映射通常适用于传递给过程或函数的实参,以及从过程或函数返回的值。但是,也有一些例外情况(在脚注中列出)。
请注意,某些 SQL 数据类型(例如 NUMBER)与多种 Java 数据类型(例如 int
、long
等)兼容。在这些情况下,可以使用任何具有足够容量来保存将传递的实际值的 Java 数据类型。如果将 SQL 值传递给不兼容的 Java 数据类型(或者反过来),则 Snowflake 将引发错误。
SQL 类型 |
Java 类型 |
备注 |
---|---|---|
ARRAY |
|
将数组的元素格式化为字符串。 |
ARRAY |
|
将数组格式化为 JSON 字符串(例如 |
BINARY |
|
|
BINARY |
|
以十六进制对二进制字符串进行编码。[4] |
BINARY |
|
将 BINARY 值公开为字节序列。 |
BOOLEAN |
|
不能为 null。 |
BOOLEAN |
|
|
BOOLEAN |
|
|
DATE |
|
|
DATE |
|
将日期格式化为 |
FLOAT |
|
不能为 null。 |
FLOAT |
|
|
FLOAT |
|
不能为 null。可能造成精度损失。 |
FLOAT |
|
可能造成精度损失。 |
FLOAT |
|
可能造成精度损失(浮点数 -> 字符串转换是有损的)。 |
GEOGRAPHY |
|
将地理数据格式化为 ` GeoJSON <https://tools.ietf.org/html/rfc7946 (https://tools.ietf.org/html/rfc7946)> `_ 。 |
GEOGRAPHY |
||
MAP |
|
输出格式为 MAP(VARCHAR、VARCHAR)。 |
NUMBER |
|
不能为 null。必须适合短整型的范围(没有小数部分,整数部分不能超过最大/最小短整型值)。 |
NUMBER |
|
必须适合短整型的范围(没有小数部分,整数部分不能超过最大/最小短整型值)。 |
NUMBER |
|
不能为 null。必须适合整型的范围(没有小数部分,整数部分不能超过最大/最小整型值)。 |
NUMBER |
|
必须适合整型的范围(没有小数部分,整数部分不能超过最大/最小整型值)。 |
NUMBER |
|
不能为 null。必须适合长整型的范围(没有小数部分,整数部分不能超过最大/最小长整型值)。 |
NUMBER |
|
必须适合长整型的范围(没有小数部分,整数部分不能超过最大/最小长整型值)。 |
NUMBER |
|
|
NUMBER |
|
必须适合 BigInteger 的范围(无小数部分)。 |
NUMBER |
|
|
OBJECT |
|
映射的键是对象的键,值格式化为字符串。 |
OBJECT |
|
将对象格式化为 JSON 字符串(例如 |
TIME |
|
|
TIME |
|
将时间格式化为 |
TIMESTAMP_LTZ |
|
必须适合 java.sql.Timestamp 的范围。[3] |
TIMESTAMP_LTZ |
|
|
TIMESTAMP_NTZ |
|
必须适合 java.sql.Timestamp 的范围。将挂钟时间视为与 Unix 时间戳的偏移量(实际上强制实行 UTC 时区)。[3] |
TIMESTAMP_NTZ |
|
将挂钟时间视为与 Unix 时间戳的偏移量(实际上强制实行 UTC 时区)。输出格式为 |
TIMESTAMP_TZ |
|
必须适合 java.sql.Timestamp 的范围。[3] |
TIMESTAMP_TZ |
|
|
VARCHAR |
|
|
VARIANT |
Variant 数据类型是Snowpark 包中的一个类。有关更多信息,请参阅 用户定义函数支持的 Snowpark 包类型。有关示例,请参阅 将 VARIANT 值传递给内联 Java UDF。 |
数组¶
Java UDFs 可以接收以下任何 Java 数据类型的数组:
数据类型 |
备注 |
---|---|
|
|
|
Snowflake ARRAY 必须仅包含 BOOLEAN 元素,不得包含任何 NULL 值。 |
|
Snowflake ARRAY 必须包含以下任一元素,并且不得包含任何 NULL 值。 |
|
Snowflake ARRAY 必须仅包含小数位数为 0 的 定点 元素,不得包含任何 NULL 值。 |
NULL 值¶
Snowflake 支持两个不同的 NULL 值:SQL NULL
和 VARIANT 的 JSON null
。(有关 Snowflake VARIANT NULL 的信息,请参阅 NULL 值。)
Java 支持一个 null
值,该值仅适用于非基元数据类型。
Java 处理程序的 SQL NULL
实参会转换为 Java null
值,但仅适用于支持 null
的 Java 数据类型。
返回的 Java null
值将转换回 SQL NULL
。
TIMESTAMP_LTZ 值和时区¶
Java UDF 在很大程度上与调用它的环境相隔离。但是,时区是从调用环境继承的。如果调用方的会话在调用 Java UDF 之前设置了默认时区,则 Java UDF 具有相同的默认时区。Java UDF 使用与 Snowflake SQL 所用的原生 TIMEZONE 相同的 `IANA 时区数据库 `_ 数据(即时区数据库的版本 2021a 中的数据)。
用户定义函数支持的 Snowpark 包类型¶
在用户定义的函数中,可以使用 Snowflake Snowpark Java 包 中包含的特定类型子集。尽管这些类型设计为用于 Snowpark 代码,但由于其中有几种类型提供了便利,因此也支持在 UDFs 中使用这几种类型。(有关 Snowpark 的更多信息,请参阅 Snowpark 文档。)
备注
用 Java、Python 和 Scala 编写存储过程时,需要使用 Snowpark 库。因此,可以在此类存储过程中不受限制地使用 Snowpark 类型。
UDF 代码支持下表中的 Snowpark 类型。请勿在 UDF 代码中使用其他 Snowpark 类型;该代码不支持这些类型。
Snowpark 类型 |
所需的 Snowpark 版本 |
描述 |
---|---|---|
1.2.0 及更高版本 |
表示 Snowflake GEOGRAPHY 类型。有关使用 |
|
1.4.0 及更高版本 |
表示 Snowflake VARIANT 数据。有关使用 |
将 Snowpark 包指定为依赖项¶
在开发使用 Snowpark 包的 UDF 代码时,需要设置开发环境,以便可以编译和运行具有 Snowpark 依赖项的代码。有关更多信息,请参阅 为 Snowpark Java 设置其他开发环境。
通过执行 CREATE FUNCTION 语句来部署 UDF 时,可以将 Snowpark 包指定为依赖项,而无需将 JAR 文件上传到暂存区(该库已在 Snowflake 中)。为此,请在 PACKAGES
子句中指定此包的名称和版本。有关语法示例,请参阅 将 GEOGRAPHY 值传递给内联 Java UDF。
SQL-JavaScript 数据类型映射¶
下表显示了 Snowflake SQL 数据类型和相应的 JavaScript 数据类型:
SQL 数据类型 |
JavaScript 数据类型 |
备注 |
---|---|---|
ARRAY |
|
|
BOOLEAN |
|
值 |
DATE |
|
|
GEOGRAPHY、GEOMETRY |
|
|
REAL、FLOAT、FLOAT8、FLOAT4、DOUBLE、DOUBLE PRECISION |
|
|
TIME |
|
|
TIMESTAMP、TIMESTAMP_LTZ、TIMESTAMP_NTZ、TIMESTAMP_TZ |
|
当时间戳作为实参传递给存储过程时,时间戳将转换为 JavaScript |
VARCHAR、CHAR、CHARACTER、STRING、TEXT |
|
|
VARIANT |
|
备注¶
部分 Snowflake SQL 数据类型没有相应的 JavaScript 数据类型。例如,JavaScript 不直接支持 INTEGER 或 NUMBER 数据类型。在这些情况下,应将 SQL 数据类型转换为适当的备选数据类型。例如,可以将 SQL INTEGER 转换为 SQL FLOAT,然后可以将后者转换为 number
数据类型的 JavaScript 值。
下表显示了不兼容的 SQL 数据类型的适当转换:
不兼容的 SQL 数据类型 |
兼容的 SQL 数据类型 |
---|---|
BINARY |
Uint8Array |
INTEGER |
FLOAT |
NUMBER、NUMERIC、DECIMAL |
FLOAT |
OBJECT |
Uint8Array |
返回值时¶
如果 JavaScript 中的 return
语句返回的数据类型与存储过程声明的返回类型不同,则如果可能,JavaScript 值会转换为 SQL 数据类型。例如,如果返回一个数字,但存储过程声明为返回字符串,则该数字将转换为 JavaScript 中的字符串,然后复制到在 SQL 语句中返回的字符串。(请注意,此行为可能会隐藏某些 JavaScript 编程错误,例如返回错误的数据类型。)
如果不存在有效的类型转换,则会发生错误。
绑定值时¶
将 JavaScript 变量绑定到 SQL 语句时,Snowflake 会从 JavaScript 数据类型转换为 SQL 数据类型。可以绑定以下 JavaScript 数据类型的变量:
数字
字符串
SfDate
有关
SfDate
数据类型(非标准 JavaScript 数据类型)的更多详细信息,请参阅 JavaScript 存储过程 API。
有关绑定的更多信息(包括一些示例),请参阅 绑定变量。
以下主题也可能很有帮助:
SQL-Python 数据类型映射¶
下表显示了 SQL 与 Python 之间的类型映射。这些映射通常适用于传递给 Python 处理程序的实参,以及从该处理程序返回的值。
SQL 类型 |
Python 类型 |
备注 |
---|---|---|
ARRAY |
|
当 Python 数据类型转换为 ARRAY 时,如果有任何嵌入的 Python 十进制数据,则嵌入的 Python 十进制数据将转换为 ARRAY 中的字符串。 |
BINARY |
|
|
BOOLEAN |
|
|
DATE |
|
|
FLOAT |
|
浮点运算可能会有较小的舍入误差,这些误差可能会累积,尤其是在聚合函数处理大量行时。如果以不同的顺序处理行,则每次执行查询时,舍入误差可能会有所不同。有关更多信息,请参阅 数值数据类型:浮点。 |
GEOGRAPHY、GEOMETRY |
|
将地理数据格式化为 ` GeoJSON <https://tools.ietf.org/html/rfc7946 (https://tools.ietf.org/html/rfc7946)> `_ ,然后将其转换为 Python 字典。 |
MAP |
|
不支持将 MAP 作为返回类型。 |
NUMBER |
|
如果 NUMBER 类型的小数位数为 0,则使用 Python int 类型。否则使用 decimal.Decimal 类型。 |
OBJECT |
|
当 Python 数据类型转换为 OBJECT 时,如果有任何嵌入的 Python 十进制数据,则嵌入的 Python 十进制数据将转换为 OBJECT 中的字符串。 |
TIME |
|
尽管 Snowflake 可以存储纳秒级精度的时间值,但 Python datetime.time 类型仅保持毫秒级精度。Snowflake 和 Python 数据类型之间的转换可以将有效精度降低到毫秒。 |
TIMESTAMP_LTZ |
|
使用本地时区将内部 UTC 时间转换为本地“无感知”的日期时间。需要的返回类型为“无感知”的日期时间。 |
TIMESTAMP_NTZ |
|
直接转换为“无感知”的日期时间。需要的返回类型为“无感知”的日期时间。 |
TIMESTAMP_TZ |
|
转换为包含时区信息的“有感知”的日期时间。需要的返回类型为“有感知”的日期时间。 |
VARCHAR |
|
|
VARIANT |
|
对于实参,每个 Variant 行都会动态转换为 Python 类型,对于返回值则会反过来转换。以下类型转换为字符串而不是 Python 原生类型:decimal、binary、date、time、timestamp_ltz、timestamp_ntz、timestamp_tz。当 Python 数据类型转换为 VARIANT 时,如果有任何嵌入的 Python 十进制数据,则嵌入的 Python 十进制数据将转换为 VARIANT 中的字符串。 |
VECTOR |
|
SQL-Scala 数据类型映射¶
除了支持 SQL-Java 数据类型映射 中列出的 Java 类型 之外,Snowflake 还支持以下 Scala 数据类型:
SQL 数据类型 |
Scala 类型 |
备注 |
---|---|---|
ARRAY |
|
|
BINARY |
|
|
BOOLEAN |
|
|
DOUBLE |
|
|
FLOAT |
|
|
MAP |
|
输出格式为 MAP(VARCHAR、VARCHAR)。 |
NUMBER |
支持以下类型:
|
|
OBJECT |
|
|
VARCHAR |
|
|
VARIANT |
|
根据所表示的类型来格式化值。Variant null 格式化为字符串“null”。 |
对于 DATE 和 TIMESTAMP,请使用 SQL-Java 数据类型映射 中列出的 Java 类型。