使用变量¶
在 Snowflake Scripting 中,可以在表达式、Snowflake Scripting 语句和 SQL 语句中使用变量。
声明变量¶
在使用变量之前,必须声明该变量。声明变量时,必须采用以下方式之一指定变量的类型:
显式指定数据类型。
为变量指定其初始值表达式。Snowflake Scripting 使用表达式来确定变量的数据类型。请参阅 Snowflake Scripting 如何推断变量的数据类型。
您可通过以下方式声明变量:
在块的 DECLARE 部分,使用以下任一方法:
在块的 BEGIN ...END 部分中(在使用变量之前),通过以下任一方法使用 LET 命令:
其中:
以下示例在块的 DECLARE 部分和 BEGIN ...END 部分声明了变量:
Note: If you use Snowflake CLI, SnowSQL, the Classic Console, or the
execute_stream or execute_string method in Python Connector
code, use this example instead (see Using Snowflake Scripting in Snowflake CLI, SnowSQL, and Python Connector):
以下章节将说明如何确定变量的数据类型和范围:
有关为变量赋值的信息,请参阅 为已声明的变量赋值。
Snowflake Scripting 如何推断变量的数据类型¶
当您在未显式指定数据类型的情况下声明变量时,Snowflake Scripting 会根据您分配给变量的表达式推断数据类型。
如果选择从声明中省略数据类型,请注意以下事项:
如果表达式可以解析为不同大小的不同数据类型,Snowflake 通常会选择灵活(例如 FLOAT,而不是 NUMBER(3, 1))且具有高存储容量(例如 VARCHAR,而不是 VARCHAR(4))的类型。
例如,如果将变量设置为值
12.3,Snowflake 可以为该变量选择多种数据类型之一,包括:NUMBER(3, 1)
NUMBER(38, 1)
FLOAT
在此示例中,Snowflake 选择了 FLOAT。
如果需要变量的特定数据类型(尤其是数字或时间戳类型),Snowflake 建议您显式指定数据类型,即使您提供了初始值也是如此。
如果 Snowflake 无法推断预期的数据类型,则 Snowflake 会报告 SQL 编译错误。
例如,以下代码声明了变量,但未显式指定数据类型。该代码将变量设置为游标中的值。
编译 Snowflake Scripting 块时(例如,执行 CREATE PROCEDURE 命令时),游标尚未打开,游标中列的数据类型未知。因此,Snowflake 报告 SQL 编译错误:
了解声明的范围¶
Snowflake Scripting 使用 ` 词法作用域 <https://en.wikipedia.org/wiki/Scope_(computer_science (link removed))#Lexical_scope>`_ 。当在块的 DECLARE 部分中声明值、结果集、游标或异常的变量时,所声明对象的作用域(或可见性)是该块以及嵌套在该块中的任何块。
如果块声明的对象与外部块中声明的对象同名,则在内部块(以及该块内的任何块)中,只有内部块的对象在作用域内。引用对象名称时,Snowflake 会查找具有该名称的对象,方法是首先从当前块开始查找,然后每次向外查找一个块,直到找到具有匹配名称的对象。
例如,如果在存储过程中声明了异常,则异常的作用域仅限于该存储过程。该存储过程调用的存储过程无法引发(或处理)该异常。调用该过程的存储过程无法处理(或引发)该异常。
为已声明的变量赋值¶
要为已声明的变量赋值,请使用 := 运算符:
其中:
使用变量¶
You can use variables in expressions and with Snowflake Scripting language elements (such as RETURN). You can add these language elements to stored procedures, Snowflake Scripting user-defined functions (UDF), and anonymous blocks.
您可以在表达式中使用变量,也可以将变量与 Snowflake Scripting 语言元素(如 RETURN)结合使用。例如,以下代码在表达式中使用变量 revenue 和 cost,在 RETURN 语句中使用变量 profit :
若要在异常处理程序(块的 EXCEPTION 部分)中使用变量,必须在 DECLARE 部分中声明该变量,或将其作为实参传递给存储过程。该变量不能在 BEGIN ...END 部分声明。有关更多信息,请参阅 在 Snowflake Scripting 中将变量传递给异常处理程序。
小技巧
您还可以在 Snowflake Scripting 匿名块和以调用方权限运行的存储程序中使用和设置 SQL(会话)变量。有关更多信息,请参阅 在存储过程中使用和设置 SQL 变量。
在 SQL 语句中使用变量(绑定)¶
您可以在SQL 语句中使用变量,有时将这称为:绑定 一个变量。为此,请在变量名称前加上冒号。例如:
您可以使用展开运算符 (**) 将表示 数组 的绑定变量扩展为单个值的列表。有关更多信息,请参阅 扩展运算符。
有关在 Snowflake Scripting 存储过程中绑定变量的信息,请参阅 在 SQL 语句中使用实参(绑定)。
如果使用变量作为对象的名称(例如,SELECT 语句的 FROM 子句中的表名称),请使用 IDENTIFIER 关键字来指示该变量表示对象标识符。例如:
如果在表达式中使用变量,或将变量与 Snowflake Scripting 语言元素)结合使用,则无需在变量前加冒号。
例如,在以下情况下,您无需添加冒号前缀:
您将变量与 RETURN 结合使用。在以下示例中,变量
profit与 Snowflake Scripting 语言元素结合使用,不需要在变量前面加冒号。您在构建一个包含要执行的 SQL 语句的字符串。在以下示例中,变量
id_variable用在表达式中,不需要在变量前面加冒号。
此外,TO_QUERY 函数提供了一种简单的语法,可直接在 SELECT 语句的 FROM 子句中接受 SQL 字符串。有关 TO_QUERY 函数与动态 SQL 的比较,请参阅 运行时构造 SQL。
将变量设置为 SELECT 语句的结果¶
在 Snowflake Scripting 块中,您可以使用 INTO 子句将变量设置为 SELECT 子句中指定的表达式的值:
使用此语法时,请执行以下操作:
将
variable1设置为expression1的值。将
variable2设置为expression2的值。
SELECT 语句必须返回一行。
以下示例包含返回单行的 SELECT 语句。该示例依赖于此表中的数据:
该示例将 Snowflake Scripting 变量 id 和 name 设置为具有这些名称的列返回的值。
Note: If you use Snowflake CLI, SnowSQL, the Classic Console, or the
execute_stream or execute_string method in Python Connector
code, use this example instead (see Using Snowflake Scripting in Snowflake CLI, SnowSQL, and Python Connector):
该示例从 SELECT 语句返回的行中打印出 id 和 name。
将变量设置为存储过程的返回值¶
请参阅 使用从存储过程调用返回的值。
使用存储过程实参¶
您可以创建 :doc:` Snowflake Scripting 存储过程 </developer-guide/stored-procedure/stored-procedures-snowflake-scripting>`,这些存储过程在调用时会传递实参。这些实参的行为方式类似于存储过程主体中声明的变量。
Snowflake Scripting 支持输入 (IN) 和输出 (OUT) 实参。实参类型决定如何了它在存储过程中的用法。
有关更多信息,请参阅 使用传递给存储过程的实参。
使用变量的示例¶
以下示例演示了如何声明变量、为变量赋值或分配表达式,以及将值转换为变量的数据类型:
Note: If you use Snowflake CLI, SnowSQL, the Classic Console, or the
execute_stream or execute_string method in Python Connector
code, use this example instead (see Using Snowflake Scripting in Snowflake CLI, SnowSQL, and Python Connector):
以下示例在表达式中使用内置 SQL 函数:
以下声明隐式指定了变量 profit、cost 和 revenue 的数据类型,方法是指定每个变量的预期数据类型初始值。
该示例还演示了如何使用 LET 语句在块的 DECLARE 部分之外声明 cost 和 revenue 变量:
Note: If you use Snowflake CLI, SnowSQL, the Classic Console, or the
execute_stream or execute_string method in Python Connector
code, use this example instead (see Using Snowflake Scripting in Snowflake CLI, SnowSQL, and Python Connector):
以下示例演示了变量的作用域。此示例包括两个变量和一个参数,它们都具有相同的名称,但作用域不同。
该示例包含三个块:最外层、中间和最内层的块。
在最内层块中,PV_NAME 解析为在该最内层块中声明和设置的变量(即设置为
innermost block variable)。在中间块内(以及最内层块之外),PV_NAME 解析为在中间块中声明和设置的变量(即设置为
middle block variable)。在最外层块内(以及任何嵌套块之外),PV_NAME 解析为传递给存储过程的参数(即通过 CALL 语句设置为
parameter)。
该示例依赖于以下表:
在以下示例中,将字符串 innermost block variable 赋值给最内层块中的 PV_NAME不会影响中间块内变量的值。最内层块中的变量与中间块中的变量不同,即使两个变量具有相同的名称。
Note: If you use Snowflake CLI, SnowSQL, the Classic Console, or the
execute_stream or execute_string method in Python Connector
code, use this example instead (see Using Snowflake Scripting in Snowflake CLI, SnowSQL, and Python Connector):
调用存储过程:
检查表中的值:
该输出显示:
在最内层的嵌套块(该块嵌套了两层)中,使用了内部块的变量
PV_NAME。在中间块(该块嵌套了一层)中,使用了该中间块的变量
PV_NAME。在最外层的块中,使用了该参数。
有关在打开游标时绑定变量的示例,请参阅 打开游标的示例。