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:
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> , ... ] )
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> , ... ] )
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.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:
Para
arg_name
, especificar o nome do argumento de entrada.Para
arg_data_type
, usar o tipo de dados Snowflake que corresponda à linguagem do manipulador que você está usando.Para os procedimentos em Java, consulte Mapeamentos de tipos de dados SQL-Java.
Para procedimentos em JavaScript, consulte Mapeamentos de tipos de dados SQL e JavaScript.
Para os procedimentos em Python, consulte Mapeamentos de tipos de dados SQL-Python.
Para os procedimentos em Scala, consulte Mapeamentos de tipos de dados SQL-Scala.
Nota
Para procedimentos que você escreve em Java, Python ou Scala (que usam APIs Snowpark), omita o argumento para o objeto Snowpark
Session
.O argumento
Session
não é um parâmetro formal que você especifica. Quando você executa este comando, o Snowflake cria automaticamente um objetoSession
e o passa para a função do manipulador para seu 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.
Para
result_data_type
, usar o tipo de dados Snowflake que corresponda ao tipo da linguagem que você está usando.Para os procedimentos em Java, consulte Mapeamentos de tipos de dados SQL-Java.
Para procedimentos em JavaScript, consulte Mapeamentos de tipos de dados SQL e JavaScript.
Para os procedimentos em Python, consulte Mapeamentos de tipos de dados SQL-Python.
Para os procedimentos em Scala, consulte Mapeamentos de tipos de dados SQL-Scala.
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) ...
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 ()
Nota
Atualmente, na cláusula
RETURNS TABLE(...)
emCREATE 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) ...
Se você fizer isso, chamar o procedimento armazenado resultará no erro:
CALL test_return_geography_table_1();
Stored procedure execution error: data type of returned table does not match expected returned table type
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() ...
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:JAVA
(para Java)JAVASCRIPT
(para JavaScript)PYTHON
(para Python)SCALA
(para Scala)
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 deprocedure 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();
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>';em que
language
éjava
,python
ouscala
.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:versionPara especificar a última versão, especifique
latest
comoversion
.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:versionPara especificar a última versão, especifique
latest
comoversion
.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.myMethodonde:
com.my_company.my_packagecorresponde 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ônimoSTRICT
) 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¶
O manipulador de um procedimento criado com este comando não pode ser escrito em Script Snowflake.
Para procedimentos em Java, consulte as limitações conhecidas.
Para procedimentos em Python, consulte as limitações conhecidas.
Para os procedimentos em Scala, consulte as limitações conhecidas.
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 em Java, consulte Como escrever procedimentos armazenados em Java.
Para exemplos de procedimentos em Python, consulte Como escrever procedimentos armazenados em Python.
Para exemplos de procedimentos em Scala, consulte Como escrever procedimentos armazenados em Scala.
Para exemplos de procedimentos, consulte Como trabalhar com procedimentos armazenados.