将字面量和变量用作标识符¶
在 Snowflake SQL 语句中,除了按名称引用对象(请参阅 标识符要求)之外,您还可以使用字符串字面量、会话变量、绑定变量或 Snowflake Scripting 变量 来引用对象。例如,可以在 SELECT 语句的 FROM 子句中使用设置为表名称的会话变量。要使用在字面量或变量中指定的对象名称,请使用 IDENTIFIER()。
使用 IDENTIFIER() 来识别数据库对象是一种最佳实践,因为它可以提高代码的可重用性并有助于防止 SQL 注入 风险。
语法¶
IDENTIFIER( { string_literal | session_variable | bind_variable | snowflake_scripting_variable } )
string_literal
标识对象名称的字符串:
该字符串必须用单引号 (
'name'
) 括起来,或以美元符号 ($name
) 开头。字符串字面量可以是完全限定的对象名称(例如
'db_name.schema_name.object_name'
或$db_name.schema_name.object_name
)。
session_variable
已为会话设置的 SQL 变量。
bind_variable
形式为
?
或:variable
的 绑定变量,可供支持绑定的客户端/编程接口(JDBC、ODBC、Python 等)使用。snowflake_scripting_variable
已设置的 Snowflake Scripting 变量。
使用说明¶
在某些情况下,需要根据名称识别对象时(查询、DDL、DML 等),可以使用字面量和变量(会话或绑定)。
在同一个查询中,您可以为对象标识符使用绑定变量,还可以为值使用绑定变量。
在 FROM 子句中,可以将
TABLE( { string_literal | session_variable | bind_variable | snowflake_scripting_variable } )
用作IDENTIFIER( { string_literal | session_variable | bind_variable | snowflake_scripting_variable } )
的同义词。尽管 IDENTIFIER() 使用函数的语法,但它不是真正的函数,也不会被 SHOW FUNCTIONS 之类的命令返回。
示例¶
以下示例使用 IDENTIFIER()。
将 IDENTIFIER() 用于字符串字面量¶
以下示例展示了当字符串字面量包含对象标识符时如何引用对象。
创建数据库:
CREATE OR REPLACE DATABASE IDENTIFIER('my_db');
+--------------------------------------+
| status |
|--------------------------------------|
| Database MY_DB successfully created. |
+--------------------------------------+
创建架构:
CREATE OR REPLACE SCHEMA IDENTIFIER('my_schema');
+----------------------------------------+
| status |
|----------------------------------------|
| Schema MY_SCHEMA successfully created. |
+----------------------------------------+
使用在字符串(包含完全限定名称)中指定的表名(不区分大小写)创建表:
CREATE OR REPLACE TABLE IDENTIFIER('my_db.my_schema.my_table') (c1 number);
+--------------------------------------+
| status |
|--------------------------------------|
| Table MY_TABLE successfully created. |
+--------------------------------------+
使用在双引号字符串中指定的表名(区分大小写)创建表:
CREATE OR REPLACE TABLE IDENTIFIER('"my_table"') (c1 number);
+--------------------------------------+
| status |
|--------------------------------------|
| Table my_table successfully created. |
+--------------------------------------+
在架构中显示表:
SHOW TABLES IN SCHEMA IDENTIFIER('my_schema');
+-------------------------------+----------+---------------+-------------+-------+---------+---------+
| created_on | name | database_name | schema_name | kind | comment | ... |
|-------------------------------+----------+---------------+-------------+-------+---------+---------|
| 2024-07-03 08:55:11.992 -0700 | MY_TABLE | MY_DB | MY_SCHEMA | TABLE | | ... |
| 2024-07-03 08:56:00.604 -0700 | my_table | MY_DB | MY_SCHEMA | TABLE | | ... |
+-------------------------------+----------+---------------+-------------+-------+---------+---------+
将 IDENTIFIER() 用于会话变量¶
以下示例展示了如何使用具有表名称或架构名称的 会话变量。
为架构名称设置会话变量:
SET schema_name = 'my_db.my_schema';
为表名设置会话变量:
SET table_name = 'my_table';
指定当前会话的架构:
USE SCHEMA IDENTIFIER($schema_name);
在表中插入值:
INSERT INTO IDENTIFIER($table_name) VALUES (1), (2), (3);
查询表:
SELECT * FROM IDENTIFIER($table_name) ORDER BY 1;
+----+
| C1 |
|----|
| 1 |
| 2 |
| 3 |
+----+
以下示例展示了如何使用具有函数名称的会话变量。
创建函数
speed_of_light
:CREATE FUNCTION speed_of_light() RETURNS INTEGER AS $$ 299792458 $$;
按名称调用该函数:
SELECT speed_of_light();
+------------------+ | SPEED_OF_LIGHT() | |------------------| | 299792458 | +------------------+
使用 IDENTIFIER() 语法调用函数:
SET my_function_name = 'speed_of_light';
SELECT IDENTIFIER($my_function_name)();
+---------------------------------+ | IDENTIFIER($MY_FUNCTION_NAME)() | |---------------------------------| | 299792458 | +---------------------------------+
将 IDENTIFIER() 用于绑定变量¶
以下示例展示了如何使用 绑定变量 来标识对象。
此示例展示了如何在 JDBC 中绑定函数名称。该函数被命名为 speed_of_light
。
String sql_command;
// Create a Statement object to use later.
System.out.println("Create JDBC statement.");
Statement statement = connection.createStatement();
System.out.println("Create function.");
sql_command = "CREATE FUNCTION speed_of_light() RETURNS INTEGER AS $$ 299792458 $$";
statement.execute(sql_command);
System.out.println("Create prepared statement.");
sql_command = "SELECT IDENTIFIER(?)()";
PreparedStatement ps = connection.prepareStatement(sql_command);
// Bind
ps.setString(1, "speed_of_light");
ResultSet rs = ps.executeQuery();
if (rs.next()) {
System.out.println("Speed of light (m/s) = " + rs.getInt(1));
}
以下示例展示了可使用绑定的各种 SQL 语句,以及可以绑定的各种数据库对象(包括架构名称和表名称):
USE SCHEMA IDENTIFIER(?);
CREATE OR REPLACE TABLE IDENTIFIER(?) (c1 NUMBER);
INSERT INTO IDENTIFIER(?) values (?), (?), (?);
SELECT t2.c1
FROM IDENTIFIER(?) AS t1,
IDENTIFIER(?) AS t2
WHERE t1.c1 = t2.c1 AND t1.c1 > (?);
DROP TABLE IDENTIFIER(?);
将 IDENTIFIER() 用于 Snowflake Scripting 变量¶
以下示例展示了如何将 Snowflake Scripting 变量用于 SELECT 语句中的表名称:
BEGIN LET res RESULTSET := (SELECT COUNT(*) AS COUNT FROM IDENTIFIER(:table_name)); ...