바인드 변수

애플리케이션은 사용자의 데이터를 허용하고 해당 데이터를 SQL 문에서 사용할 수 있습니다. 예를 들어 애플리케이션에서 사용자에게 주소, 전화번호 등의 연락처 정보를 입력하도록 요청할 수 있습니다.

SQL 문에서 이 사용자 입력을 지정하려면 사용자 입력을 문의 다른 부분과 연결하여 SQL 문에 대한 문자열을 프로그래밍 방식으로 구성할 수 있습니다. 또는 바인드 변수 를 사용할 수 있습니다. 변수를 바인딩하려면 SQL 문의 텍스트에 자리 표시자를 1개 이상 추가한 다음 각 자리 표시자에 변수(사용할 변수)를 지정하십시오.

바인드 변수 개요

바인드 변수 사용 시, SQL 문의 리터럴을 자리 표시자로 바꿉니다. 예를 들어, 다음 SQL 문은 삽입된 값에 리터럴을 사용합니다.

INSERT INTO t (c1, c2) VALUES (1, 'Test string');
Copy

다음 SQL 문은 삽입된 값에 자리 표시자를 사용합니다.

INSERT INTO t (c1, c2) VALUES (?, ?);
Copy

애플리케이션 코드는 데이터를 SQL 문의 각 자리 표시자와 바인딩합니다. 자리 표시자를 사용하여 데이터를 바인딩하는 기법은 프로그래밍 언어에 따라 다릅니다. 또한 자리 표시자의 구문은 프로그래밍 언어에 따라 다릅니다. ?, :varname 또는 %varname 입니다.

Javascript 저장 프로시저에서 바인드 변수 사용하기

:doc:`Javascript</developer-guide/stored-procedure/stored-procedures-javascript>`를 사용하여 SQL을 실행하는 저장 프로시저를 만들 수 있습니다.

Javascript 코드에서 바인드 변수를 지정하려면 ? 자리 표시자를 사용합니다. 예를 들어, 다음 INSERT 문은 테이블 행에 삽입된 값에 대한 바인드 변수를 지정합니다.

INSERT INTO t (col1, col2) VALUES (?, ?)
Copy

자바스크립트 코드에서 대부분 SQL 문의 값에는 바인드 변수를 사용할 수 있습니다. 제한 사항에 대한 자세한 내용은 바인드 변수에 대한 제한 사항 섹션을 참조하십시오.

Javascript에서 바인드 변수를 사용하는 방법에 대한 자세한 내용은 변수 바인딩하기 섹션을 참조하십시오.

Snowflake Scripting과 함께 바인드 변수 사용하기

Snowflake Scripting</developer-guide/snowflake-scripting/index>`을 사용하여 코드 블록 및 저장 프로시저와 같은 SQL을 실행하는 절차적 코드를 생성할 수 있습니다. Snowflake Scripting 코드에서 바인드 변수를 지정하려면 변수 이름 앞에 콜론을 접두사로 붙입니다. 예를 들어, 다음 INSERT 문은 :code:`variable1 이라는 바인드 변수를 지정합니다.

INSERT INTO t (c1) VALUES (:variable1)
Copy

EXECUTE IMMEDIATE 명령에서 SQL을 실행하거나 커서에 대해 :ref:`OPEN 명령<label-snowscript_cursors_open>`을 실행할 때 USING 절로 변수를 바인딩할 수 있습니다.

이 예에서는 USING 절을 사용하여 EXECUTE IMMEDIATE 명령의 변수를 바인딩합니다.

EXECUTE IMMEDIATE :query USING (minimum_price, maximum_price);
Copy

이 코드가 포함된 전체 예제는 바인드 변수가 포함된 문 실행하기 섹션을 참조하십시오.

커서를 선언할 때 SELECT 문에 바인딩 매개 변수(? 문자)를 지정할 수 있습니다. 그런 다음, 커서를 열 때 이러한 매개 변수를 USING 절의 변수에 바인딩할 수 있습니다.

다음 예제에서는 커서를 선언하고 바인드 매개 변수를 지정한 다음, USING 절로 커서를 엽니다.

LET c1 CURSOR FOR SELECT id FROM invoices WHERE price > ? AND price < ?;
OPEN c1 USING (minimum_price, maximum_price);
Copy

Snowflake Scripting은 위치별로 바인드 변수에 번호를 매기고 SQL 문에서 바인드 변수를 재사용하는 기능도 지원합니다. 번호가 매겨진 바인드 변수의 경우, 각 변수 선언에 인덱스가 할당되며 :n 으로 n번째로 선언된 변수를 참조할 수 있습니다. 예를 들어, 다음 Snowflake Scripting 블록에서는 i 변수에 대해 바인드 변수 :1 을 지정하고 v 변수에 대해 바인드 변수 :2 를 지정하며 SQL 문에서 :1 바인드 변수를 재사용합니다.

EXECUTE IMMEDIATE $$
DECLARE
  i INTEGER DEFAULT 1;
  v VARCHAR DEFAULT 'SnowFlake';
  r RESULTSET;
BEGIN
  CREATE OR REPLACE TABLE snowflake_scripting_bind_demo (id INTEGER, value VARCHAR);
  EXECUTE IMMEDIATE 'INSERT INTO snowflake_scripting_bind_demo (id, value)
    SELECT :1, (:2 || :1)' USING (i, v);
  r := (SELECT * FROM snowflake_scripting_bind_demo);
  RETURN TABLE(r);
END;
$$
;
Copy
+----+------------+
| ID | VALUE      |
|----+------------|
|  1 | SnowFlake1 |
+----+------------+

Snowflake Scripting 코드에서 대부분 SQL 문의 값에 바인드 변수를 사용할 수 있습니다. 제한 사항에 대한 자세한 내용은 바인드 변수에 대한 제한 사항 섹션을 참조하십시오.

Snowflake Scripting에서 바인드 변수를 사용하는 방법에 대한 자세한 내용은 SQL 문에서 변수 사용하기(바인딩)SQL 문에서 인자 사용하기(바인딩) 섹션을 참조하십시오.

SQL API와 함께 바인드 변수 사용하기

Snowflake SQL API 를 사용하여 Snowflake 데이터베이스의 데이터에 액세스하고 업데이트할 수 있습니다. SQL API를 사용하여 SQL 문을 제출하고 배포를 관리하는 애플리케이션을 만들 수 있습니다.

SQL 문을 실행하는 요청을 제출하면 문의 값에 바인드 변수를 사용할 수 있습니다. 자세한 내용은 문에서 바인드 변수 사용하기 섹션을 참조하세요.

드라이버와 함께 바인드 변수 사용하기

Snowflake 드라이버 를 사용하면 Snowflake에서 작업을 수행하는 애플리케이션을 작성할 수 있습니다. 드라이버는 Go, Java, Python과 같은 프로그래밍 언어를 지원합니다. 특정 드라이버에 대한 애플리케이션의 바인드 변수 사용에 대한 자세한 내용을 보려면 해당 드라이버에 대한 링크를 따르십시오.

참고

PHP 드라이버는 바인드 변수를 지원하지 않습니다.

값 배열과 함께 바인드 변수 사용하기

SQL 문의 변수에 값 배열을 바인딩할 수 있습니다. 이 기법을 사용하면 여러 행을 단일 배치에 삽입하여 네트워크 왕복 및 컴파일을 방지함으로써 성능을 개선할 수 있습니다. 배열 바인드 사용을 “대량 삽입” 또는 “배치 삽입”이라고도 합니다.

참고

Snowflake는 배열 바인드를 사용하는 대신 권장되는 다른 데이터 로딩 방법을 지원합니다. 자세한 내용은 Snowflake에 데이터 로드하기데이터 로딩 및 언로딩 명령 섹션을 참조하십시오.

다음은 Python 코드의 배열 바인드의 예입니다.

conn = snowflake.connector.connect( ... )
rows_to_insert = [('milk', 2), ('apple', 3), ('egg', 2)]
conn.cursor().executemany(
            "insert into grocery (item, quantity) values (?, ?)",
            rows_to_insert)
Copy

이 예제에서는 바인드 목록 [('milk', 2), ('apple', 3), ('egg', 2)] 를 지정합니다. 애플리케이션이 바인드 목록을 지정하는 방식은 프로그래밍 언어에 따라 다릅니다.

이 코드는 테이블에 세 개의 행을 삽입합니다.

+-------+----+
| C1    | C2 |
|-------+----|
| milk  |  2 |
| apple |  3 |
| egg   |  2 |
+-------+----+

특정 드라이버에 대한 애플리케이션의 배열 바인드 사용에 대한 자세한 내용을 보려면 해당 드라이버에 대한 링크를 따르십시오.

참고

PHP 드라이버는 배열 바인드를 지원하지 않습니다.

배열 바인드 사용의 제한 사항

배열 바인드에 적용되는 제한 사항은 다음과 같습니다.

  • INSERT INTO … VALUES 문만 배열 바인드 변수를 포함할 수 있습니다.

  • VALUES 절은 바인드 변수의 단일 행 목록이어야 합니다. 예를 들어 다음 VALUES 절은 허용되지 않습니다.

    VALUES (?,?), (?,?)
    
    Copy

배열 바인드를 사용하지 않고 여러 행 삽입하기

INSERT 문은 바인드 변수를 사용하여 배열 바인드를 사용하지 않고 여러 행을 삽입할 수 있습니다. 다음 예에서는 두 행에 값을 삽입하지만, 배열 바인드를 사용하지 않습니다.

INSERT INTO t VALUES (?,?), (?,?);
Copy

예를 들어, 애플리케이션은 자리 표시자에 대해 [1,'String1',2,'String2'] 값에 해당하는 바인드 목록을 순서대로 지정할 수 있습니다. VALUES 절은 2개 이상의 행을 지정하므로 이 문은 동적인 행의 수 대신 값의 정확한 개수(이 예에서는 4개)만 삽입합니다.

반정형 데이터에 바인드 변수 사용하기

변수를 반정형 데이터와 바인딩하려면 변수를 문자열 유형으로 바인딩하고 PARSE_JSON 또는 ARRAY_CONSTRUCT 와 같은 함수를 사용하십시오.

다음 예에서는 하나의 VARIANT 열이 1개 있는 테이블을 만든 다음 PARSE_JSON 함수를 호출하여 바인드 변수가 있는 테이블에 반정형 데이터를 삽입합니다.

CREATE TABLE t (a VARIANT);
-- Code that supplies a bind value for ? of '{'a': 'abc', 'x': 'xyz'}'
INSERT INTO t SELECT PARSE_JSON(a) FROM VALUES (?);
Copy

다음 예에서는 테이블을 쿼리합니다.

SELECT * FROM t;
Copy

쿼리에서 반환되는 출력은 다음과 같습니다.

+---------------+
| A             |
|---------------|
| {             |
|   "a": "abc", |
|   "x": "xyz"  |
| }             |
+---------------+

다음 문은 ARRAY_CONSTRUCT 함수를 호출하여 반정형 데이터 배열을 바인드 변수가 있는 VARIANT 열에 삽입합니다.

INSERT INTO t SELECT ARRAY_CONSTRUCT(column1) FROM VALUES (?);
Copy

이 두 예제에서는 모두 단일 행을 삽입하거나 배열 바인드를 사용하여 한 배치에 여러 행을 삽입할 수 있습니다. 이 기법을 사용하면 VARIANT 열에 유효한 모든 유형의 반정형 데이터를 삽입할 수 있습니다.

바인드 변수 값 검색하기

참고

바인드 변수 값을 검색하려면 :doc:`2025_06 동작 변경 번들</release-notes/bcr-bundles/2025_06_bundle>`을 해당 계정에서 활성화해야 합니다. 이 번들은 기본적으로 비활성화되어 있습니다.

실행된 쿼리에서 바인드 변수의 값을 검색하려면 INFORMATION_SCHEMA 스키마의 BIND_VALUES 테이블 함수를 사용할 수 있습니다. 이 함수를 사용하면 Javascript 및 Snowflake Scripting 코드를 포함하여 바인드 변수를 지원하는 모든 코드에서 바인드 변수 값을 검색할 수 있습니다.

QUERY_HISTORYAccount Usage 뷰, QUERY_HISTORYOrganization Usage 뷰, QUERY_HISTORY 함수</sql-reference/functions/query_history>`에 대한 출력의 :code:`bind_values 열에서 이러한 바인드 변수 값에 액세스할 수도 있습니다.

이러한 메서드를 사용하여 바인드 변수 값을 검색하려면 ALLOW_BIND_VALUES_ACCESS 계정 수준 매개 변수를 ``TRUE``로 설정해야 합니다.

다음과 같은 경우 바인드 변수 값을 검색할 수 있습니다.

  • 쿼리 문제 해결 - 쿼리에 사용된 정확한 바인드 값을 알면 쿼리를 최적화하고 다음 유형의 문제를 디버깅하는 것이 더 쉽습니다.

    • 쿼리 실행에 실패합니다.

    • 쿼리의 성능이 좋지 않습니다.

    • 쿼리가 캐시 또는 예상 실행 계획을 사용하지 않습니다.

  • 테스트를 위한 쿼리 다시 만들기 - 개발자 및 DBAs는 문제를 복제하고 스트레스를 테스트하기 위해 바인드 변수 값으로 사용자 생성 쿼리를 다시 생성할 수 있습니다.

  • 감사 및 규정 준수 - 보안 및 규정 준수를 위해 조직은 사용자가 액세스하는 데이터를 감사해야 합니다. 바인드 변수 값을 사용하여 사용자가 검색한 정확한 데이터를 확인할 수 있습니다.

바인드 변수 값을 검색하는 예제

다음 쿼리는 이전 쿼리에 대한 바인드 변수 값을 반환합니다.

SELECT * FROM TABLE(
  INFORMATION_SCHEMA.BIND_VALUES('<query_id_value>'));
Copy
SELECT bind_values
  FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
  WHERE query_id = '<query_id_value>';
Copy

query_id_value`를 쿼리 ID로 바꿉니다. :doc:/sql-reference/functions/last_query_id` 함수를 사용하여 이전 쿼리의 ID를 반환할 수 있습니다.

참고

QUERY_HISTORY 뷰의 대기 시간은 최대 45분일 수 있습니다.

다음 예제에서는 BIND_VALUES 함수를 사용합니다.

명명된 바인드 변수를 검색하는 Snowflake Scripting 예제

바인드 변수를 사용하는 문이 포함된 다음 Snowflake Scripting 익명 블록을 실행합니다.

DECLARE
  name STRING;
  temperature FLOAT;
  res RESULTSET;
BEGIN
  name := 'Snowman';
  temperature := -20.14;
  res := (
    SELECT
      CONCAT('Hello ', :NAME, '!') as greeting,
      CONCAT('It is ', :TEMPERATURE, 'deg C today.') as weather
  );
  RETURN LAST_QUERY_ID();
END;
Copy

참고: Python Connector 코드에서 Snowflake CLI, SnowSQL, Classic Console, 또는 execute_stream 또는 execute_string 메서드를 사용하는 경우 이 예제를 대신 사용하십시오(Snowflake CLI, SnowSQL, Classic Console 및 Python Connector에서 Snowflake Scripting 사용하기 참조).

EXECUTE IMMEDIATE
$$
DECLARE
  name STRING;
  temperature FLOAT;
  res RESULTSET;
BEGIN
  name := 'Snowman';
  temperature := -20.14;
  res := (
    SELECT
      CONCAT('Hello ', :NAME, '!') as greeting,
      CONCAT('It is ', :TEMPERATURE, 'deg C today.') as weather
  );
  RETURN LAST_QUERY_ID();
END;
$$
;
Copy

블록은 바인드 변수를 사용하는 문의 쿼리 ID를 반환합니다.

참고

문은 여기에 표시된 것과 다른 쿼리 ID를 반환합니다.

+--------------------------------------+
| anonymous block                      |
|--------------------------------------|
| 01bbe3d6-0109-0863-0000-a99502ffa062 |
+--------------------------------------+

익명 블록에 사용된 바인드 변수를 검색하려면 다음 쿼리를 실행합니다. 익명 블록을 실행한 후 출력에서 ``01bbe3d6-0109-0863-0000-a99502ffa062``를 쿼리 ID로 바꿉니다.

SELECT * FROM TABLE(
  INFORMATION_SCHEMA.BIND_VALUES('01bbe3d6-0109-0863-0000-a99502ffa062'));
Copy
+--------------------------------------+----------+-------------+------+---------+
| QUERY_ID                             | POSITION | NAME        | TYPE | VALUE   |
|--------------------------------------+----------+-------------+------+---------|
| 01bbe3d6-0109-0863-0000-a99502ffa062 |     NULL | TEMPERATURE | REAL | -20.14  |
| 01bbe3d6-0109-0863-0000-a99502ffa062 |     NULL | NAME        | TEXT | Snowman |
+--------------------------------------+----------+-------------+------+---------+

위치 바인드 변수를 검색하는 Python Connector 예제

다음 Python Connector 코드는 BIND_VALUES 함수를 사용하여 출력에 위치 바인드 변수의 값을 표시합니다.

cursor = conn.cursor()
print(cursor.execute(
          """
          SELECT
              CONCAT('Hello ', ?, '!') as greeting,
              CONCAT('It is ', ?, 'deg C today.') as weather
          """,
          params=["Snowman", -20.14],
      ).fetch_pandas_all())

query_id = cursor.sfqid
print(f"Bind values for query {query_id} are:")
print(cursor.execute("SELECT * FROM TABLE(INFORMATION_SCHEMA.BIND_VALUES(?))", params=[query_id]).fetch_pandas_all())
Copy
        GREETING                   WEATHER
0  Hello Snowman!  It is -20.14deg C today.

Bind values for query 01bbe918-0200-0001-0000-000000101145 are:

                               QUERY_ID POSITION  NAME  TYPE    VALUE
0  01bbe918-0200-0001-0000-000000101145        1  None  TEXT  Snowman
1  01bbe918-0200-0001-0000-000000101145        2  None  REAL   -20.14

바인드 변수에 대한 제한 사항

바인드 변수에는 다음과 같은 제한 사항이 적용됩니다.

  • SELECT 문에 대한 제한 사항:

    • 바인드 변수는 데이터 타입 정의(예: NUMBER(?)) 또는 데이터 정렬 사양 (예: COLLATE ?)의 일부인 숫자를 대체할 수 없습니다.

    • 스테이지에 있는 파일을 쿼리하는 SELECT 문의 소스에는 바인드 변수를 사용할 수 없습니다.

  • DDL 명령의 제한 사항:

    • 다음 DDL 명령에는 바인드 변수를 사용할 수 없습니다.

      • CREATE/ALTER INTEGRATION

      • CREATE/ALTER REPLICATION GROUP

      • CREATE/ALTER PIPE

      • CREATE TABLE … USING TEMPLATE

    • 다음 절에는 바인드 변수를 사용할 수 없습니다.

      • ALTER COLUMN

      • COMMENT ON CONSTRAINT

    • CREATE/ALTER 명령에는 다음 매개 변수 값에 바인드 변수를 사용할 수 없습니다.

      • CREDENTIALS

      • DIRECTORY

      • ENCRYPTION

      • IMPORTS

      • PACKAGES

      • REFRESH

      • TAG

      • 외부 테이블에 특정한 매개 변수

    • 바인드 변수는 FILE FORMAT 값의 일부에 해당하는 속성에는 사용할 수 없습니다.

  • COPY INTO 명령에는 다음 매개 변수 값에 바인드 변수를 사용할 수 없습니다.

    • CREDENTIALS

    • ENCRYPTION

    • FILE_FORMAT

  • SHOW 명령에서 STARTS WITH 매개 변수에는 바인드 변수를 사용할 수 없습니다.

  • 바인드 변수는 EXECUTE IMMEDIATE FROM 명령에 사용할 수 없습니다.

  • 바인드 변수를 사용하는 경우 바인드 변수 값을 한 데이터 타입에서 다른 데이터 타입으로 자동 변환할 수 없습니다.

    • 데이터 타입을 명시적으로 지정하는 Snowflake Scripting 코드

    • DDL 문

    • 스테이지 이름

바인드 변수에 대한 보안 고려 사항

바인드 변수가 모든 경우에 민감한 데이터를 마스킹하는 것은 아닙니다. 예를 들어, 바인드 변수 값이 오류 메시지 및 기타 아티팩트에 표시될 수 있습니다.

바인드 변수는 사용자 입력으로 SQL 문을 구성할 때 SQL 삽입 공격을 방지하는 데 도움이 될 수 있습니다. 그러나 바인드 변수는 보안 위험을 초래할 가능성이 있습니다. SQL 문에 대한 입력이 외부 소스에서 제공된 경우 해당 입력의 유효성을 검사해야 합니다. 자세한 내용은 SQL 주입 섹션을 참조하십시오.