CALL(익명 프로시저 사용)

저장 프로시저 와 같지만 나중에 사용할 수 있도록 저장하지 않는 익명 프로시저를 만들고 호출합니다.

이 명령으로 WITH 절의 매개 변수로 정의된 익명 프로시저를 만들고 그 프로시저를 호출하기도 합니다.

이 명령에 대해 CREATE PROCEDURE 스키마 권한이 있는 역할이 없어도 됩니다.

프로시저는 호출자의 권한 으로 실행되는데, 이는 프로시저가 호출자의 권한으로 실행되고 현재 세션 컨텍스트를 사용하며 호출자의 세션 변수와 매개 변수에 액세스할 수 있다는 뜻입니다.

참고 항목:

CREATE PROCEDURE , CALL.

구문

Java 및 Scala

WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
  RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE { SCALA | JAVA }
  RUNTIME_VERSION = '<scala_or_java_runtime_version>'
  PACKAGES = ( 'com.snowflake:snowpark:<version>' [, '<package_name_and_version>' ...] )
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
  HANDLER = '<fully_qualified_method_name>'
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ AS '<procedure_definition>' ]
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

스테이징된 처리기 가 있는 Java 및 Scala 프로시저의 경우 다음 구문을 사용하십시오.

WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
  RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE { SCALA | JAVA }
  RUNTIME_VERSION = '<scala_or_java_runtime_version>'
  PACKAGES = ( 'com.snowflake:snowpark:<version>' [, '<package_name_and_version>' ...] )
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
  HANDLER = '<fully_qualified_method_name>'
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

JavaScript

WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
  RETURNS <result_data_type> [ [ NOT ] NULL ]
  LANGUAGE JAVASCRIPT
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  AS '<procedure_definition>'
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

Python

인라인 프로시저의 경우 다음 구문을 사용합니다.

WITH <name> AS PROCEDURE ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE PYTHON
  RUNTIME_VERSION = '<python_version>'
  PACKAGES = ( 'snowflake-snowpark-python[==<version>]'[, '<package_name>[==<version>]' ... ])
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
  HANDLER = '<function_name>'
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
  AS '<procedure_definition>'
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

코드가 스테이지의 파일에 있는 프로시저의 경우 다음 구문을 사용하십시오.

WITH <name> AS PROCEDURE ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE PYTHON
  RUNTIME_VERSION = '<python_version>'
  PACKAGES = ( 'snowflake-snowpark-python[==<version>]'[, '<package_name>[==<version>]' ... ])
  [ IMPORTS = ( '<stage_path_and_file_name_to_read>' [, '<stage_path_and_file_name_to_read>' ...] ) ]
  HANDLER = '<module_file_name>.<function_name>'
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

Snowflake Scripting

WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
  RETURNS { <result_data_type> | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
  LANGUAGE SQL
  [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
  AS '<procedure_definition>'
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ [ <arg_name> => ] <arg> , ... ] )
  [ INTO :<snowflake_scripting_variable> ]
Copy

필수 매개 변수

모든 언어

WITH name AS PROCEDURE ( [ arg_name arg_data_type ] [ , ... ] )

프로시저에 대한 식별자(name) 및 입력 인자를 지정합니다.

  • 식별자의 경우:

    • 식별자는 알파벳 문자로 시작해야 하며 전체 식별자 문자열을 큰따옴표(예: 《My object》)로 묶지 않는 한 공백이나 특수 문자를 포함할 수 없습니다. 큰따옴표로 묶인 식별자도 대/소문자를 구분합니다. 식별자 요구 사항 섹션을 참조하십시오.

  • 입력 인자의 경우:

RETURNS result_data_type [ [ NOT ] NULL ]

프로시저에서 반환된 결과 타입을 지정합니다.

NOT NULL을 사용하여 프로시저가 null이 아닌 값만 반환해야 함을 지정합니다. 기본값은 NULL인데, 이는 프로시저가 NULL을 반환할 수 있음을 의미합니다.

  • result_data_type 의 경우, 사용 중인 언어의 타입에 해당하는 Snowflake 데이터 타입을 사용합니다.

    참고

    Java 또는 Scala에서 작성하는 프로시저에는 반환 값이 있어야 합니다. Python에서 프로시저가 아무런 값도 반환하지 않으면 None 을 반환하는 것으로 간주됩니다.

    처리기 언어에 상관없이, 프로시저가 명시적으로 아무것도 반환하지 않더라도 이 명령의 WITH 절에는 반환 타입을 정의하는 RETURNS 절이 포함되어야 합니다.

  • RETURNS TABLE ( [ col_name col_data_type [ , ... ] ] ) 의 경우 반환된 테이블에 있는 열의 Snowflake 데이터 타입 을 알면 열 이름과 유형을 지정하십시오.

    WITH get_top_sales() AS PROCEDURE
      RETURNS TABLE (sales_date DATE, quantity NUMBER)
      ...
    CALL get_top_sales();
    
    Copy

    그렇지 않으면(예: 런타임 중에 열 유형을 결정하는 경우) 열 이름과 유형을 생략할 수 있습니다.

    WITH get_top_sales() AS PROCEDURE
      ...
      RETURNS TABLE ()
    CALL get_top_sales();
    
    Copy

    참고

    현재, RETURNS TABLE(...) 절에서는 GEOGRAPHY를 열 유형으로 지정할 수 없습니다. 이는 저장 프로시저를 생성하든 익명 프로시저를 생성하든 관계없이 적용됩니다.

    CREATE OR REPLACE PROCEDURE test_return_geography_table_1()
      RETURNS TABLE(g GEOGRAPHY)
      ...
    
    Copy
    WITH test_return_geography_table_1() AS PROCEDURE
      RETURNS TABLE(g GEOGRAPHY)
      ...
    CALL test_return_geography_table_1();
    
    Copy

    GEOGRAPHY를 열 유형으로 지정하려고 할 경우 저장 프로시저를 호출하면 오류가 발생합니다.

    Stored procedure execution error: data type of returned table does not match expected returned table type
    
    Copy

    이 문제를 해결하려면 RETURNS TABLE() 에서 열 인자와 유형을 생략하면 됩니다.

    CREATE OR REPLACE PROCEDURE test_return_geography_table_1()
      RETURNS TABLE()
      ...
    
    Copy
    WITH test_return_geography_table_1() AS PROCEDURE
      RETURNS TABLE()
      ...
    CALL test_return_geography_table_1();
    
    Copy

    RETURNS TABLE(...) 은 처리기가 다음 언어로 작성된 경우에만 지원됩니다.

실제로는, Snowflake Scripting 블록 외부에서는 호출이 식의 일부가 될 수 없으므로 반환된 값을 사용할 수 없습니다.

LANGUAGE language

프로시저의 처리기 코드 언어를 지정합니다.

현재, 지원되는 language 값은 다음과 같습니다.

AS procedure_definition

프로시저로 실행되는 코드를 정의합니다. 정의는 어떤 유효한 코드로든 구성될 수 있습니다.

다음 사항을 참고하십시오.

  • 코드가 인라인이 아닌 프로시저의 경우 AS 절을 생략합니다. 여기에는 처리기가 스테이지에 있는 프로시저가 포함됩니다.

    대신 IMPORTS 절을 사용하여 프로시저에 대한 코드가 포함된 파일의 위치를 지정하십시오. 자세한 내용은 다음을 참조하십시오.

  • Snowflake Scripting에서도 procedure definition 주위에 문자열 리터럴 구분 기호 (' 또는 $$)를 사용해야 합니다.

  • JavaScript로 작성된 프로시저의 경우, 줄 바꿈을 포함하는 문자열을 작성 중이라면 문자열 주위에 역따옴표(《억음 부호》라고도 함)를 사용할 수 있습니다.

    JavaScript 프로시저의 다음 예에서는 프로시저의 본문에 작은따옴표와 큰따옴표가 포함되어 있으므로 $$ 및 역따옴표를 사용합니다.

    WITH proc3 AS PROCEDURE ()
      RETURNS VARCHAR
      LANGUAGE javascript
      AS
      $$
      var rs = snowflake.execute( { sqlText:
          `INSERT INTO table1 ("column 1")
              SELECT 'value 1' AS "column 1" ;`
          } );
      return 'Done.';
      $$
    CALL proc3();
    
    Copy
  • Snowflake는 처리기 코드의 유효성을 검사하지 않습니다. 하지만 유효하지 않은 처리기 코드는 명령을 실행할 때 오류를 발생시킵니다.

저장 프로시저에 대한 자세한 내용은 저장 프로시저 작업하기 섹션을 참조하십시오.

CALL name ( [ [ arg_name => ] arg , ... ] )

호출할 프로시저의 식별자(name)와 입력 인자를 지정합니다.

이름(arg_name => arg) 또는 위치(arg)로 입력 인자를 지정할 수 있습니다.

다음 사항을 참고하십시오.

  • 이름 또는 위치로 모든 인자를 지정해야 합니다. 일부 인자는 이름으로, 다른 인자는 위치로 지정할 수는 없습니다.

    이름으로 인자를 지정할 때 인자 이름 주위에 큰따옴표를 사용할 수 없습니다.

  • 두 함수 또는 두 프로시저가 이름은 같지만 인자 유형이 다른 경우 인자 이름이 다르면 인자 이름을 사용하여 실행할 함수 또는 프로시저를 지정할 수 있습니다. 프로시저 및 함수 오버로딩하기 섹션을 참조하십시오.

Java, Python 또는 Scala

RUNTIME_VERSION = 'language_runtime_version'

사용할 언어 런타임 버전입니다. 현재 지원되는 버전은 다음과 같습니다.

  • Java: 11

  • Python:

    • 3.8

    • 3.9

    • 3.10

    • 3.11

  • Scala: 2.12

PACKAGES = ( 'snowpark_package_name' [, 'package_name' ...] )

Snowflake에 배포되어 처리기 코드의 실행 환경에 포함해야 하는 패키지의 이름이 수록된 쉼표로 구분된 목록입니다. Snowpark 패키지는 프로시저에 필수적이므로, PACKAGES 절에서 항상 참조해야 합니다. Snowpark에 대한 자세한 내용은 Snowpark API 섹션을 참조하십시오.

기본적으로, Snowflake가 프로시저를 실행하는 환경에는 지원되는 언어용으로 선택된 패키지 세트가 포함됩니다. PACKAGES 절에서 이러한 패키지를 참조할 때 Snowflake에서 해당 패키지를 이미 제공하므로 IMPORTS 절에 패키지가 포함된 파일을 참조할 필요가 없습니다.

특정 언어에 대해 지원되는 패키지 및 버전 목록을 보려면 언어를 지정하는 INFORMATION_SCHEMA.PACKAGES 뷰 를 쿼리하십시오. 예:

SELECT * FROM information_schema.packages WHERE language = '<language>';
Copy

여기서 languagejava, python 또는 scala 입니다.

아래의 설명과 같이, PACKAGES 절에서 패키지를 참조하는 구문은 패키지의 언어에 따라 다릅니다.

  • Java

    다음 형식을 사용하여 패키지 이름과 버전 번호를 지정합니다.

    domain:package_name:version
    
    Copy

    최신 버전을 지정하려면 version 에 대해 latest 를 지정하십시오.

    예를 들어 Snowflake에 최신 Snowpark 라이브러리의 패키지를 포함하려면 다음을 사용하십시오.

    PACKAGES = ('com.snowflake:snowpark:latest')
    
    Copy

    Snowpark 라이브러리에서 패키지를 지정할 때 버전 1.3.0 이상을 지정해야 합니다.

  • Python

    Snowflake에는 Anaconda를 통해 구할 수 있는 패키지가 다수 포함되어 있습니다. 서드 파티 패키지 사용하기 섹션을 참조하십시오.

    다음 형식을 사용하여 패키지 이름과 버전 번호를 지정합니다.

    package_name[==version]
    
    Copy

    최신 버전을 지정하려면 버전 번호를 생략하십시오.

    예를 들어, (필요한 Snowpark 패키지의 최신 버전과 함께) spacy 패키지 버전 2.3.5를 포함하려면 다음을 사용하십시오.

    PACKAGES = ('snowflake-snowpark-python', 'spacy==2.3.5')
    
    Copy

    Snowpark 라이브러리에서 패키지를 지정할 때 버전 0.4.0 이상을 지정해야 합니다. Snowflake에서 사용 가능한 최신 버전을 사용하려면 버전 번호를 생략하십시오.

  • Scala

    다음 형식을 사용하여 패키지 이름과 버전 번호를 지정합니다.

    domain:package_name:version
    
    Copy

    최신 버전을 지정하려면 version 에 대해 latest 를 지정하십시오.

    예를 들어 Snowflake에 최신 Snowpark 라이브러리의 패키지를 포함하려면 다음을 사용하십시오.

    PACKAGES = ('com.snowflake:snowpark:latest')
    
    Copy

    Snowflake는 Scala 프로시저에서 Snowpark 버전 0.9.0 이상 사용을 지원합니다. 그러나 이러한 버전에는 제한 사항이 있습니다. 예를 들어 1.1.0 이전 버전은 프로시저에서 트랜잭션 사용을 지원하지 않습니다.

HANDLER = 'fully_qualified_method_name'
  • Python

    프로시저의 함수 또는 메서드의 이름을 사용합니다. 이는 코드가 인라인인지, 또는 스테이지에서 참조되는지에 따라 다를 수 있습니다.

    • 코드가 인라인이면 다음 예제에서처럼 함수 이름만 지정할 수 있습니다.

      WITH myproc AS PROCEDURE()
        ...
        HANDLER = 'run'
        AS
        $$
        def run(session):
          ...
        $$
      CALL myproc();
      
      Copy
    • 코드를 스테이지에서 가져올 때 정규화된 핸들러 함수 이름을 <모듈_이름>.<함수_이름> 으로 지정합니다.

      WITH myproc AS PROCEDURE()
        ...
        IMPORTS = ('@mystage/my_py_file.py')
        HANDLER = 'my_py_file.run'
      CALL myproc();
      
      Copy
  • Java 및 Scala

    프로시저에 대한 메서드 또는 함수의 정규화된 이름을 사용합니다. 이것은 일반적으로 다음과 같은 형식입니다.

    com.my_company.my_package.MyClass.myMethod
    
    Copy

    여기서,

    com.my_company.my_package
    
    Copy

    오브젝트 또는 클래스를 포함하는 패키지에 해당합니다.

    package com.my_company.my_package;
    
    Copy

선택적 매개 변수

모든 언어

CALLED ON NULL INPUT 또는 . RETURNS NULL ON NULL INPUT | STRICT

null 입력으로 호출 시 프로시저의 동작을 지정합니다. 입력값이 null일 때 항상 null을 반환하는 시스템 정의 함수와는 반대로, 프로시저는 null 입력을 처리하여 입력값이 null일 때도 null이 아닌 값을 반환할 수 있습니다.

  • CALLED ON NULL INPUT 은 항상 null 입력으로 프로시저를 호출합니다. 그와 같은 값을 적절히 처리하는 것은 프로시저에 달려 있습니다.

  • RETURNS NULL ON NULL INPUT (또는 동의어 STRICT)은 입력값이 null인 경우 프로시저를 호출하지 않으므로, 프로시저 내의 문이 실행되지 않습니다. 대신, 항상 null 값이 반환됩니다. 프로시저는 null이 아닌 입력값에 대해 여전히 null을 반환할 수도 있습니다.

기본값: CALLED ON NULL INPUT

INTO :snowflake_scripting_variable

지정된 Snowflake Scripting 변수 를 저장 프로시저의 반환 값으로 설정합니다.

Java, Python 또는 Scala

IMPORTS = ( 'stage_path_and_file_name_to_read' [, 'stage_path_and_file_name_to_read' ...] )

가져올 파일의 위치(스테이지), 경로, 이름입니다. 프로시저가 의존하는 모든 파일을 포함하도록 IMPORTS 절을 설정해야 합니다.

  • 인라인 프로시저를 작성하는 경우, 코드가 프로시저 또는 리소스 파일 외부에 정의된 클래스에 종속되지 않는 한 이 절을 생략할 수 있습니다.

  • Java 또는 Scala: 처리기가 컴파일된 코드가 되는 프로시저를 작성하는 경우 프로시저의 처리기가 포함된 JAR 파일의 경로도 포함해야 합니다.

  • Python: 프로시저의 코드가 스테이지에 있을 경우 코드가 있는 모듈 파일의 경로도 포함해야 합니다.

파일이 다른 하위 디렉터리나 다른 스테이지에 있더라도 IMPORTS 절의 각 파일은 고유한 이름을 가져야 합니다.

사용법 노트

일반 사용

  • 프로시저는 원자성이 아닙니다. 프로시저의 한 문이 실패할 경우 프로시저의 다른 문이 반드시 롤백되는 것은 아닙니다. 프로시저 및 트랜잭션에 대한 자세한 내용은 트랜잭션 관리 섹션을 참조하십시오.

  • 프로시저는 문자열(예: 성공/실패 표시기) 또는 숫자(예: 오류 코드)와 같은 단일 값만 반환할 수 있습니다. 더 광범위한 정보를 반환해야 하는 경우 구분 기호(예: 쉼표)로 구분된 값을 포함하는 VARCHAR나 VARIANT 와 같은 반정형 데이터 타입을 반환할 수 있습니다.

  • 메타데이터 관련:

    주의

    고객은 Snowflake 서비스를 사용할 때 개인 데이터(사용자 오브젝트 제외), 민감한 데이터, 수출 통제 대상 데이터 또는 기타 규제 데이터가 메타데이터로 입력되지 않도록 해야 합니다. 자세한 내용은 Snowflake의 메타데이터 필드 섹션을 참조하십시오.

구문

  • WITH 절이 SELECT 문과 함께 사용될 때와 마찬가지로, CALL과 함께 사용되는 WITH 절은 프로시저 정의 외에도 쉼표로 구분된 CTE의 지정을 지원합니다. 하지만 WITH 절로 생성된 테이블 형식 값을 CALL 절에 전달할 수 없습니다.

    하지만 WITH 절에 값이 할당된 단순 변수를 지정할 수 있습니다.

  • CALL 절은 구문의 마지막에 나와야 합니다.

권한

  • 이 명령으로 프로시저를 만들고 호출하는 데 CREATE PROCEDURE 스키마 권한이 있는 역할이 필요하지 않습니다.

  • 프로시저의 처리기 코드는 이 명령을 실행한 사람에게 할당된 역할에 대해 허용된 작업만 수행할 수 있습니다.

언어별

다음 예에서는 위치로 인자를 지정하는 프로시저를 만들고 호출합니다.

WITH copy_to_table AS PROCEDURE (fromTable STRING, toTable STRING, count INT)
  RETURNS STRING
  LANGUAGE SCALA
  RUNTIME_VERSION = '2.12'
  PACKAGES = ('com.snowflake:snowpark:latest')
  HANDLER = 'DataCopy.copyBetweenTables'
  AS
  $$
    object DataCopy
    {
      def copyBetweenTables(session: com.snowflake.snowpark.Session, fromTable: String, toTable: String, count: Int): String =
      {
        session.table(fromTable).limit(count).write.saveAsTable(toTable)
        return "Success"
      }
    }
  $$
  CALL copy_to_table('table_a', 'table_b', 5);
Copy

다음 예에서는 이름으로 인자를 지정하는 프로시저를 만들고 호출합니다.

WITH copy_to_table AS PROCEDURE (fromTable STRING, toTable STRING, count INT)
  RETURNS STRING
  LANGUAGE SCALA
  RUNTIME_VERSION = '2.12'
  PACKAGES = ('com.snowflake:snowpark:latest')
  HANDLER = 'DataCopy.copyBetweenTables'
  AS
  $$
    object DataCopy
    {
      def copyBetweenTables(session: com.snowflake.snowpark.Session, fromTable: String, toTable: String, count: Int): String =
      {
        session.table(fromTable).limit(count).write.saveAsTable(toTable)
        return "Success"
      }
      }
    }
  $$
  CALL copy_to_table(
    toTable => 'table_b',
    count => 5,
    fromTable => 'table_a');
Copy

추가적인 예는 다음 항목을 참조하십시오.

프로시저의 예는 저장 프로시저 작업하기 섹션을 참조하십시오.