用户定义的函数概述¶
您可以编写用户定义函数 (UDFs) 来扩展系统,以执行 Snowflake 提供的 内置系统定义函数 无法执行的操作。创建 UDF 后,可以多次重用它。函数总是通过指定表达式来显式返回值,因此它是计算和返回值的不错选择。
您可以使用 UDFs 来扩展内置功能或封装您组织的标准计算。可以以类似于内置函数的方式调用您创建的 UDFs。
您可以使用 受支持的语言 之一编写的 UDF 逻辑(其处理程序)。有了处理程序后,您可以使用 Snowflake 中包含的几种工具中的任何一种 创建 UDF,然后 执行 UDF。
UDF 类似于存储过程,但两者存在重要区别。有关更多信息,请参阅 选择是编写存储过程还是用户定义函数。
UDF 只是扩展 Snowflake 的一种方式。对于其他内容,请参阅以下内容:
用户定义的函数变体¶
您可以根据函数必须满足的输入和输出要求,在几种变体之一中编写 UDF。
变体 |
描述 |
---|---|
用户定义的函数 (UDF) |
也称为 标量函数,为每个输入行返回一个输出行。返回的行由单个列/值组成。 |
用户定义的聚合函数 (UDAF) |
对多行值进行运算,以执行求和、求平均值、计数、查找最小值或最大值、标准差和估计值等数学运算,以及一些非数学运算。 |
用户定义的表函数 (UDTF) |
返回每个输入行的表格值。 |
矢量化用户定义的函数 (UDF) |
以 Pandas DataFrames (https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html) 的形式接收成批的输入行,并以 Pandas 数组 (https://pandas.pydata.org/docs/reference/api/pandas.array.html) 或 序列 (https://pandas.pydata.org/docs/reference/series.html) 的形式返回成批的结果。 |
矢量化用户定义的表函数 (UDTF) |
以 Pandas DataFrames (https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html) 的形式接收成批的输入行,并返回表格结果。 |
支持的语言和工具¶
您可以使用多种工具中的任何一种(具体取决于您喜欢的工作方式),创建 和管理 UDFs(以及其他 Snowflake 实体)。
语言 |
方法 |
支持 |
---|---|---|
SQL 使用 Java、JavaScript、Python、Scala 或 SQL 处理程序 |
在 Snowflake 中编写 SQL 代码,以创建和管理 Snowflake 实体。使用支持的处理程序语言之一编写函数的逻辑。 |
|
Java、Python 或 Scala |
在客户端,为推送到 Snowflake 以进行处理的操作编写代码。 |
|
命令行界面 |
使用命令行创建和管理 Snowflake 实体,将属性指定为 JSON 对象的属性。 |
|
Python |
在客户端,执行命令以使用 Python 创建函数,使用支持的处理程序语言之一编写函数的处理程序。 |
|
REST |
请求 RESTful 端点以创建和管理 Snowflake 实体。 |
选择语言时,还要考虑以下几点:
支持的处理程序位置。 并非所有语言都支持在暂存区中引用处理程序(处理程序代码必须是内联的)。有关更多信息,请参阅 将处理程序代码保持内联或保留在暂存区。
处理程序是否生成可共享的 UDF。 可共享的 UDF 可与 Snowflake Secure Data Sharing 功能一起使用。
语言 |
处理程序位置 |
共享 |
---|---|---|
Java |
内联或暂存 |
否 [1] |
JavaScript |
内联 |
是 |
Python |
内联或暂存 |
否 [2] |
Scala |
内联或暂存 |
否 [3] |
SQL |
内联 |
是 |
注意事项¶
如果查询调用 UDF 来访问暂存文件,则如果 SQL 语句还查询调用 任何 UDF 或 UDTF 的视图,则无论视图中的函数是否访问暂存文件,操作都将失败并显示用户错误。
UDTFs 可以并行处理多个文件;但是,UDFs 当前以串行方式处理文件。解决方法是使用 GROUP BY 子句对子查询中的行进行分组。有关示例,请参阅 使用 UDTF 处理 CSV。
目前,如果在查询运行时修改或删除了查询中引用的暂存文件,则函数调用将失败并显示错误。
如果在 UDF 的处理程序代码中指定 CURRENT_DATABASE 或 CURRENT_SCHEMA 函数,该函数会返回包含 UDF 的数据库或架构,而不是会话中使用的数据库或架构。
UDF 示例¶
以下示例中的代码用于创建一个名为 addone
的 UDF 处理程序,其中包含一个使用 Python 编写的处理程序。处理程序函数为 addone_py
。此 UDF 返回一个 int
。
CREATE OR REPLACE FUNCTION addone(i int)
RETURNS INT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
HANDLER = 'addone_py'
as
$$
def addone_py(i):
return i+1
$$;
以下示例中的代码用于执行 addone
UDF。
SELECT addone(3);
准则和约束¶
- Snowflake 约束:
您可以通过在 Snowflake 约束内进行开发来确保 Snowflake 环境的稳定性。有关更多信息,请参阅 设计保持在 Snowflake 施加的约束范围内的处理程序。
- 命名:
请确保在命名函数时避免与其他函数发生冲突。有关更多信息,请参阅 命名和重载过程和 UDFs。
- 实参:
指定实参,并指示哪些实参是可选的。有关更多信息,请参阅 定义 UDFs 和存储过程的实参。
- 数据类型映射:
每种处理程序语言的数据类型与用于实参和返回值的 SQL 类型之间都有一套单独的映射。有关每种语言的映射的更多信息,请参阅 SQL 与处理程序语言之间的数据类型映射。
处理程序写入¶
- 处理程序语言:
有关编写处理程序的特定于语言的内容,请参阅 支持的语言和工具。
- 外部网络访问:
您可以使用 外部网络访问 访问外部网络位置。您可以创建对 Snowflake 外部的特定网络位置的安全访问,然后从处理程序代码中使用该访问。
- 日志记录、跟踪和指标:
您可以通过 获取日志消息、跟踪事件和指标数据 来记录代码活动,将数据存储在以后可以查询的数据库中。
安全¶
您可以授予对象使用 UDF 或 UDTF 执行特定 SQL 操作所需的权限。有关更多信息,请参阅 授予用户定义的函数的权限
函数与存储过程共享某些安全问题。有关更多信息,请参阅以下内容:
您可以通过遵循 UDFs 和过程的安全实践 中所述的最佳实践,帮助存储过程的处理程序代码安全地执行
确保对不应访问敏感信息的用户隐藏敏感信息。有关更多信息,请参阅 使用安全 UDFs 和存储过程保护敏感信息
处理程序代码部署¶
在创建函数时,可以将实现函数逻辑的处理程序指定为与函数定义内联的代码,也可以指定为定义外部的代码,例如打包并复制到暂存区的编译代码。
有关更多信息,请参阅 将处理程序代码保持内联或保留在暂存区。