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> , ... ] )
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> , ... ] )
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> , ... ] )
Copy

Python

Para procedimentos inline, use a seguinte sintaxe:

WITH <name> AS PROCEDURE ( [ <arg_name> <arg_data_type> ] [ , ... ] )
  RETURNS <result_data_type> [ [ NOT ] NULL ]
  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> , ... ] )
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 ]
  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 } } ]
  [ , <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] ) ... ]
  [ , <cte_nameN> [ ( <cte_column_list> ) ] AS ( SELECT ...  ) ]
CALL <name> ( [ <arg> , ... ] )
Copy

Parâmetros obrigatórios

Todos os idiomas

name ( [ 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:

    CREATE OR REPLACE PROCEDURE get_top_sales()
    RETURNS TABLE (sales_date DATE, quantity NUMBER)
    ...
    
    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:

    CREATE OR REPLACE PROCEDURE get_top_sales()
    RETURNS TABLE ()
    
    Copy

    Nota

    Atualmente, na cláusula RETURNS TABLE(...) em CREATE PROCEDURE, você não pode especificar GEOGRAPHY como um tipo de coluna.

    CREATE OR REPLACE PROCEDURE test_return_geography_table_1()
    RETURNS TABLE(g GEOGRAPHY)
    ...
    
    Copy

    Se você fizer isso, chamar o procedimento armazenado resultará no erro:

    CALL test_return_geography_table_1();
    
    Copy
    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

    RETURNS TABLE(...) é suportado somente quando o manipulador é escrito nas seguintes linguagens:

Por uma questão prática, 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.

  • 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.

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

  • 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

Todos os idiomas

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

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

with copy_to_table as procedure (fromTable string, toTable string, count int)
  returns string
  language scala
  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

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