변수 작업하기

Snowflake Scripting에서는 식, Snowflake Scripting 문, SQL 문에 변수를 사용할 수 있습니다.

이 항목의 내용:

변수 선언하기

변수를 사용하려면 먼저 변수를 선언해야 합니다. 변수를 선언할 때 다음 중 하나를 통해 변수 타입을 지정해야 합니다.

다음과 같이 변수를 선언할 수 있습니다.

  • 다음 중 하나를 사용하여 블록의 DECLARE 섹션 내에서:

    <variable_name> <type>;
    
    <variable_name> DEFAULT <expression> ;
    
    <variable_name> <type> DEFAULT <expression> ;
    
    Copy
  • 다음 방법 중 하나로 LET 명령을 사용하여 블록의 BEGIN … END 섹션 내에서(변수를 사용하기 전에):

    LET <variable_name> <type> { DEFAULT | := } <expression> ;
    
    LET <variable_name> { DEFAULT | := } <expression> ;
    
    Copy

여기서:

variable_name

변수의 이름입니다. 이름은 오브젝트 식별자 에 대한 명명 규칙을 따라야 합니다.

type

변수의 데이터 타입입니다. 다음과 같을 수 있습니다.

DEFAULT expression 또는 . := expression

변수에 expression 의 값을 할당합니다.

typeexpression 이 둘 다 지정된 경우, 식은 일치하는 데이터 타입으로 평가되어야 합니다. 타입이 일치하지 않는 경우, 값을 지정된 type 으로 캐스팅 할 수 있습니다.

다음 예에서는 블록의 DECLARE 섹션과 BEGIN ... END 섹션에서 변수를 선언합니다.

DECLARE
    profit number(38, 2) DEFAULT 0.0;
BEGIN
    LET cost number(38, 2) := 100.0;
    LET revenue number(38, 2) DEFAULT 110.0;

    profit := revenue - cost;
    RETURN profit;
END;
Copy

참고: SnowSQL 또는 Classic Console 을 사용하는 경우 대신 다음 예를 사용하십시오(SnowSQL 및 Classic Console 에서 Snowflake Scripting 사용하기 참조).

EXECUTE IMMEDIATE $$
    DECLARE
        profit number(38, 2) DEFAULT 0.0;
    BEGIN
        LET cost number(38, 2) := 100.0;
        LET revenue number(38, 2) DEFAULT 110.0;

        profit := revenue - cost;
        RETURN profit;
    END;
$$
;
Copy

다음 섹션에서는 변수의 데이터 타입과 범위가 결정되는 방법을 설명합니다.

변수에 값을 할당하는 방법에 대한 자세한 내용은 선언된 변수에 값 할당하기 섹션을 참조하십시오.

Snowflake Scripting이 변수의 데이터 타입을 유추하는 방법

앞서 언급했듯이, 데이터 타입을 명시적으로 지정하지 않고 변수를 선언하면 Snowflake Scripting은 변수에 할당한 식에서 데이터 타입을 유추합니다.

선언에서 데이터 타입을 생략하도록 선택한 경우, 다음 사항에 유의하십시오.

  • 식이 크기가 다른 다양한 데이터 타입으로 해석될 수 있는 경우, 일반적으로 Snowflake는 유연하고(예: NUMBER(3, 1) 대신 FLOAT) 저장 용량이 큰(예: VARCHAR(4) 대신 VARCHAR) 타입을 선택합니다.

    예를 들어 변수를 값 12.3 으로 설정하면 Snowflake는 다음을 포함하여 변수에 대한 여러 데이터 타입 중 하나를 선택할 수 있습니다.

    • NUMBER(3, 1)

    • NUMBER(38, 1)

    • FLOAT

    이 예에서 Snowflake는 FLOAT를 선택합니다.

    변수에 대한 특정 데이터 타입(특히 숫자 또는 타임스탬프 타입)이 필요한 경우, Snowflake는 사용자가 초기 값을 제공하더라도 데이터 타입을 명시적으로 지정할 것을 권장합니다.

  • Snowflake가 의도된 데이터 타입을 유추할 수 없는 경우, Snowflake는 SQL 컴파일 오류를 보고합니다.

    예를 들어 다음 코드는 데이터 타입을 명시적으로 지정하지 않고 변수를 선언합니다. 코드는 변수를 커서의 값으로 설정합니다.

    ...
    for current_row in cursor_1 do:
        let price := current_row.price_column;
        ...
    
    Copy

    Snowflake Scripting 블록이 컴파일되면(예: CREATE PROCEDURE 명령이 실행될 때) 커서는 열리지 않고, 커서에 있는 열의 데이터 타입을 알 수 없습니다. 결과적으로 Snowflake는 SQL 컴파일 오류를 보고합니다.

    092228 (P0000): SQL compilation error:
        error line 7 at position 4 variable 'PRICE' cannot have its type inferred from initializer
    
    Copy

선언 범위 이해하기

Snowflake Scripting은 어휘적 범위 지정 을 사용합니다. 값, 결과 세트, 커서 또는 예외에 대한 변수가 블록의 DECLARE 섹션에서 선언된 경우, 선언된 오브젝트의 범위(또는 가시성)는 해당 블록과 해당 블록에 중첩된 모든 블록입니다.

블록이 외부 블록에 선언된 오브젝트와 이름이 같은 오브젝트를 선언하는 경우, 내부 블록(및 해당 블록 내부의 모든 블록) 내에서, 내부 블록의 오브젝트만 범위 내에 있습니다. 오브젝트 이름이 참조된 경우, Snowflake는 현재 블록에서 먼저 시작하여 이름이 일치하는 오브젝트를 찾을 때까지 바깥쪽으로 한 번에 한 블록씩 작업하여, 해당 이름을 가진 오브젝트를 찾습니다.

예를 들어 저장 프로시저 내에서 예외가 선언된 경우, 예외의 범위는 해당 저장 프로시저로 제한됩니다. 해당 저장 프로시저에 의해 호출된 저장 프로시저는 해당 예외를 발생시킬(또는 처리할) 수 없습니다. 해당 프로시저를 호출하는 저장 프로시저는 해당 예외를 처리할(또는 발생시킬) 수 없습니다.

선언된 변수에 값 할당하기

이미 선언된 변수에 값을 할당하려면 := 연산자를 사용합니다.

<variable_name> := <expression> ;
Copy

여기서:

variable_name

변수의 이름입니다. 이름은 오브젝트 식별자 에 대한 명명 규칙을 따라야 합니다.

expression

식이 평가되고 결과 값이 변수에 할당됩니다.

식은 변수 타입과 일치하는 데이터 타입으로 평가되어야 합니다. 식이 타입과 일치하지 않으면 값을 타입 유형으로 캐스팅 할 수 있습니다.

식에서 기본 제공 SQL 함수 및 UDF (사용자 정의 함수)를 포함한 함수를 사용할 수 있습니다.

변수 사용하기

Snowflake Scripting 언어 요소(예: RETURN)와 함께 식에 변수를 사용할 수 있습니다. 예를 들어, 아래 코드에서는 식에 변수 revenuecost 를 사용하고 RETURN 문에 변수 profit 을 사용합니다.

DECLARE
    profit NUMBER(38, 2);
    revenue NUMBER(38, 2);
    cost NUMBER(38, 2);
BEGIN
    ...
    profit := revenue - cost;
    ...
    RETURN profit;
Copy

SQL 문에서 변수 사용하기(바인딩)

SQL 문에서 변수를 사용할 수 있습니다. (이를 때로는 변수 바인딩 이라고도 합니다.) 변수 이름 앞에 콜론을 붙입니다. 예:

INSERT INTO my_table (x) VALUES (:my_variable)
Copy

변수를 오브젝트의 이름으로 사용하는 경우(예: SELECT 문의 FROM 절에 있는 테이블의 이름) IDENTIFIER 키워드를 사용하여 변수가 오브젝트 식별자를 나타냄을 표시합니다. 예:

SELECT COUNT(*) FROM IDENTIFIER(:table_name)
Copy

식에서 변수를 사용하거나 Snowflake Scripting 언어 요소 (예: RETURN)를 함께 사용하는 경우 변수 앞에 콜론을 접두사로 붙일 필요가 없습니다.

예를 들어, 다음과 같은 경우에는 콜론 접두사가 필요 없습니다.

  • RETURN과 함께 변수를 사용하는 경우. 이 예에서는 변수 profit 이 Snowflake Scripting 언어 요소와 함께 사용되며 콜론 접두사가 불필요합니다.

    RETURN profit;
    
    Copy
  • 실행할 SQL 문을 포함한 문자열을 작성 중인 경우. 이 예에서는 변수 id_variable 이 식에 사용되며 콜론 접두사가 불필요합니다.

    LET select_statement := 'SELECT * FROM invoices WHERE id = ' || id_variable;
    
    Copy

SELECT 문의 결과에 대한 변수 설정하기

Snowflake Scripting 블록에서 INTO 절을 사용해 변수를 SELECT 절에 지정된 식의 값으로 설정할 수 있습니다.

SELECT <expression1>, <expression2>, ... INTO :<variable1>, :<variable2>, ... FROM ... WHERE ...;
Copy

이 구문을 사용할 때 다음 사항이 적용됩니다.

  • variable1expression1 의 값으로 설정됩니다.

  • variable2expression2 의 값으로 설정됩니다.

SELECT 문은 단일 행을 반환해야 합니다.

다음 예에는 단일 행을 반환하는 SELECT 문이 포함되어 있습니다. 이 예에서는 다음 테이블의 데이터를 사용합니다.

CREATE OR REPLACE TABLE some_data (id INTEGER, name VARCHAR);
INSERT INTO some_data (id, name) VALUES
  (1, 'a'),
  (2, 'b');
Copy

이 예에서는 Snowflake Scripting 변수 idname 을 해당 이름이 있는 열에 대해 반환된 값으로 설정합니다.

DECLARE
  id_variable INTEGER;
  name_variable VARCHAR;
BEGIN
  SELECT id, name INTO :id_variable, :name_variable FROM some_data WHERE id = 1;
  RETURN id_variable || ' ' || name_variable;
END;
Copy

참고: SnowSQL 또는 Classic Console 을 사용하는 경우 대신 다음 예를 사용하십시오(SnowSQL 및 Classic Console 에서 Snowflake Scripting 사용하기 참조).

EXECUTE IMMEDIATE $$
DECLARE
  id INTEGER;
  name VARCHAR;
BEGIN
  SELECT id, name INTO :id, :name FROM some_data WHERE id = 1;
  RETURN :id || ' ' || :name;
END;
$$
;
Copy

이 예에서는 SELECT 문에 의해 반환된 행에서 ID와 이름을 출력합니다.

+-----------------+
| anonymous block |
|-----------------|
| 1 a             |
+-----------------+
Copy

저장 프로시저의 반환 값으로 변수 설정하기

저장 프로시저 호출에서 반환된 값 사용하기 섹션을 참조하십시오.

변수 사용의 예

다음 예에서는 변수를 선언하고, 변수에 값이나 식을 할당하고, 변수의 데이터 타입에 값을 캐스팅하는 방법을 보여줍니다.

DECLARE
  w INTEGER;
  x INTEGER DEFAULT 0;
  dt DATE;
  result_string VARCHAR;
BEGIN
  w := 1;                     -- Assign a value.
  w := 24 * 7;                -- Assign the result of an expression.
  dt := '2020-09-30'::DATE;   -- Explicit cast.
  dt := '2020-09-30';         -- Implicit cast.
  result_string := w::VARCHAR || ', ' || dt::VARCHAR;
  RETURN result_string;
END;
Copy

참고: SnowSQL 또는 Classic Console 을 사용하는 경우 대신 다음 예를 사용하십시오(SnowSQL 및 Classic Console 에서 Snowflake Scripting 사용하기 참조).

EXECUTE IMMEDIATE $$
DECLARE
    w INTEGER;
    x INTEGER DEFAULT 0;
    dt DATE;
    result_string VARCHAR;
BEGIN
    w := 1;                     -- Assign a value.
    w := 24 * 7;                -- Assign the result of an expression.
    dt := '2020-09-30'::DATE;   -- Explicit cast.
    dt := '2020-09-30';         -- Implicit cast.
    result_string := w::VARCHAR || ', ' || dt::VARCHAR;
    RETURN result_string;
END;
$$
;
Copy

다음 예에서는 식에 기본 제공 SQL 함수를 사용합니다.

my_variable := SQRT(variable_x);
Copy

다음 선언은 각 변수에 대해 의도된 데이터 타입의 초기 값을 지정하여 변수 profit, cost, revenue 의 데이터 타입을 암시적으로 지정합니다.

이 예에서는 LET 문을 사용하여 블록의 DECLARE 부분 외부에 costrevenue 변수를 선언하는 방법도 보여줍니다.

DECLARE
  profit number(38, 2) DEFAULT 0.0;
BEGIN
  LET cost number(38, 2) := 100.0;
  LET revenue number(38, 2) DEFAULT 110.0;

  profit := revenue - cost;
  RETURN profit;
END;
Copy

참고: SnowSQL 또는 Classic Console 을 사용하는 경우 대신 다음 예를 사용하십시오(SnowSQL 및 Classic Console 에서 Snowflake Scripting 사용하기 참조).

EXECUTE IMMEDIATE $$
DECLARE
    profit DEFAULT 0.0;
BEGIN
    LET cost := 100.0;
    LET revenue DEFAULT 110.0;
    profit := revenue - cost;
    RETURN profit;
END;
$$
;
Copy

다음 예는 변수의 범위를 보여줍니다. 이 예에는 이름은 같지만 범위가 다른 두 개의 변수와 매개 변수가 포함되어 있습니다.

이 예에는 세 가지 블록, 즉 가장 바깥쪽, 중간, 가장 안쪽 블록이 있습니다.

  • 가장 안쪽 블록 내에서 PV_NAME은 가장 안쪽 블록에서 선언되고 설정된 변수(innermost block variable 로 설정됨)로 해석됩니다.

  • 중간 블록 내에서(및 가장 안쪽 블록의 외부에서) PV_NAME은 중간 블록에서 선언되고 설정된 변수(middle block variable 로 설정됨)로 해석됩니다.

  • 가장 바깥쪽 블록 내에서(및 중첩 블록의 외부에서) PV_NAME은 저장 프로시저에 전달된 매개 변수(CALL 문에 의해 parameter 로 설정됨)로 확인됩니다.

예를 들어, 가장 안쪽 블록의 PV_NAME에 문자열 innermost block variable 을 할당해도 중간 블록의 변수 값에는 영향을 미치지 않습니다. 가장 안쪽 블록의 변수는 중간 블록의 변수와 다릅니다. 두 변수의 이름이 같더라도 마찬가지입니다.

CREATE PROCEDURE duplicate_name(pv_name VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
AS
BEGIN
  DECLARE
    PV_NAME VARCHAR;
  BEGIN
    PV_NAME := 'middle block variable';
    DECLARE
      PV_NAME VARCHAR;
    BEGIN
      PV_NAME := 'innermost block variable';
      INSERT INTO names (v) VALUES (:PV_NAME);
    END;
    -- Because the innermost and middle blocks have separate variables
    -- named "pv_name", the INSERT below inserts the value
    -- 'middle block variable'.
    INSERT INTO names (v) VALUES (:PV_NAME);
  END;
  -- This inserts the value of the input parameter.
  INSERT INTO names (v) VALUES (:PV_NAME);
  RETURN 'Completed.';
END;
Copy

참고: SnowSQL 또는 Classic Console 을 사용하는 경우 대신 다음 예를 사용하십시오(SnowSQL 및 Classic Console 에서 Snowflake Scripting 사용하기 참조).

CREATE PROCEDURE duplicate_name(pv_name VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
    BEGIN
        DECLARE
            PV_NAME VARCHAR;
        BEGIN
            PV_NAME := 'middle block variable';
            DECLARE
                PV_NAME VARCHAR;
            BEGIN
                PV_NAME := 'innermost block variable';
                INSERT INTO names (v) VALUES (:PV_NAME);
            END;
            -- Because the innermost and middle blocks have separate variables
            -- named "pv_name", the INSERT below inserts the value
            -- 'middle block variable'.
            INSERT INTO names (v) VALUES (:PV_NAME);
        END;
        -- This inserts the value of the input parameter.
        INSERT INTO names (v) VALUES (:PV_NAME);
        RETURN 'Completed.';
    END;
$$
;
Copy

저장 프로시저를 호출합니다.

CALL duplicate_name('parameter');
Copy

테이블의 값을 확인합니다. 이는 다음을 보여줍니다.

  • 가장 안쪽에 중첩된 블록(두 개의 레이어가 중첩됨)에는 내부 블록의 변수 PV_NAME 이 사용되었습니다.

  • 중간 블록(한 레이어가 중첩됨)에서는 중간 블록의 변수 PV_NAME 이 사용되었습니다.

  • 가장 바깥쪽 블록에는 매개 변수가 사용되었습니다.

    SELECT *
        FROM names
        ORDER BY v;
    +--------------------------+
    | V                        |
    |--------------------------|
    | innermost block variable |
    | middle block variable    |
    | parameter                |
    +--------------------------+
    
    Copy

커서를 열 때 변수를 바인딩하는 예는 커서 열기의 예 를 참조하십시오.