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_name> => ] <arg> , ... ] )
[ INTO :<snowflake_scripting_variable> ]
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> ]
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> ]
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> ]
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> ]
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> ]
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:
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.
Para Script Snowflake, um tipo de dados SQL.
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.
Para Script Snowflake, um tipo de dados SQL.
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();
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();
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) ...
WITH test_return_geography_table_1() AS PROCEDURE RETURNS TABLE(g GEOGRAPHY) ... CALL test_return_geography_table_1();
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
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() ...
WITH test_return_geography_table_1() AS PROCEDURE RETURNS TABLE() ... CALL test_return_geography_table_1();
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:JAVA
(para Java)JAVASCRIPT
(para JavaScript)PYTHON
(para Python)SCALA
(para Scala)SQL
(para Script Snowflake)
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
, 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();
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>';
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:version
Para 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:version
Para 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.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¶
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ô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
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¶
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¶
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);
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');
Para exemplos adicionais, consulte os seguintes tópicos:
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 obter exemplos de procedimentos armazenados do Snowflake Scripting, consulte Como escrever procedimentos armazenados no Script Snowflake.
Para exemplos de procedimentos, consulte Como trabalhar com procedimentos armazenados.