将字面量和变量用作标识符

在 Snowflake SQL 语句中,除了按名称引用对象(请参阅 标识符要求)之外,您还可以使用字符串字面量、会话变量、绑定变量或 Snowflake Scripting 变量 来引用对象。例如,可以在 SELECT 语句的 FROM 子句中使用设置为表名称的会话变量。要使用在字面量或变量中指定的对象名称,请使用 IDENTIFIER()。

使用 IDENTIFIER() 来识别数据库对象是一种最佳实践,因为它可以提高代码的可重用性并有助于防止 SQL 注入 风险。

语法

IDENTIFIER( { string_literal | session_variable | bind_variable | snowflake_scripting_variable } )
Copy
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');
Copy
+--------------------------------------+
| status                               |
|--------------------------------------|
| Database MY_DB successfully created. |
+--------------------------------------+

创建架构:

CREATE OR REPLACE SCHEMA IDENTIFIER('my_schema');
Copy
+----------------------------------------+
| status                                 |
|----------------------------------------|
| Schema MY_SCHEMA successfully created. |
+----------------------------------------+

使用在字符串(包含完全限定名称)中指定的表名(不区分大小写)创建表:

CREATE OR REPLACE TABLE IDENTIFIER('my_db.my_schema.my_table') (c1 number);
Copy
+--------------------------------------+
| status                               |
|--------------------------------------|
| Table MY_TABLE successfully created. |
+--------------------------------------+

使用在双引号字符串中指定的表名(区分大小写)创建表:

CREATE OR REPLACE TABLE IDENTIFIER('"my_table"') (c1 number);
Copy
+--------------------------------------+
| status                               |
|--------------------------------------|
| Table my_table successfully created. |
+--------------------------------------+

在架构中显示表:

SHOW TABLES IN SCHEMA IDENTIFIER('my_schema');
Copy
+-------------------------------+----------+---------------+-------------+-------+---------+---------+
| 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';
Copy

为表名设置会话变量:

SET table_name = 'my_table';
Copy

指定当前会话的架构:

USE SCHEMA IDENTIFIER($schema_name);
Copy

在表中插入值:

INSERT INTO IDENTIFIER($table_name) VALUES (1), (2), (3);
Copy

查询表:

SELECT * FROM IDENTIFIER($table_name) ORDER BY 1;
Copy
+----+
| C1 |
|----|
|  1 |
|  2 |
|  3 |
+----+

以下示例展示了如何使用具有函数名称的会话变量。

  1. 创建函数 speed_of_light

    CREATE FUNCTION speed_of_light() 
    RETURNS INTEGER
    AS
      $$
      299792458
      $$;
    
    Copy
  2. 按名称调用该函数:

    SELECT speed_of_light();
    
    Copy
    +------------------+
    | SPEED_OF_LIGHT() |
    |------------------|
    |        299792458 |
    +------------------+
    
  3. 使用 IDENTIFIER() 语法调用函数:

    SET my_function_name = 'speed_of_light';
    
    Copy
    SELECT IDENTIFIER($my_function_name)();
    
    Copy
    +---------------------------------+
    | 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));
}
Copy

以下示例展示了可使用绑定的各种 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(?);
Copy

将 IDENTIFIER() 用于 Snowflake Scripting 变量

以下示例展示了如何将 Snowflake Scripting 变量用于 SELECT 语句中的表名称:

BEGIN
  LET res RESULTSET := (SELECT COUNT(*) AS COUNT FROM IDENTIFIER(:table_name));
  ...
Copy
语言: 中文