将处理程序代码保持内联或保留在暂存区¶
使用 SQL 创建用户定义函数 (UDF) 或存储过程时,可以指定处理程序代码是与创建它的 SQL 内嵌在一起,还是在 SQL 外部,例如在暂存区中的文件中。本主题描述了区别。
并非所有语言都支持使用内联或暂存处理程序。有关支持的语言的列表,请参阅 存储过程 或 UDFs 的语言选择。
实际区别¶
内联处理程序的优势¶
采用内联处理程序的函数和过程可能更易于管理。使用开发工具验证代码正常工作后,可以通过将代码复制到创建函数或过程时执行的 SQL 语句中来部署代码。可以在该位置维护代码,用 SQL 语句更新代码(例如用 ALTER FUNCTION 或 ALTER PROCEDURE),而不必在其他位置维护代码。
暂存处理程序的优势¶
使用暂存处理程序时,您可以执行以下操作:
使用您在 Snowflake 使用的 Git 存储库中单独管理的代码。
有关更多信息,请参阅 Snowflake 如何使用远程 Git 存储库。
使用之前编译的代码,例如当您已编译输出但没有源代码时。
使用处理程序代码,该代码可能太大而无法粘贴到在创建函数或过程时使用的 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 PROCEDURE 参考信息,请参阅 CREATE PROCEDURE。
使用暂存处理程序¶
使用暂存处理程序时,可以使用 IMPORTS 子句引用另一个位置的处理程序,例如一个暂存区。例如,可以使用 SQL 语句的 IMPORTS 子句指定处理程序的路径,如 CREATE PROCEDURE 或 CREATE FUNCTION。
使用 HANDLER 子句引用处理程序函数名时,您必须使用其包含类或模块的名称限定函数名。这与内联处理程序相反,内联处理程序有时允许您仅通过名称引用处理程序函数。
暂存处理程序以供函数或过程使用¶
以下内容介绍如何向执行函数或过程的环境中添加处理程序文件。
如有必要,例如使用用 Java 或 Scala 编写的处理程序,编译并打包处理程序代码以上传到暂存区。有关构建工具的更多信息,请参阅 打包处理程序代码。
对于用 Python 编写的处理程序,可以使用处理程序模块源代码。
当您的处理程序代码用 Java 或 Scala 编写时,构建一个 JAR 文件,其中包含存储过程所需的所有依赖项。稍后,您需要将 JAR 文件上传到暂存区,并引用 CREATE PROCEDURE 语句中的文件 JAR。如果要上传和引用的 JAR 文件较少,则此过程会更简单。
使用 Maven 构建具有依赖项的 JAR 文件。
如果您使用 Maven 构建和打包代码,则可以使用 ` Maven Assembly 插件 <https://maven.apache.org/plugins/maven-assembly-plugin/index.html (https://maven.apache.org/plugins/maven-assembly-plugin/index.html)>`_ 创建包含所有依赖项的 JAR 文件。有关更多信息,请参阅 使用 Maven 打包 Java 或 Scala 处理程序代码。
使用其他工具构建具有依赖项的 JAR 文件。
如果您未使用 Maven,请参阅所用构建工具的文档,了解有关使用所有依赖项构建 JAR 文件的说明。
例如,如果您使用的是 IntelliJ IDEA 项目,请参阅 ` 关于设置构件配置的说明 <https://www.jetbrains.com/help/idea/compiling-applications.html#configure_artifact (https://www.jetbrains.com/help/idea/compiling-applications.html#configure_artifact)>`__。
将处理程序文件上传到 为代码提供依赖项 中所述的暂存区。
如果您的处理程序来自 与 Snowflake 一起使用的 Git 存储库,则您可能需要从远程存储库 将最新版本提取 到 Snowflake Git 存储库。
创建函数或过程时引用处理程序文件。
可以在 IMPORTS 子句中引用处理程序文件,如 引用依赖项 中所述。
以下示例中的代码创建了一个名为
my_udf的 UDF,其处理程序MyClass.myFunction是用 Java 编写的。代码的 IMPORTS 子句指定名为my_handler.jar的处理程序文件位于暂存区子目录handlers中的暂存区mystage。在运行时,Snowflake 会将处理程序 JAR 添加到类路径中。有关 CREATE FUNCTION 参考信息,请参阅 CREATE FUNCTION。
注意事项和最佳实践¶
如果删除或重命名处理程序文件,则无法再调用该函数或过程。如果需要更新处理程序文件,请执行以下操作:
首先确保没有调用使用该处理程序的函数或过程。
使用 PUT 命令上传新的处理程序文件。如果在上传新的处理程序文件时,旧的处理程序文件仍在暂存区中,请使用
PUT命令的OVERWRITE=TRUE子句来覆盖旧的处理程序文件。