将处理程序代码保持内联或保留在暂存区¶
使用 SQL 创建用户定义函数 (UDF) 或存储过程时,可以指定处理程序代码是与创建它的 SQL 内嵌在一起,还是在 SQL 外部,例如在暂存区中的文件中。本主题描述了区别。
本主题内容:
实际区别¶
内联处理程序的优势¶
通常更容易实现。使用开发工具验证代码正常工作后,可以通过将代码复制到创建函数或过程时执行的 SQL 语句中来部署代码。可以在该位置维护代码,用 SQL 语句更新代码(例如用 ALTER FUNCTION 或 ALTER PROCEDURE),而不必在其他位置维护代码。
暂存处理程序的优势¶
使用暂存处理程序时,您可以执行以下操作:
使用之前编译的代码,例如已经编译了输出但没有源代码时。
使用可能太大而无法粘贴到创建函数或过程的 SQL 语句中的处理程序代码。内联代码对源代码大小有上限。
重用来自多个函数或过程的处理程序代码。暂存代码可以包含多个处理程序函数,其中每个函数可以由不同的 UDF 或过程使用。当创建多个 UDFs 或过程时,它们可以分别指定相同的处理程序文件,但可以指定在该文件中实现的不同处理程序函数。
相反,内联函数或过程的处理程序通常仅包含一个可调用函数。该可调用函数可以调用其他函数,而这些其他函数可以在同一个代码文件或其他暂存代码文件中定义。
可能会发现使用现有的测试和调试工具来完成大部分开发工作更方便。如果代码很大或很复杂,尤其如此。
使用内联处理程序¶
使用内联处理程序时,应将处理程序源代码包含在创建函数或过程的 SQL 语句的 AS 子句中。例如,可以在 CREATE FUNCTION 或 CREATE PROCEDURE 语句本身的 AS 子句中包含处理程序代码。
在 AS 子句中,使用单引号或一对美元符号 ($$
) 将代码包围。使用双美元符号可能会更容易,例如当源代码包含嵌入式单引号时。
如果需要编译内联处理程序源代码(比如用 Java 或 Scala 编写的处理程序),Snowflake 会编译源代码并存储输出(例如 JAR 文件)供以后使用。可以选择使用 TARGET_PATH 子句指定结果输出文件的位置。
Snowflake 通过以下方式管理编译后的输出:
如果 SQL 语句(例如 CREATE FUNCTION)使用 TARGET_PATH 来指定输出文件的位置,Snowflake 会编译一次代码,并保留编译后的输出供将来使用。
如果 SQL 语句未指定文件的位置,Snowflake 会为调用该函数或过程的每条 SQL 语句重新编译代码。SQL 语句完成后,Snowflake 会自动清理文件。
备注
作为使用内联 Java 或 Scala 处理程序时的最佳实践,请考虑为 TARGET_PATH 参数指定一个值。这可以提高性能,因为 Snowflake 会重复使用处理程序代码的编译结果,而不是每次调用存储过程或 UDF 时都重新编译代码。
注意
当以内联方式定义处理程序代码时,它将被获取为元数据。如果不希望将代码获取为元数据,可以用其他方式部署,例如使用 暂存处理程序。
客户应确保在使用 Snowflake 服务时,不会将个人数据(用户对象除外)、敏感数据、出口管制数据或其他受监管数据作为元数据输入。有关更多信息,请参阅 Snowflake 中的元数据字段。
使用 Java 处理程序的内联示例¶
以下示例中的代码用 Java 创建了一个带有内联处理程序的 MYPROC 存储过程。处理程序是 MyJavaClass
类的 run
方法。
CREATE OR REPLACE PROCEDURE MYPROC(fromTable STRING, toTable STRING, count INT)
RETURNS STRING
LANGUAGE JAVA
RUNTIME_VERSION = '11'
PACKAGES = ('com.snowflake:snowpark:latest')
HANDLER = 'MyJavaClass.run'
AS
$$
import com.snowflake.snowpark_java.*;
public class MyJavaClass {
public String run(Session session, String fromTable, String toTable, int count) {
session.table(fromTable).limit(count).write().saveAsTable(toTable);
return "SUCCESS";
}
}
$$;
有关 CREATE PROCEDURE 参考信息,请参阅 CREATE PROCEDURE。
使用暂存处理程序¶
使用暂存处理程序时,可以使用 IMPORTS 子句引用另一个位置的处理程序,例如一个暂存区。例如,可以使用 SQL 语句的 IMPORTS 子句指定处理程序的路径,如 CREATE PROCEDURE 或 CREATE FUNCTION。
暂存处理程序以供函数或过程使用¶
以下内容介绍如何向执行函数或过程的环境中添加处理程序文件。
如有必要,例如使用用 Java 或 Scala 编写的处理程序,编译并打包处理程序代码以上传到暂存区。有关构建工具的更多信息,请参阅 打包处理程序代码。
对于用 Python 编写的处理程序,可以使用处理程序模块源代码。
将处理程序文件上传到 为代码提供依赖项 中所述的暂存区。
创建函数或过程时引用处理程序文件。
可以在 IMPORTS 子句中引用处理程序文件,如 引用依赖项 中所述。
以下示例中的代码创建了一个名为
my_udf
的 UDF,其处理程序MyClass.myFunction
是用 Java 编写的。代码的 IMPORTS 子句指定名为my_handler.jar
的处理程序文件位于暂存区子目录handlers
中的暂存区mystage
。在运行时,Snowflake 会将处理程序 JAR 添加到类路径中。CREATE FUNCTION my_udf(i NUMBER) RETURNS NUMBER LANGUAGE JAVA IMPORTS = ('@mystage/handlers/my_handler.jar') HANDLER = 'MyClass.myFunction'
有关 CREATE FUNCTION 参考信息,请参阅 CREATE FUNCTION。
注意事项和最佳实践¶
如果删除或重命名处理程序文件,则无法再调用该函数或过程。如果需要更新处理程序文件,请执行以下操作:
首先确保没有调用使用该处理程序的函数或过程。
使用 PUT 命令上传新的处理程序文件。如果在上传新的处理程序文件时,旧的处理程序文件仍在暂存区中,请使用
PUT
命令的OVERWRITE=TRUE
子句来覆盖旧的处理程序文件。