1

与用户定义的函数相比,我需要一些关于雪花存储过程的最佳用例的指导。请问是否有关于一种比另一种更合适的场景的指导方针?我正在尝试为我的项目做出正确的选择。谢谢。

4

2 回答 2

1
  • Snowflake 存储过程是用 JavaScript 编写的。UDF 可以用 JavaScript 或 SQL 编写。
  • 存储过程允许返回值,但不需要返回值。
  • 存储过程被称为独立语句,而不是语句的一部分(SELECT myfunc(x) vs CALL myproc(x))。
  • 存储过程返回的值与函数返回的值不同,不能直接在 SQL 中使用。

https://docs.snowflake.com/en/sql-reference/stored-procedures-overview.html#differences-between-stored-procedures-and-udfs

以及选择创建存储过程或 UDF 的指南:

https://docs.snowflake.com/en/sql-reference/stored-procedures-overview.html#choosing-to-create-a-stored-procedure-or-a-udf

于 2021-09-18T23:47:36.947 回答
0

重要的区别是对象在执行堆栈中的位置。Snowflake 中的模式对于数据库系统来说非常典型:您有一个客户端程序向 Snowflake 发出 SQL,系统会在其中创建计划;然后将该计划分发给实际执行工作的执行引擎。

视觉上:

[Client Program] --SQL--> [Planner] --plan--> [Execution Engine]

用户定义的函数实际上是内置在计划中并由执行引擎运行的。因为它实际上是计划的一部分,Snowflake 将做一些事情,比如保证事务语义,并在仓库中分发和扩展工作。

另一方面,存储过程实际上取代了客户端程序——它恰好在 Snowflake 内部存储和执行。从管理的角度来看,这很好,但 Snowflake 不能做任何特别的事情来扩展它或提供任何关于交易的特殊保证。这只是一个客户端程序。

举一个具体的例子来说明它们有何不同,假设我想从我的存储过程或函数中运行一个查询。对于一个过程,这没有问题:它非常像任何客户端发出查询。

另一方面,也许我希望我的函数发出一个简单的查询来从他们的标识符中查找用户的姓名。我们不能,但是假设我们能够将该查询包装在一个名为get_name(). 现在我可能会发出如下查询:

SELECT id, get_name(id)
FROM my_table

但是让我们考虑一下当它运行时会发生什么。该查询包含我的函数,因此包含此调用的计划将在我的仓库中分发。但是假设my_table有 100 万条记录:这意味着 100 万次调用get_name()和 100 万次查询将被发送到雪花。

哎哟。所以结果是你不能这样做。

无论如何,对您的问题的回答是冗长的。但这实际上取决于您要完成的工作。如果您正在寻找托管客户端程序,您需要一个过程。如果您希望托管您实际想要在查询中运行的逻辑,那么您需要一个函数。有时你想扩展你的逻辑并在查询中运行它,但是,就像上面的例子,你不能——那么你需要更聪明地组织你的逻辑。

于 2021-09-20T18:13:01.463 回答