SQL 与处理程序语言之间的数据类型映射

本主题内容:

您编写的存储过程或用户定义函数是从 SQL 调用的,因此,它们接收和返回 SQL 数据类型的值。但是,其基础处理程序将使用处理程序语言(例如 Java、Python 或 Scala)的数据类型。在运行时,Snowflake 会在 SQL 类型与处理程序类型之间转换实参和返回值。

请注意,Snowflake 也会在以下情况下进行这些转换:

  • 动态构造使用处理程序变量值的 SQL 语句时。

  • 将处理程序变量的值绑定到预编译语句时。

本主题介绍 SQL 数据和类型与受支持的处理程序语言的数据和类型之间的有效映射。编写处理程序时,请参考以下内容选择数据类型。

有关 Snowflake SQL 数据类型的信息,请参阅 数据类型摘要

SQL-Java 数据类型映射

下表显示了 SQL 与 Java 之间的类型映射。这些映射通常适用于传递给过程或函数的实参,以及从过程或函数返回的值。但是,也有一些例外情况(在脚注中列出)。

请注意,某些 SQL 数据类型(例如 NUMBER)与多种 Java 数据类型(例如 intlong 等)兼容。在这些情况下,可以使用任何具有足够容量来保存将传递的实际值的 Java 数据类型。如果将 SQL 值传递给不兼容的 Java 数据类型(或者反过来),则 Snowflake 将引发错误。

SQL 类型

Java 类型

备注

ARRAY

String[]

将数组的元素格式化为字符串。

ARRAY

String

将数组格式化为 JSON 字符串(例如 [1, "foo", null])。

BINARY

byte[]

BINARY

String

以十六进制对二进制字符串进行编码。[4]

BINARY

InputStream

将 BINARY 值公开为字节序列。

BOOLEAN

boolean

不能为 null。

BOOLEAN

Boolean

BOOLEAN

String

[4]

DATE

java.sql.Date

DATE

String

将日期格式化为 YYYY-MM-DD[4]

FLOAT

double

不能为 null。

FLOAT

Double

FLOAT

float

不能为 null。可能造成精度损失。

FLOAT

Float

可能造成精度损失。

FLOAT

String

可能造成精度损失(浮点数 -> 字符串转换是有损的)。

GEOGRAPHY

String

将地理数据格式化为 ` GeoJSON <https://tools.ietf.org/html/rfc7946 (https://tools.ietf.org/html/rfc7946)> `_ 。

GEOGRAPHY

Geography

[5]

MAP

Map<String, String>

输出格式为 MAP(VARCHAR、VARCHAR)。

NUMBER

short

不能为 null。必须适合短整型的范围(没有小数部分,整数部分不能超过最大/最小短整型值)。

NUMBER

Short

必须适合短整型的范围(没有小数部分,整数部分不能超过最大/最小短整型值)。

NUMBER

int

不能为 null。必须适合整型的范围(没有小数部分,整数部分不能超过最大/最小整型值)。

NUMBER

Integer

必须适合整型的范围(没有小数部分,整数部分不能超过最大/最小整型值)。

NUMBER

long

不能为 null。必须适合长整型的范围(没有小数部分,整数部分不能超过最大/最小长整型值)。

NUMBER

Long

必须适合长整型的范围(没有小数部分,整数部分不能超过最大/最小长整型值)。

NUMBER

java.math.BigDecimal

NUMBER

java.math.BigInteger

必须适合 BigInteger 的范围(无小数部分)。

NUMBER

String

OBJECT

Map<String, String>

映射的键是对象的键,值格式化为字符串。

OBJECT

String

将对象格式化为 JSON 字符串(例如 {"x": 3, "y": true})。

TIME

java.sql.Time

[3]

TIME

String

将时间格式化为 HH:MI:SS.SSSSSSSSS,其中小数秒部分取决于时间的精度。[3]

TIMESTAMP_LTZ

java.sql.Timestamp

必须适合 java.sql.Timestamp 的范围。[3]

TIMESTAMP_LTZ

String

输出格式为 DY, DD MON YYYY HH24:MI:SS TZHTZM[1][3][4]

TIMESTAMP_NTZ

java.sql.Timestamp

必须适合 java.sql.Timestamp 的范围。将挂钟时间视为与 Unix 时间戳的偏移量(实际上强制实行 UTC 时区)。[3]

TIMESTAMP_NTZ

String

将挂钟时间视为与 Unix 时间戳的偏移量(实际上强制实行 UTC 时区)。输出格式为 DY, DD MON YYYY HH:MI:SS[2][3][4]

TIMESTAMP_TZ

java.sql.Timestamp

必须适合 java.sql.Timestamp 的范围。[3]

TIMESTAMP_TZ

String

输出格式为 DY, DD MON YYYY HH24:MI:SS TZHTZM[1][3][4]

VARCHAR

String

VARIANT

Variant

Variant 数据类型是Snowpark 包中的一个类。有关更多信息,请参阅 用户定义函数支持的 Snowpark 包类型。有关示例,请参阅 将 VARIANT 值传递给内联 Java UDF

数组

Java UDFs 可以接收以下任何 Java 数据类型的数组:

数据类型

备注

String

boolean

Snowflake ARRAY 必须仅包含 BOOLEAN 元素,不得包含任何 NULL 值。

double

float

Snowflake ARRAY 必须包含以下任一元素,并且不得包含任何 NULL 值。

  • FLOAT 元素。

  • 定点 元素(具有任意小数位数)。

int

long

short

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 版本

描述

Geography

1.2.0 及更高版本

表示 Snowflake GEOGRAPHY 类型。有关使用 Geography 数据类型的示例,请参阅 将 GEOGRAPHY 值传递给内联 Java UDF

Variant

1.4.0 及更高版本

表示 Snowflake VARIANT 数据。有关使用 Variant 数据类型的示例,请参阅 将 VARIANT 值传递给内联 Java UDF

将 Snowpark 包指定为依赖项

在开发使用 Snowpark 包的 UDF 代码时,需要设置开发环境,以便可以编译和运行具有 Snowpark 依赖项的代码。有关更多信息,请参阅 为 Snowpark Java 设置其他开发环境

通过执行 CREATE FUNCTION 语句来部署 UDF 时,可以将 Snowpark 包指定为依赖项,而无需将 JAR 文件上传到暂存区(该库已在 Snowflake 中)。为此,请在 PACKAGES 子句中指定此包的名称和版本。有关语法示例,请参阅 将 GEOGRAPHY 值传递给内联 Java UDF

SQL-JavaScript 数据类型映射

下表显示了 Snowflake SQL 数据类型和相应的 JavaScript 数据类型:

SQL 数据类型

JavaScript 数据类型

备注

ARRAY

JSON

BOOLEAN

number

truefalse 分别用 10 表示。请注意,此行为在未来版本中可能会改变,因此您应该依赖 JavaScript 真实性,而不是直接的值比较。

DATE

date

GEOGRAPHY、GEOMETRY

JSON

REAL、FLOAT、FLOAT8、FLOAT4、DOUBLE、DOUBLE PRECISION

number

TIME

string

TIMESTAMP、TIMESTAMP_LTZ、TIMESTAMP_NTZ、TIMESTAMP_TZ

dateSfDate

当时间戳作为实参传递给存储过程时,时间戳将转换为 JavaScript date 对象。在其他情况下(例如,从 ResultSet 中检索时),时间戳将转换为 SfDate 对象。有关 SfDate 数据类型(非标准 JavaScript 数据类型)的更多详细信息,请参阅 JavaScript 存储过程 API

VARCHAR、CHAR、CHARACTER、STRING、TEXT

string

VARIANT

JSON

备注

部分 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

list

当 Python 数据类型转换为 ARRAY 时,如果有任何嵌入的 Python 十进制数据,则嵌入的 Python 十进制数据将转换为 ARRAY 中的字符串。

BINARY

bytes

BOOLEAN

bool

DATE

datetime.date

FLOAT

float

浮点运算可能会有较小的舍入误差,这些误差可能会累积,尤其是在聚合函数处理大量行时。如果以不同的顺序处理行,则每次执行查询时,舍入误差可能会有所不同。有关更多信息,请参阅 数值数据类型:浮点

GEOGRAPHY、GEOMETRY

dict

将地理数据格式化为 ` GeoJSON <https://tools.ietf.org/html/rfc7946 (https://tools.ietf.org/html/rfc7946)> `_ ,然后将其转换为 Python 字典。

MAP

dict

不支持将 MAP 作为返回类型。

NUMBER

intdecimal.Decimal

如果 NUMBER 类型的小数位数为 0,则使用 Python int 类型。否则使用 decimal.Decimal 类型。

OBJECT

dict

当 Python 数据类型转换为 OBJECT 时,如果有任何嵌入的 Python 十进制数据,则嵌入的 Python 十进制数据将转换为 OBJECT 中的字符串。

TIME

datetime.time

尽管 Snowflake 可以存储纳秒级精度的时间值,但 Python datetime.time 类型仅保持毫秒级精度。Snowflake 和 Python 数据类型之间的转换可以将有效精度降低到毫秒。

TIMESTAMP_LTZ

datetime.datetime

使用本地时区将内部 UTC 时间转换为本地“无感知”的日期时间。需要的返回类型为“无感知”的日期时间。

TIMESTAMP_NTZ

datetime.datetime

直接转换为“无感知”的日期时间。需要的返回类型为“无感知”的日期时间。

TIMESTAMP_TZ

datetime.datetime

转换为包含时区信息的“有感知”的日期时间。需要的返回类型为“有感知”的日期时间。

VARCHAR

str

VARIANT

dictlistintfloatstrbool

对于实参,每个 Variant 行都会动态转换为 Python 类型,对于返回值则会反过来转换。以下类型转换为字符串而不是 Python 原生类型:decimal、binary、date、time、timestamp_ltz、timestamp_ntz、timestamp_tz。当 Python 数据类型转换为 VARIANT 时,如果有任何嵌入的 Python 十进制数据,则嵌入的 Python 十进制数据将转换为 VARIANT 中的字符串。

VECTOR

memoryview

SQL-Scala 数据类型映射

除了支持 SQL-Java 数据类型映射 中列出的 Java 类型 之外,Snowflake 还支持以下 Scala 数据类型:

SQL 数据类型

Scala 类型

备注

ARRAY

Array[String]

BINARY

Array[Byte]

BOOLEAN

BooleanOption[Boolean]

DOUBLE

DoubleOption[Double]

FLOAT

FloatOption[Float]

MAP

Map[String, String]

输出格式为 MAP(VARCHAR、VARCHAR)。

NUMBER

支持以下类型:

  • IntOption[Int]

  • LongOption[Long]

OBJECT

Map[String, String]

VARCHAR

String

VARIANT

String

根据所表示的类型来格式化值。Variant null 格式化为字符串“null”。

对于 DATETIMESTAMP,请使用 SQL-Java 数据类型映射 中列出的 Java 类型。

语言: 中文