IDENTIFIER 절

IDENTIFIER 절 (IDENTIFIER clause)

상수 STRING 표현식을 SQL 객체 이름으로 변환하는 IDENTIFIER 절을 설명하는 문서예요. 이 절의 목적은 SQL 인젝션 공격의 위험 없이 SQL 문에서 식별자를 템플릿화(templating)할 수 있게 해주는 거예요. 문자열 리터럴 형태와 좀 더 복잡한 상수 표현식 형태, 두 가지 사용법을 예제와 함께 다룰게요.

출처: 문서

본문

설명 (Description)

상수 STRING 표현식을 SQL 객체 이름으로 변환해요. 이 절의 목적은 SQL 인젝션 공격의 위험을 열지 않고 SQL 문에서 식별자를 템플릿화할 수 있게 하는 것이에요.

이 절은 두 가지 형태로 제공돼요:

  • 문자열 리터럴(문자열 리터럴과 매개변수 마커의 병합된 string 포함 가능)을 전달하면, 식별자나 한정된(qualified) 식별자를 사용할 수 있는 어디에서나 사용할 수 있어요. 이 형태의 사용을 권장해요.
  • 변수도 포함할 수 있는 더 복잡한 상수 문자열 표현식을 전달하면, 테이블 이름, 컬럼 이름, 함수 이름 같은 동적 SQL 객체 참조를 참조하기 위해 제한된 경우에 사용할 수 있어요. 이 형태의 사용은 꼭 필요하지 않으면 권장하지 않아요. 예를 들어 이 형태로는 테이블이나 컬럼 별칭, 또는 CREATE TABLE 문의 컬럼 이름을 매개변수화할 수 없어요.

구문 (Syntax)

IDENTIFIER ( strLiteral )

IDENTIFIER ( strExpr )

매개변수 (Parameters)

  • strLiteral

    문자열과 문자열 매개변수 마커의 병합(string coalescing)을 포함할 수 있는 상수 STRING 리터럴이에요.

    문자열은 유효한 (한정된) 식별자여야 해요.

    예를 들어:

    IDENTIFIER('default.' :tablename)
    IDENTIFIER(:catalog '.' :namespace '.' :tablename '.' :columnname)
    IDENTIFIER(:rootdirectory '/data/' :tablename)
    
  • strExpr: 상수 STRING 표현식이에요. 일반적으로 표현식은 매개변수 마커나 세션 변수를 포함해요.

    문자열은 유효한 (한정된) 식별자여야 해요.

    예를 들어:

    IDENTIFIER(session.schema || '.' || session.tablename)
    IDENTIFIER('`' || session.schema || '`.`' session.tablename || '`')
    IDENTIFIER(CONCAT(:catalog, '.', :namespace, '.', :tablename, '.', :columnname))
    

반환값 (Returns)

(한정된) 식별자.

예제 (Examples)

Scala 예제 (Scala examples)

이 예제들은 쿼리를 템플릿화하기 위해 이름 있는 매개변수 마커(named parameter marker)를 사용해요.

// Creation of a table using parameter marker.
spark.sql("CREATE TABLE IDENTIFIER(:mytab)(c1 INT)", args = Map("mytab" -> "tab1")).show()

spark.sql("DESCRIBE IDENTIFIER(:mytab)", args = Map("mytab" -> "tab1")).show()
+--------+---------+-------+
|col_name|data_type|comment|
+--------+---------+-------+
|      c1|      int|   NULL|
+--------+---------+-------+

// Altering a table with a fixed schema and a parameterized table name. 
spark.sql("ALTER TABLE IDENTIFIER('default.' || :mytab) ADD COLUMN c2 INT", args = Map("mytab" -> "tab1")).show()

spark.sql("DESCRIBE IDENTIFIER(:mytab)", args = Map("mytab" -> "default.tab1")).show()
+--------+---------+-------+
|col_name|data_type|comment|
+--------+---------+-------+
|      c1|      int|   NULL|
|      c2|      int|   NULL|
+--------+---------+-------+

// A parameterized reference to a table in a query. This table name is qualified and uses back-ticks.
spark.sql("SELECT * FROM IDENTIFIER(:mytab)", args = Map("mytab" -> "`default`.`tab1`")).show()
+---+---+
| c1| c2|
+---+---+
+---+---+

// You cannot qualify the IDENTIFIER clause or use it as a qualifier itself.
spark.sql("SELECT * FROM myschema.IDENTIFIER(:mytab)", args = Map("mytab" -> "`tab1`")).show()
[INVALID_SQL_SYNTAX.INVALID_TABLE_VALUED_FUNC_NAME] `myschema`.`IDENTIFIER`.

spark.sql("SELECT * FROM IDENTIFIER(:myschema).mytab", args = Map("mychema" -> "`default`")).show()
[PARSE_SYNTAX_ERROR]

// Dropping a table with separate schema and table parameters.
spark.sql("DROP TABLE IDENTIFIER(:myschema '.' :mytab)", args = Map("myschema" -> "default", "mytab" -> "tab1")).show()

// A parameterized column reference
spark.sql("SELECT IDENTIFIER(:col) FROM VALUES(1) AS T(c1)", args = Map("col" -> "t.c1")).show()
+---+
| c1|
+---+
|  1|
+---+

// Passing in a function name as a parameter
spark.sql("SELECT IDENTIFIER(:func)(-1)", args = Map("func" -> "abs")).show();
+-------+
|abs(-1)|
+-------+
|      1|
+-------+

SQL 예제 (SQL examples)

이 예제들은 쿼리를 템플릿화하기 위해 SQL 변수를 사용해요.

DECLARE mytab = 'tab1';

-- Creation of a table using variable.
CREATE TABLE IDENTIFIER(mytab)(c1 INT);

EXECUTE IMMEDIATE 'DESCRIBE IDENTIFIER(:mytab)' USING mytab;
+--------+---------+-------+
|col_name|data_type|comment|
+--------+---------+-------+
|      c1|      int|   NULL|
+--------+---------+-------+

-- Altering a table with a fixed schema and a parameterized table name. 
EXECUTE IMMEDIATE 'ALTER TABLE IDENTIFIER('default.' || :mytab) ADD COLUMN :col INT' USING mytab, 'c2' AS col;

SET VAR mytab = '`default`.`tab1`';
EXECUTE IMMEDIATE 'DESCRIBE IDENTIFIER(:mytab)' USING mytab;
+--------+---------+-------+
|col_name|data_type|comment|
+--------+---------+-------+
|      c1|      int|   NULL|
|      c2|      int|   NULL|
+--------+---------+-------+

-- A parameterized reference to a table in a query. This table name is qualified and uses back-ticks.
EXECUTE IMMEDIATE 'SELECT * FROM IDENTIFIER(mytab)' USING mytab;
+---+---+
| c1| c2|
+---+---+

-- Dropping a table with separate schema and table parameters.
DECLARE myschema = 'default';
SET VAR mytab = 'tab1';
EXECUTE IMMEDIATE 'DROP TABLE IDENTIFIER(:myschema '.' :mytab)' USING myschema, mytab;

-- A parameterized column reference
DECLARE col = 'c1';
EXECUTE IMEMDIATE 'SELECT IDENTIFIER(:col) FROM VALUES(1) AS T(IDENTIFIER(:col))' USING col;
+---+
| c1|
+---+
|  1|
+---+

-- Passing in a function name as a parameter
EXECUTE IMMEDIATE 'SELECT IDENTIFIER(:func)(-1)' USING 'abs' AS func;
+-------+
|abs(-1)|
+-------+
|      1|
+-------+

더 알아보기 (Learn more)