CALL (com procedimento anônimo)

Cria e chama um procedimento anônimo que é como um procedimento armazenado, mas não é armazenado para uso posterior.

Com este comando, ambos criam um procedimento anônimo definido por parâmetros na cláusula WITH e chamam esse procedimento.

Você não precisa ter uma função com privilégios de esquema CREATE PROCEDURE para este comando.

O procedimento é executado com direitos do chamador, o que significa que o procedimento é executado com os privilégios do chamador, utiliza o contexto atual da sessão e tem acesso às variáveis e parâmetros da sessão do chamador.

Consulte também:

CREATE PROCEDURE , CALL.

Sintaxe

Java e 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

Para procedimentos Java e Scala com manipuladores em estágio, use a seguinte sintaxe:

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

Para procedimentos inline, use a seguinte sintaxe:

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

Para um procedimento em que o código está em um arquivo em um estágio, use a seguinte sintaxe:

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

Script Snowflake

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

Parâmetros obrigatórios

Todas as linguagens

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

Especifica o identificador (name) e quaisquer argumentos de entrada para o procedimento.

  • Para o identificador:

    • O identificador deve começar com um caractere alfabético e não pode conter espaços ou caracteres especiais a menos que toda a cadeia de caracteres do identificador esteja entre aspas duplas (por exemplo, “Meu objeto”). Os identificadores delimitados por aspas duplas também diferenciam letras maiúsculas de minúsculas. Consulte Requisitos para identificadores.

  • Para os argumentos de entrada:

RETURNS result_data_type [ [ NOT ] NULL ]

Especifica o tipo do resultado retornado pelo procedimento.

Use NOT NULL para especificar que o procedimento deve retornar somente valores diferentes de nulo; o padrão é NULL, o que significa que o procedimento pode retornar NULL.

  • Para result_data_type, usar o tipo de dados Snowflake que corresponda ao tipo da linguagem que você está usando.

    Nota

    Procedimentos que você escreve em Java ou Scala devem ter um valor de retorno. Em Python, quando um procedimento não retorna nenhum valor, é considerado como None retornando.

    Note que independentemente da linguagem do manipulador, a cláusula WITH para este comando deve incluir uma cláusula RETURNS que define um tipo de retorno, mesmo que o procedimento não retorne nada explicitamente.

  • Para RETURNS TABLE ( [ col_name col_data_type [ , ... ] ] ), se você conhecer os tipo de dados Snowflake das colunas na tabela retornada, especificar os nomes e tipos das colunas:

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

    Caso contrário (por exemplo, se você estiver determinando os tipos de coluna durante o tempo de execução), você pode omitir os nomes e tipos de coluna:

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

    Nota

    Atualmente, na cláusula RETURNS TABLE(...), você não pode especificar GEOGRAPHY como um tipo de coluna. Isso se aplica se você estiver criando um procedimento armazenado ou anônimo.

    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

    Se você tentar especificar GEOGRAPHY como um tipo de coluna, chamar o procedimento armazenado resultará no erro:

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

    Para contornar isso, você pode omitir os argumentos da coluna e digitar 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(...) é suportado somente quando o manipulador é escrito nas seguintes linguagens:

Por uma questão prática, fora de um bloco do Script Snowflake, o valor retornado não pode ser usado porque a chamada não pode fazer parte de uma expressão.

LANGUAGE language

Especifica a linguagem do código do manipulador do procedimento.

Atualmente, os valores suportados para language incluem:

AS procedure_definition

Define o código executado pelo procedimento. A definição pode consistir em qualquer código válido.

Observe o seguinte:

  • Para procedimentos para os quais o código não é em linha, omitir a cláusula AS. Isto inclui os procedimentos cujos manipuladores estão em um estágio.

    Em vez disso, use a cláusula IMPORTS para especificar a localização do arquivo contendo o código para o procedimento. Para obter mais detalhes, consulte:

  • Você deve usar delimitadores de literal de cadeias de caracteres (' ou $$) ao redor de procedure definition, inclusive no Snowflake Scripting.

  • Para procedimentos em JavaScript, se você estiver escrevendo uma cadeia de caracteres que contenha novas linhas, você pode usar backquotes (também chamadas de “backticks”) ao redor da cadeia de caracteres.

    O seguinte exemplo de um procedimento em JavaScript usa $$ e backticks porque o corpo do procedimento contém aspas simples e aspas duplas:

    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
  • O Snowflake não valida o código do manipulador. No entanto, o código do manipulador inválido resultará em erros quando você executar o comando.

Para obter mais detalhes sobre os procedimentos armazenados, consulte Como trabalhar com procedimentos armazenados.

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

Especifica o identificador (name) para o procedimento a ser chamado e quaisquer argumentos de entrada.

Você pode especificar os argumentos de entrada por nome (arg_name => arg) ou por posição (arg).

Observe o seguinte:

  • Você deve especificar todos os argumentos por nome ou por posição. Você não pode especificar alguns dos argumentos por nome e outros argumentos por posição.

    Ao especificar um argumento por nome, você não pode usar aspas duplas no nome do argumento.

  • Se duas funções ou dois procedimentos tiverem o mesmo nome, mas tipos de argumento diferentes, você poderá usar os nomes dos argumentos para especificar qual função ou procedimento executar, se os nomes dos argumentos forem diferentes. Consulte Sobrecarga de procedimentos e funções.

Java, Python ou Scala

RUNTIME_VERSION = 'language_runtime_version'

A versão de tempo de execução da linguagem a ser usada. Atualmente, as versões suportadas são:

  • Java: 11

  • Python

    • 3.8

    • 3.9

    • 3,10

    • 3,11

  • Scala: 2.12

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

Uma lista separada por vírgula dos nomes dos pacotes implantados no Snowflake que devem ser incluídos no ambiente de execução do código do manipulador. O pacote Snowpark é necessário para procedimentos, portanto deve ser sempre referenciado na cláusula PACKAGES. Para obter mais informações sobre o Snowpark, consulte API Snowpark.

Por padrão, o ambiente no qual o Snowflake executa procedimentos inclui um conjunto selecionado de pacotes para as linguagens suportadas. Ao referenciar estes pacotes na cláusula PACKAGES, não é necessário referenciar um arquivo contendo o pacote na cláusula IMPORTS porque o pacote já está disponível no Snowflake.

Para a lista de pacotes e versões suportados para uma determinada linguagem, consulte a exibição INFORMATION_SCHEMA.PACKAGES, especificando a linguagem. Por exemplo:

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

em que language é java, python ou scala.

A sintaxe para se referir a um pacote na cláusula PACKAGES varia de acordo com a linguagem do pacote, conforme descrito abaixo.

  • Java

    Especificar o nome do pacote e o número da versão usando o seguinte formulário:

    domain:package_name:version
    
    Copy

    Para especificar a última versão, especifique latest como version.

    Por exemplo, para incluir um pacote da biblioteca mais recente do Snowpark no Snowflake, usar o seguinte:

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

    Ao especificar um pacote da biblioteca do Snowpark, você deve especificar a versão 1.3.0 ou posterior.

  • Python

    O Snowflake inclui um grande número de pacotes disponíveis por meio do Anaconda; para obter mais informações, consulte Como usar pacotes de terceiros.

    Especificar o nome do pacote e o número da versão usando o seguinte formulário:

    package_name[==version]
    
    Copy

    Para especificar a última versão, omita o número da versão.

    Por exemplo, para incluir a versão do pacote spacy 2.3.5 (junto com a última versão do pacote Snowpark necessário), usar o seguinte:

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

    Ao especificar um pacote da biblioteca do Snowpark, você deve especificar a versão 0.4.0 ou posterior. Omitir o número da versão para usar a última versão disponível no Snowflake.

  • Scala

    Especificar o nome do pacote e o número da versão usando o seguinte formulário:

    domain:package_name:version
    
    Copy

    Para especificar a última versão, especifique latest como version.

    Por exemplo, para incluir um pacote da biblioteca mais recente do Snowpark no Snowflake, usar o seguinte:

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

    O Snowflake oferece suporte ao uso da versão do Snowpark 0.9.0 ou superior em um procedimento Scala. Observe, no entanto, que essas versões têm limitações. Por exemplo, as versões anteriores a 1.1.0 não oferecem suporte ao uso de transações em um procedimento.

HANDLER = 'fully_qualified_method_name'
  • Python

    Use o nome da função ou método do procedimento. Isso pode variar dependendo se o código está em linha ou referenciado em um estágio.

    • Quando o código está em linha, você pode especificar apenas o nome da função, como no exemplo a seguir:

      WITH myproc AS PROCEDURE()
        ...
        HANDLER = 'run'
        AS
        $$
        def run(session):
          ...
        $$
      CALL myproc();
      
      Copy
    • Quando o código é importado de um estágio, especifique o nome da função do manipulador totalmente qualificado como <nome_módulo>.<nome_função>.

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

    Use o nome totalmente qualificado do método ou função para o procedimento. Isso normalmente é feito da seguinte forma:

    com.my_company.my_package.MyClass.myMethod
    
    Copy

    onde:

    com.my_company.my_package
    
    Copy

    corresponde ao pacote que contém o objeto ou classe:

    package com.my_company.my_package;
    
    Copy

Parâmetros opcionais

Todas as linguagens

CALLED ON NULL INPUT ou . RETURNS NULL ON NULL INPUT | STRICT

Especifica o comportamento do procedimento quando chamado com entradas nulas. Ao contrário das funções definidas pelo sistema, que sempre retornam nulo quando qualquer entrada é nula, os procedimentos podem lidar com entradas nulas, retornando valores não nulos mesmo quando uma entrada é nula:

  • CALLED ON NULL INPUT sempre chamará o procedimento com entradas nulas. Cabe ao procedimento tratar tais valores de forma apropriada.

  • RETURNS NULL ON NULL INPUT (ou seu sinônimo STRICT) não chamará o procedimento se qualquer entrada for nula, por isso as instruções dentro do procedimento não serão executadas. Em vez disso, um valor nulo será sempre retornado. Note que o procedimento ainda pode retornar nulo para entradas não nulas.

Padrão: CALLED ON NULL INPUT

INTO :snowflake_scripting_variable

Define a variável do Script Snowflake especificada para o valor de retorno do procedimento armazenado.

Java, Python ou Scala

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

O local (estágio), caminho e nome do(s) arquivo(s) a ser(em) importado(s). Você deve definir a cláusula IMPORTS para incluir quaisquer arquivos dos quais seu procedimento dependa:

  • Se você estiver escrevendo um procedimento inline, você pode omitir esta cláusula, a menos que seu código dependa de classes definidas fora do procedimento ou dos arquivos de recursos.

  • Java ou Scala: se você estiver escrevendo um procedimento cujo manipulador será um código compilado, você também deve incluir um caminho para o arquivo JAR contendo o manipulador do procedimento.

  • Python: se o código de seu procedimento estiver em um estágio, você também deve incluir um caminho para o arquivo do módulo em que seu código está.

Cada arquivo na cláusula IMPORTS deve ter um nome único, mesmo que os arquivos estejam em subdiretórios diferentes ou em estágios diferentes.

Notas de uso

Uso geral

  • Procedimentos não são atômicos; se uma instrução em um procedimento falhar, as outras instruções no procedimento não são necessariamente revertidas. Para obter mais informações sobre procedimentos e transações, consulte Gerenciamento de transações.

  • Um procedimento pode retornar somente um único valor, como uma cadeia de caracteres (por exemplo, um indicador de sucesso/falha) ou um número (por exemplo, um código de erro). Se você precisar retornar informações mais extensas, você pode retornar um VARCHAR que contenha valores separados por um delimitador (como uma vírgula), ou um tipo de dados semiestruturados, como o VARIANT.

  • Em relação aos metadados:

    Atenção

    Os clientes devem garantir que nenhum dado pessoal (exceto para um objeto do usuário), dados sensíveis, dados controlados por exportação ou outros dados regulamentados sejam inseridos como metadados ao usar o serviço Snowflake. Para obter mais informações, consulte Campos de metadados no Snowflake.

Sintaxe

  • Similar a quando uma cláusula WITH é usada com uma instrução SELECT, uma cláusula WITH usada com CALL oferece suporte à especificação de múltiplos CTEs separados por vírgulas, além da definição do procedimento. No entanto, não é possível passar os valores tabulares produzidos por uma cláusula WITH para a cláusula CALL.

    É possível, entretanto, especificar uma variável simples cujo valor é atribuído na cláusula WITH.

  • A cláusula CALL deve ocorrer por último na sintaxe.

Privilégios

  • Criar e chamar um procedimento com este comando não requer uma função com privilégios de esquema CREATE PROCEDURE.

  • O código do manipulador do procedimento será capaz de executar somente as ações permitidas para a função atribuída à pessoa que executou este comando.

Específico da linguagem

Exemplos

O exemplo a seguir cria e chama um procedimento, especificando os argumentos por posição:

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

O exemplo a seguir cria e chama um procedimento, especificando os argumentos por nome:

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

Para exemplos adicionais, consulte os seguintes tópicos:

Para exemplos de procedimentos, consulte Como trabalhar com procedimentos armazenados.