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

Para procedimentos pré-compilados em Scala e Java, use a seguinte sintaxe:

WITH <name> AS PROCEDURE ([ <arg_name> <arg_data_type> ]) [ , ... ] )
  RETURNS <result_data_type> [ [ NOT ] NULL ]
  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> , ... ] )

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

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

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

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.

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.

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 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>';

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
    

    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')
    

    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]
    

    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')
    

    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
    

    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')
    

    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();
      
    • 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();
      
  • 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
    

    onde:

    com.my_company.my_package
    

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

    package com.my_company.my_package;
    

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 pré-compilado, você também deve incluir um caminho para o arquivo JAR contendo a definição 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);

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