Snowflake 脚本

2025 年 7 月 29 日 | 阅读 9 分钟

Snowflake 一直支持符合 ANSI 标准的 SQL 语言版本。尽管我们喜欢使用 SQL 处理数据,但用一门基于 Lambda 演算的语言编写代码是多么棒啊!然而,在编写过程式命令和它们之间的切换时,尤其是在存储过程中,它并不完全是函数式的。

当然,Snowflake SQL 支持存储过程,但它们必须用不同的语言定义,例如 JavaScript。

Snowflake 的过程式 SQL 扩展称为 Snowflake Scripting,它允许您使用过程逻辑(如分支和循环)创建存储过程和脚本。标准 SQL 中添加了 IF、WHILE、FOR 等过程构造,从而促进了数据操作的自动化和管理。

1. 控制流语句

使用 Snowflake Scripting 的控制流语句,您可以管理 SQL 语句的执行顺序。

CASE:根据匹配的值执行语句。

WHILE:在条件满足时重复执行一个语句块。

FOR:迭代一个值范围。

2. 赋值和变量

DEFINE 关键字用于定义变量,LET 语句或 := 语法用于为其赋值。

3. 异常处理

使用 TRY...CATCH 块和 Snowflake Scripting 提供了一种处理异常或错误的方法。这有助于在出现问题时控制行为。

4. 存储过程

存储过程是执行复杂操作的程序,它们封装了 SQL 语句和控制流逻辑。它们可以用 JavaScript、Java 或 Snowflake Scripting 编写。

5. Snowflake Scripting 事务

BEGIN、COMMIT 和 ROLLBACK 命令允许您处理事务并控制事件序列的原子性。

6. 游标

游标使得逐行处理查询结果成为可能,这在处理大型数据集或执行需要仔细考虑每一行的任务时非常有用。

7. 动态 SQL

Snowflake Scripting 支持动态 SQL,使您能够即时创建和执行 SQL 语句。

8. 错误处理和记录

RAISE 语句可用于提供自定义错误处理和日志记录,它将抛出异常并记录数据以进行调试。

Snowflake Scripting 的优势

  • 功能和灵活性:此脚本将 SQL 的强大功能与过程式编程的灵活性相结合。
  • 改进的逻辑控制:便于在数据仓库中直接实现业务逻辑。
  • 减少数据移动:Snowflake 直接处理数据,最大限度地减少数据移动。
  • 自动化工作流:有助于自动化复杂的 ETL 操作和重复性任务。

用例

  • 数据转换和清理:数据转换和质量检查可以自动化。
  • 数据迁移:存储过程可以包含复杂的数据迁移逻辑。
  • 批量处理:计划好的、自动化的批量数据处理。
  • 自定义警报和监控:开发自定义监控脚本,根据业务逻辑触发警报。

这很有帮助,但即使是最基本的 SQL 语句也很麻烦且耗时。Snowflake 使得能够用“Snowflake Scripting”编写存储过程。

这种编程语言经过增强,支持过程式、条件式和错误处理指令,并且与 SQL 命令无缝集成。我们将通过示例存储过程来演示 Snowflake Scripting 的一些主要功能。让我们从一个基本任务开始。

基于我们已知的内容

Snowflake Scripting 是对熟悉 SQL 语言的简单扩展,它用 BEGIN-END 对来封装操作。在我们的第一个示例中,我们希望能够快速删除几个我们知道名字的临时表。

注意:虽然不是必需的,但缩进可以提高可读性。

对于多行字符串,$$ 界定符用作开始-结束标记。这包括将字符串内的字符串作为成功指示符返回。将来,我们将使用这种形式,因为将其返回到未加引号的版本是一项简单的任务。事实上,这种 $$ 形式在较新的界面中也有效。

与灵活性相关的变量

多亏了 Snowflake Scripting,存储过程中的变量可以存储临时值,包括作为参数传递的值。在下面的示例中,我们传递了这种类型的参数,并使用它来创建我们的三个表的副本,或称为“克隆”,并将我们输入的作为名称的前缀。

您可能会在此简单示例中看到 Snowflake Scripting 的其他一些功能。具体来说,我们可以

  • 在 BEGIN 之前,在 DECLARE 部分定义变量。
  • 将更新后的值添加到每个表的“newname”变量前面。
  • 使用“CREATE TABLE”命令从旧表复制新命名的表。

由于“IDENTIFIER()”函数,可以“TEXT”变量(用于表名)来提供表名。请注意,变量在 SQL 命令中用冒号(“:t1”)在其前面命名。在为变量赋值或从变量读取时,如在 SQL 命令之前的行中,不需要冒号。

由于“TEXT”很简洁,并且可以与“STRING”、“VARCHAR”等变量互换使用,因此我们使用它来保持变量类型声明的一致性。

值得注意的是,Snowflake Scripting 很好地利用了 Snowflake SQL 语句“EXECUTE IMMEDIATE”。此命令很有用,因为它允许动态构建字符串,并执行其中包含的 SQL 语句。这很有帮助,但即使是最基本的 SQL 语句也很麻烦且耗时。

看看下面的存储过程,它会将所有列名更改为大写字母。据我经验,当源文件包含大量大小写混合的列名时,此方法很有用。它使用“IF-THEN”来确定是否需要更改列,然后发送“RENAME”,并且它将管理和报告任何潜在的语句错误。

  • 过程 UPPER_COLNAMES(tbl_name)
  • 描述:将表名更改为大写
  • 参数:tbl_name - 要更改列名的表名
  • 列将被更改
  • 返回:描述操作结果的对象
  • (“RESULT”键包含 SUCCESS 或其他错误消息)

必须检查和分解此过程。再次,指定了几个“TEXT”字符串,其中包含带有“?”占位符的SQL 命令。借助这些说明,我们可以重命名列并提供我们感兴趣的表的描述。在过程体中,我们执行以下操作:

  • 在通过“EXECUTE IMMEDIATE”并“USING”提供的表名获取表描述后,将结果分配给“RESULTSET”变量“rs”。
  • 当您在 FOR 循环中循环遍历“RESULTSET”时,“col_desc”变量指向每一行,其中包含列描述。
  • 使用“IF-THEN”来确定列名是否需要更改为大写。
  • LET <variable_name> <type> := <expression> ;
  • 使用“EXECUTE IMMEDIATE”通过表名、前一个列名和新列名来重命名列。
  • 如果一切顺利,我们将返回一个指示成功结果的对象。
  • 如果发生语句错误,它将被检测到,并返回一个带有错误描述的相应对象。

巨大的权力和责任

Snowflake Scripting 为常规 SQL 提供了便捷且强大的补充。请注意,我是标准过程语言的忠实拥护者,并且很欣赏它们为 SQL 语句提供的额外功能。然而,随着这种增强的功能,也存在一些警告。以下警告适用于用任何语言编写的存储过程,但在使用 Snowflake Scripting 时牢记这些警告至关重要:

不要放弃您的所有权

此特性将所有示例存储过程统一起来:“EXECUTE AS CALLER”。这是有意的,并遵循存储过程最佳实践,始终保护调用者的权限。这意味着调用者无法使用她无法通过简单的 SQL 指令列表完成的过程来完成任何任务。

警惕 SQL 注入

虽然 SQL 注入未正式包含在 Snowflake Scripting 中,但存储过程经常充分利用 Snowflake SQL 命令“EXECUTE IMMEDIATE”。通过从用户输入拼凑命令字符串,狡猾的调用者可以修改简单的命令,并可能使其执行完全不同的操作。SQL 注入是指这种类型的伎俩,它可能导致严重问题。

Snowflake Scripting 在使用中存储过程的强大功能

正如您可能已经观察到的,我们提供的大部分示例存储过程都处理对数据结构有影响的操作,例如添加和删除表、显示元信息、更改列名等。SQL 的数据定义语言(DDL)方面可以与数据操作语言(DML)方面进行比较,后者包括关系连接、查询和选择。这并不是说 DML 不能与 Snowflake Scripting 一起使用;事实上,我们在某些情况下已经使用过它。

好好利用它

通过 Snowflake Scripting 设置存储过程是一种高效且有效的方法。由于它与 SQL 的紧密联系,它可以成为您新的最佳朋友;它简单明了。

注意 - 多个循环

如前所述,Snowflake Scripting 提供了其他执行循环的方法。我们将尝试检查不同的方法并评估它们的有效性。探索 Snowflake Scripting 的世界,数据开发人员可以在其中创建存储过程或匿名块来处理从简单到非常复杂的各种用例。

块结构

块结构为 Snowflake 和 SQL 编程分别提供了封装和执行的基础。在本视频中,我们将详细介绍这些结构如何链接到存储过程或作为匿名块。我们将介绍理论和实际方面,向您展示如何创建简单的 Snowflake 脚本,并使用我们的 Snowsight WebUI 来引入问题以进行有目的的故障排除。

局部变量

在处理匿名块和存储过程时,Snowflake SQL 脚本中的 LET 关键字用于定义局部变量。将涵盖定义局部变量的不同方法、默认函数以及使用冒号-等号运算符将表达式赋值给局部变量。

局部变量 SQL 脚本

如何使用 Snowflake Scripting 变量

一旦定义了变量,明智地使用它们至关重要。我们将在本视频中探讨如何在普通 SQL 语句和 Snowflake SQL Scripting 语句中使用变量。我们将介绍理解数据类型和在标准表达式中使用变量。我们还将检查 IDENTIFIER 函数的使用以及如何在 SQL 语句中使用冒号表示法访问变量。本课程的目标是帮助您使用 Snowflake scripting 编写复杂、动态且高效的存储过程。

使用 INTO 关键字赋值给不同值

在特定情况下,有必要给不同的变量赋不同的值。为了简化此过程,snowflake scripting 有一个特定的关键字;理解并应用 INTO 关键字为变量赋值将是主要主题,并特别强调在开发存储过程时需要考虑的重要因素。此外,我们将检查不同的问题场景以及在使用 INTO 关键字时不遵循建议方法时可能出现的调试消息。本知识的目的是帮助您进行 Snowflake SQL scripting 的开发和调试。

嵌套块和变量可见性

您可以在存储过程的主体内包含匿名块或嵌套块。根据具体情况,您可以声明同名或不同名的变量。在处理高度嵌套或嵌套块时,理解变量作用域和可见性功能至关重要。

结论

总而言之,我们可以得出结论,通过 Snowflake Scripting 提供的强大的基于 SQL 的过程式编程功能,开发人员可以在 Snowflake 内部创建复杂业务逻辑。Snowflake Scripting 通过存储过程、控制结构(条件语句、循环、错误处理)以及无缝的 SQL 集成等功能,简化数据工作流管理,封装可重用代码,并通过将逻辑处理移近数据来减少网络延迟。


下一主题