RESULTSET 작업하기

이 항목에서는 Snowflake Scripting에서 RESULTSET를 사용하는 방법을 설명합니다.

이 항목의 내용:

소개

Snowflake Scripting에서 RESULTSET는 쿼리의 결과 세트를 가리키는 SQL 데이터 타입입니다.

RESULTSET는 결과에 대한 포인터일 뿐이므로 RESULTSET를 통해 결과에 액세스하려면 다음 중 하나를 수행해야 합니다.

  • TABLE() 구문을 사용하여 결과를 테이블로 검색합니다.

  • 커서 로 RESULTSET를 반복합니다.

이 두 가지의 예가 아래에 포함되어 있습니다.

커서와 RESULTSET의 차이점 이해하기

RESULTSET와 커서 는 둘 다 쿼리의 결과 세트에 대한 액세스를 제공합니다. 그러나 이러한 오브젝트는 다음과 같은 면에서 다릅니다.

  • 쿼리가 실행되는 시점.

    • 커서의 경우 커서에서 OPEN 명령을 실행할 때 쿼리가 실행됩니다.

    • RESULTSET의 경우 쿼리를 RESULTSET(DECLARE 섹션 또는 BEGIN … END 블록)에 할당하면 쿼리가 실행됩니다.

  • OPEN 명령에서 바인딩 지원.

    • 커서를 선언할 때 바인딩 매개 변수(? 문자)를 지정할 수 있습니다. 나중에 OPEN 명령을 실행할 때 USING 절의 해당 매개 변수에 변수를 바인딩할 수 있습니다.

    • RESULTSET는 OPEN 명령을 지원하지 않습니다.

커서가 있고 Snowflake Scripting 블록에서 테이블을 반환해야 하는 경우, 커서를 RESULTSET_FROM_CURSOR(cursor) 로 전달하여 RESULTSET를 반환하고 해당 RESULTSET를 TABLE(...) 로 전달할 수 있습니다. 커서에 대한 테이블 반환하기 섹션을 참조하십시오.

RESULTSET 선언하기

블록의 DECLARE 섹션 또는 블록의 BEGIN … END 섹션에서 RESULTSET를 선언할 수 있습니다.

  • DECLARE 섹션 내에서, RESULTSET 선언 구문 에 설명된 구문을 사용합니다. 예:

    DECLARE
      ...
      res RESULTSET DEFAULT (SELECT col1 FROM mytable ORDER BY col1);
    
    Copy
  • BEGIN … END 블록 내에서, RESULTSET 할당 구문 에 설명된 구문을 사용합니다. 예:

    BEGIN
      ...
      LET res RESULTSET := (SELECT col1 FROM mytable ORDER BY col1);
    
    Copy

선언된 RESULTSET에 쿼리 할당하기

이미 선언된 RESULTSET에 쿼리 결과를 할당하려면 다음 구문을 사용합니다.

<resultset_name> := ( <query> ) ;
Copy

여기서:

resultset_name

RESULTSET에 부여할 이름입니다.

이름은 현재 범위 내에서 고유해야 합니다.

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

query

RESULTSET에 할당할 쿼리입니다.

예:

DECLARE
  res RESULTSET;
BEGIN
  res := (SELECT col1 FROM mytable ORDER BY col1);
  ...
Copy

쿼리에 대해 동적으로 SQL 문자열을 빌드해야 하는 경우 query(EXECUTE IMMEDIATE string_of_sql) 로 설정합니다. 예:

DECLARE
  res RESULTSET;
  col_name VARCHAR;
  select_statement VARCHAR;
BEGIN
  col_name := 'col1';
  select_statement := 'SELECT ' || col_name || ' FROM mytable';
  res := (EXECUTE IMMEDIATE :select_statement);
  RETURN TABLE(res);
END;
Copy

query 를 RESULTSET에 대한 EXECUTE IMMEDIATE 문으로 설정할 수 있지만, 커서에 대해서는 이 작업을 수행할 수 없습니다.

RESULTSET 사용하기

RESULTSET에 대한 쿼리는 오브젝트가 해당 쿼리와 연결될 때 실행됩니다. 예:

  • RESULTSET를 선언하고 DEFAULT 절을 쿼리에 설정하면 해당 시점에서 쿼리가 실행됩니다.

  • := 연산자를 사용하여 RESULTSET에 쿼리를 할당하면 해당 시점에서 쿼리가 실행됩니다.

참고

RESULTSET는 쿼리의 결과 세트를 가리키기 때문에(쿼리의 결과 세트는 포함하지 않음) RESULTSET는 쿼리 결과가 캐시되는 동안(일반적으로 24시간)에만 유효합니다. 쿼리 결과 캐싱에 대한 자세한 내용은 지속형 쿼리 결과 사용하기 섹션을 참조하십시오.

쿼리가 실행되면 커서를 사용하여 결과에 액세스할 수 있습니다. 저장 프로시저에서 결과를 테이블로 반환할 수도 있습니다.

커서를 사용하여 RESULTSET의 데이터에 액세스하기

커서를 사용하여 RESULTSET의 데이터에 액세스하려면 오브젝트에 커서를 선언합니다. 예:

DECLARE
  ...
  res RESULTSET DEFAULT (SELECT col1 FROM mytable ORDER BY col1);
  c1 CURSOR FOR res;
Copy

RESULTSET에 커서를 선언하면 커서는 RESULTSET에 이미 있는 데이터에 액세스할 수 있습니다. 커서에서 OPEN 명령을 실행하면 RESULTSET에 대한 쿼리가 다시 실행되지 않습니다.

그런 다음 커서를 열고 커서를 사용하여 데이터를 가져올 수 있습니다.

참고

결과에 GEOGRAPHY 값이 포함된 경우 값을 GEOGRAPHY 유형으로 캐스트한 후에 GEOGRAPHY 입력 값을 예상하는 함수에 값을 전달해야 합니다. 커서를 사용하여 GEOGRAPHY 값 검색하기 섹션을 참조하십시오.

RESULTSET를 테이블로 반환하기

RESULTSET가 가리키는 결과를 반환하려면 RESULTSET를 TABLE() 에 전달합니다. 예:

CREATE PROCEDURE f()
  RETURNS TABLE(column_1 INTEGER, column_2 VARCHAR)
  ...
    RETURN TABLE(my_resultset_1);
  ...
Copy

이는 TABLE()테이블 함수 (예: RESULT_SCAN)와 함께 사용되는 방식과 유사합니다.

예와 같이, 테이블을 반환하는 저장 프로시저를 작성하는 경우, 저장 프로시저를 테이블을 반환하는 것으로 선언해야 합니다.

참고

현재, TABLE(resultset_name) 구문은 RETURN 문에서만 지원됩니다.

커서를 사용하여 RESULTSET에서 행을 가져온 경우에도, TABLE(resultset_name) 에 의해 반환된 테이블에는 (커서의 내부 행 포인터에서 시작하는 행뿐 아니라) 여전히 모든 행이 포함되어 있습니다.

RESULTSET 데이터 타입의 제한 사항

RESULTSET 는 데이터 타입이지만, Snowflake는 아직 다음을 지원하지 않습니다.

  • RESULTSET 타입의 열 선언.

  • RESULTSET 타입의 매개 변수 선언 .

  • 저장 프로시저의 반환 유형을 RESULTSET으로 선언.

Snowflake는 Snowflake Scripting 내에서만 RESULTSET를 지원합니다.

또한 RESULTSET를 테이블로 직접 사용할 수 없습니다. 예를 들어 다음은 유효하지 않습니다.

select * from my_result_set;
Copy

RESULTSET 사용 예

다음 섹션에서는 RESULTSET를 사용하는 예를 제시합니다.

예제를 위한 데이터 설정하기

아래의 많은 예에서는 아래에 표시된 테이블과 데이터를 사용합니다.

CREATE TABLE t001 (a INTEGER, b VARCHAR);
INSERT INTO t001 (a, b) VALUES
    (1, 'row1'),
    (2, 'row2');
Copy

예: 저장 프로시저에서 테이블 반환하기

다음 코드는 RESULTSET를 선언하고 RESULTSET가 가리키는 결과를 반환하는 방법을 보여줍니다. CREATE PROCEDURE 명령의 RETURNS 절은 저장 프로시저가 INTEGER 타입의 열 하나를 포함하는 테이블을 반환한다고 선언합니다.

블록 내부의 RETURN 문은 TABLE() 구문을 사용하여 결과를 테이블로 반환합니다.

저장 프로시저를 만듭니다.

CREATE OR REPLACE PROCEDURE test_sp()
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
  DECLARE
    res RESULTSET default (select a from t001 order by a);
  BEGIN
    RETURN TABLE(res);
  END;
Copy

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

CREATE OR REPLACE PROCEDURE test_sp()
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
$$
    DECLARE
        res RESULTSET default (select a from t001 order by a);
    BEGIN
        RETURN TABLE(res);
    END;
$$;
Copy

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

CALL test_sp();
+---+
| A |
|---|
| 1 |
| 2 |
+---+
Copy

RESULT_SCAN 함수를 사용하여 저장 프로시저 호출의 결과를 처리할 수 있습니다.

SELECT *
    FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
    ORDER BY 1;
+---+
| A |
|---|
| 1 |
| 2 |
+---+
Copy

예: 동적으로 SQL 문 생성하기

SQL을 동적으로 구성할 수 있습니다. 다음은 위의 저장 프로시저와 동일한 쿼리를 실행하지만, 동적으로 구성된 SQL 문을 사용하는 예입니다.

CREATE OR REPLACE PROCEDURE test_sp_dynamic(table_name VARCHAR)
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
  DECLARE
    res RESULTSET;
    query VARCHAR DEFAULT 'SELECT a FROM ' || :table_name || ' ORDER BY a';
  BEGIN
    res := (EXECUTE IMMEDIATE :query);
    RETURN TABLE (res);
  END;
Copy

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

CREATE OR REPLACE PROCEDURE test_sp_dynamic(table_name VARCHAR)
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
$$
  DECLARE
    res RESULTSET;
    query VARCHAR DEFAULT 'SELECT a FROM ' || :table_name || ' ORDER BY a';
  BEGIN
    res := (EXECUTE IMMEDIATE :query);
    RETURN TABLE (res);
  END;
$$
;
Copy

예를 실행하려면 저장 프로시저를 호출하고 테이블 이름을 전달합니다.

call test_sp_dynamic('t001');

+---+
| A |
|---|
| 1 |
| 2 |
+---+
Copy

예: DEFAULT 절 없이 RESULTSET 변수 선언하기

다음 코드는 DEFAULT 절 없이(즉, 쿼리를 RESULTSET와 연결하지 않고) RESULTSET를 선언한 다음 나중에 RESULTSET를 쿼리와 연결하는 방법을 보여줍니다.

CREATE OR REPLACE PROCEDURE test_sp_02()
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
  DECLARE
    res RESULTSET;
  BEGIN
    res := (select a from t001 order by a);
    RETURN TABLE(res);
  END;
Copy

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

CREATE OR REPLACE PROCEDURE test_sp_02()
RETURNS TABLE(a INTEGER)
LANGUAGE SQL
AS
$$
    DECLARE
        res RESULTSET;
    BEGIN
        res := (select a from t001 order by a);
        RETURN TABLE(res);
    END;
$$;
Copy

예: RESULTSET와 함께 CURSOR 사용하기

다음 코드는 커서 를 사용하여 RESULTSET의 행을 반복하는 방법을 보여줍니다.

저장 프로시저를 만듭니다.

CREATE OR REPLACE PROCEDURE test_sp_03()
RETURNS VARCHAR
LANGUAGE SQL
AS

  DECLARE
    accumulator INTEGER DEFAULT 0;
    res1 RESULTSET DEFAULT (select a from t001 order by a);
    cur1 CURSOR FOR res1;
  BEGIN
    FOR row_variable IN cur1 DO
      accumulator := accumulator + row_variable.a;
    END FOR;
    RETURN accumulator::VARCHAR;
  END;
Copy

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

CREATE OR REPLACE PROCEDURE test_sp_03()
RETURNS INTEGER
LANGUAGE SQL
AS
$$
    DECLARE
        accumulator INTEGER DEFAULT 0;
        res1 RESULTSET DEFAULT (select a from t001 order by a);
        cur1 CURSOR FOR res1;
    BEGIN
        FOR row_variable IN cur1 DO
                accumulator := accumulator + row_variable.a;
        END FOR;
        RETURN accumulator;
    END;
$$;
Copy

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

CALL test_sp_03();
+------------+
| TEST_SP_03 |
|------------|
| 3          |
+------------+
Copy