CREATE PROCEDURE¶
Cria um novo procedimento armazenado.
Um procedimento pode ser escrito em uma das seguintes linguagens:
Nota
Quando você quiser criar e chamar um procedimento que seja anônimo (em vez de armazenado), use CALL (com procedimento anônimo). Criar um procedimento anônimo não exige uma função com privilégios de esquema CREATE PROCEDURE.
Esse comando é compatível com as seguintes variantes:
CREATE OR ALTER PROCEDURE: cria um novo procedimento se ele não existir ou altera um procedimento existente.
- Consulte também:
ALTER PROCEDURE, DROP PROCEDURE , SHOW PROCEDURES , DESCRIBE PROCEDURE, CALL
Sintaxe¶
Manipulador de Java¶
Você pode criar um procedimento armazenado que inclui seu código de manipulador em linha, ou se refere a seu código de manipulador em um arquivo JAR. Para obter mais informações, consulte Como manter o código do manipulador em linha ou em um estágio.
Para exemplos de procedimentos armazenados em Java, consulte Como escrever manipuladores Java para procedimentos armazenados criados com SQL.
Para procedimentos armazenados inline, use a seguinte sintaxe:
CREATE [ OR REPLACE ] [ SECURE ] PROCEDURE <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
LANGUAGE JAVA
RUNTIME_VERSION = '<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>'
[ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
[ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
[ TARGET_PATH = '<stage_path_and_file_name_to_write>' ]
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ] -- Note: VOLATILE and IMMUTABLE are deprecated.
[ COMMENT = '<string_literal>' ]
[ EXECUTE AS { OWNER | CALLER | RESTRICTED CALLER } ]
AS '<procedure_definition>'
Para um procedimento armazenado que utiliza um manipulador pré-compilado, use a seguinte sintaxe.
CREATE [ OR REPLACE ] [ SECURE ] PROCEDURE <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
LANGUAGE JAVA
RUNTIME_VERSION = '<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>'
[ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
[ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ VOLATILE | IMMUTABLE ] -- Note: VOLATILE and IMMUTABLE are deprecated.
[ COMMENT = '<string_literal>' ]
[ EXECUTE AS { OWNER | CALLER | RESTRICTED CALLER } ]
Manipulador de JavaScript¶
Para exemplos de procedimentos armazenados JavaScript, consulte Como escrever procedimentos armazenados em JavaScript.
CREATE [ OR REPLACE ] [ SECURE ] PROCEDURE <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS <result_data_type> [ NOT NULL ]
LANGUAGE JAVASCRIPT
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ VOLATILE | IMMUTABLE ] -- Note: VOLATILE and IMMUTABLE are deprecated.
[ COMMENT = '<string_literal>' ]
[ EXECUTE AS { OWNER | CALLER | RESTRICTED CALLER } ]
AS '<procedure_definition>'
Importante
JavaScript diferencia maiúsculas e minúsculas, enquanto SQL não. Consulte Diferenciação entre maiúsculas e minúsculas em argumentos JavaScript para informações importantes sobre o uso de nomes de argumentos de procedimentos armazenados no código JavaScript.
Manipulador de Python¶
Para exemplos de procedimentos armazenados em Python, consulte Como escrever procedimentos armazenados com SQL e Python.
Para procedimentos armazenados inline, use a seguinte sintaxe:
CREATE [ OR REPLACE ] [ SECURE ] PROCEDURE <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
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>'
[ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
[ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ] -- Note: VOLATILE and IMMUTABLE are deprecated.
[ COMMENT = '<string_literal>' ]
[ EXECUTE AS { OWNER | CALLER | RESTRICTED CALLER }]
AS '<procedure_definition>'
Para um procedimento armazenado em que o código está em um arquivo em um estágio, use a seguinte sintaxe:
CREATE [ OR REPLACE ] PROCEDURE <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
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>'
[ EXTERNAL_ACCESS_INTEGRATIONS = ( <name_of_integration> [ , ... ] ) ]
[ SECRETS = ('<secret_variable_name>' = <secret_name> [ , ... ] ) ]
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ] -- Note: VOLATILE and IMMUTABLE are deprecated.
[ COMMENT = '<string_literal>' ]
[ EXECUTE AS { OWNER | CALLER | RESTRICTED CALLER } ]
Manipulador de Scala¶
Você pode criar um procedimento armazenado que inclui seu código de manipulador em linha, ou se refere a seu código de manipulador em um arquivo JAR. Para obter mais informações, consulte Como manter o código do manipulador em linha ou em um estágio.
Para exemplos de procedimentos armazenados em Scala, consulte Como escrever manipuladores Scala para procedimentos armazenados criados com SQL.
Para procedimentos armazenados inline, use a seguinte sintaxe:
CREATE [ OR REPLACE ] [ SECURE ] PROCEDURE <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
LANGUAGE SCALA
RUNTIME_VERSION = '<scala_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>'
[ TARGET_PATH = '<stage_path_and_file_name_to_write>' ]
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ] -- Note: VOLATILE and IMMUTABLE are deprecated.
[ COMMENT = '<string_literal>' ]
[ EXECUTE AS { OWNER | CALLER | RESTRICTED CALLER } ]
AS '<procedure_definition>'
Para um procedimento armazenado que utiliza um manipulador pré-compilado, use a seguinte sintaxe.
CREATE [ OR REPLACE ] [ SECURE ] PROCEDURE <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> [ [ NOT ] NULL ] | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
LANGUAGE SCALA
RUNTIME_VERSION = '<scala_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 } } ]
[ VOLATILE | IMMUTABLE ] -- Note: VOLATILE and IMMUTABLE are deprecated.
[ COMMENT = '<string_literal>' ]
[ EXECUTE AS { OWNER | CALLER | RESTRICTED CALLER } ]
Manipulador do Script Snowflake¶
Para obter exemplos de procedimentos armazenados do Snowflake Scripting, consulte Como escrever procedimentos armazenados no Script Snowflake.
CREATE [ OR REPLACE ] PROCEDURE <name> (
[ <arg_name> <arg_data_type> [ DEFAULT <default_value> ] ] [ , ... ] )
[ COPY GRANTS ]
RETURNS { <result_data_type> | TABLE ( [ <col_name> <col_data_type> [ , ... ] ] ) }
[ NOT NULL ]
LANGUAGE SQL
[ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
[ { VOLATILE | IMMUTABLE } ] -- Note: VOLATILE and IMMUTABLE are deprecated.
[ COMMENT = '<string_literal>' ]
[ EXECUTE AS { OWNER | CALLER | RESTRICTED CALLER } ]
AS <procedure_definition>
Nota
Se você estiver criando um procedimento do Script Snowflake em SnowSQL ou Classic Console, você deve usar delimitadores de literal de cadeia de caracteres ('
ou $$
) ao redor de procedure definition
. Consulte Uso do Script Snowflake em SnowSQL, Classic Console e conector Python.
Sintaxe da variante¶
CREATE OR ALTER PROCEDURE¶
Cria um novo procedimento, se ele ainda não existir, ou transforma um procedimento existente no procedimento definido na instrução. Uma instrução CREATE OR ALTER PROCEDURE segue as regras de sintaxe de uma instrução CREATE PROCEDURE e tem as mesmas limitações de uma instrução ALTER PROCEDURE.
São aceitas alterações nos seguintes itens:
LOG_LEVEL, TRACE_LEVEL, COMMENT, SECURE
SECRETS e EXTERNAL_ACCESS_INTEGRATIONS para processos armazenados em Python, Scala e Java
Privilégios de execução (EXECUTE AS CALLER ou EXECUTE AS OWNER)
Para obter mais informações, consulte Notas de uso de CREATE OR ALTER PROCEDURE.
CREATE [ OR ALTER ] PROCEDURE ...
Parâmetros obrigatórios¶
Todos os idiomas¶
name ( [ arg_name arg_data_type [ DEFAULT default_value ] ] [ , ... ] )
Especifica o identificador (
name
), quaisquer argumentos de entrada e os valores padrão para quaisquer argumentos opcionais do procedimento armazenado.Para o identificador:
O identificador não precisa ser único para o esquema no qual o procedimento é criado porque os procedimentos armazenados são identificados e resolvidos pela combinação dos tipos de nome e argumento.
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 que você está usando.Para procedimentos armazenados em Java, consulte Mapeamentos de tipos de dados SQL-Java.
Para procedimentos armazenados em JavaScript, consulte Mapeamentos de tipos de dados SQL e JavaScript.
Para procedimentos armazenados em Python, consulte Mapeamentos de tipos de dados SQL-Python.
Para procedimentos armazenados em Scala, consulte Mapeamentos de tipos de dados SQL-Scala.
Para Script Snowflake, um tipo de dados SQL.
Nota
Para procedimentos armazenados 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 em CREATE PROCEDURE ou CALL. Quando você chama seu procedimento armazenado, o Snowflake cria automaticamente um objetoSession
e o passa para a função do manipulador para seu procedimento armazenado.Para indicar que um argumento é opcional, use
DEFAULT default_value
para especificar o valor padrão do argumento. Para o valor padrão, você pode usar um literal ou uma expressão.Se você especificar quaisquer argumentos opcionais, deverá colocá-los após os argumentos obrigatórios.
Se um procedimento tiver argumentos opcionais, você não poderá definir procedimentos adicionais com o mesmo nome e assinaturas diferentes.
Para obter mais detalhes, consulte Especificação de argumentos opcionais.
RETURNS result_data_type [ NOT NULL ]
Especifica o tipo do resultado retornado pelo procedimento armazenado.
Para
result_data_type
, usar o tipo de dados Snowflake que corresponda ao tipo da linguagem que você está usando.Para procedimentos armazenados em Java, consulte Mapeamentos de tipos de dados SQL-Java.
Para procedimentos armazenados em JavaScript, consulte Mapeamentos de tipos de dados SQL e JavaScript.
Para procedimentos armazenados em Python, consulte Mapeamentos de tipos de dados SQL-Python.
Para procedimentos armazenados em Scala, consulte Mapeamentos de tipos de dados SQL-Scala.
Para Script Snowflake, um tipo de dados SQL.
Nota
Os procedimentos armazenados que você escreve no Snowpark (Java ou Scala) devem ter um valor de retorno. No Snowpark (Python), quando um procedimento armazenado não retorna nenhum valor, é considerado como
None
retornando. Note que toda instrução CREATE PROCEDURE 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(...)
, 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 este problema, 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 o idioma do código de procedimento armazenado. Note que isso é opcional para procedimentos armazenados escritos com Script Snowflake.
Atualmente, os valores suportados para
language
incluem:JAVA
(para Java)JAVASCRIPT
(para JavaScript)PYTHON
(para Python)SCALA
(para Scala)SQL
(para Script Snowflake)
Padrão:
SQL
.AS procedure_definition
Define o código executado pelo procedimento armazenado. A definição pode consistir em qualquer código válido.
Observe o seguinte:
Para procedimentos armazenados para os quais o código não é em linha, omitir a cláusula AS. Isto inclui procedimentos armazenados com manipuladores em estágio.
Em vez disso, use a cláusula IMPORTS para especificar a localização do arquivo contendo o código para o procedimento armazenado. Para obter mais detalhes, consulte:
Como escrever manipuladores Java para procedimentos armazenados criados com SQL
Como escrever manipuladores Scala para procedimentos armazenados criados com SQL
Para obter mais informações sobre manipuladores em linha e em estágio, consulte Como manter o código do manipulador em linha ou em um estágio.
Você deve usar delimitadores de literal de cadeias de caracteres (
'
ou$$
) ao redor deprocedure definition
se:Você está usando uma linguagem que não é Script Snowflake.
Você está criando um procedimento de Script Snowflake em SnowSQL ou Classic Console. Consulte Uso do Script Snowflake em SnowSQL, Classic Console e conector Python.
Para procedimentos armazenados 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 armazenado em JavaScript usa
$$
e backticks porque o corpo do procedimento armazenado contém aspas simples e aspas duplas:CREATE OR REPLACE TABLE table1 ("column 1" VARCHAR);
CREATE or replace PROCEDURE proc3() RETURNS VARCHAR LANGUAGE javascript AS $$ var rs = snowflake.execute( { sqlText: `INSERT INTO table1 ("column 1") SELECT 'value 1' AS "column 1" ;` } ); return 'Done.'; $$;
O Snowflake não valida completamente o código quando você executa o comando CREATE PROCEDURE.
Por exemplo, para procedimentos armazenados no Snowpark (Scala), o número e os tipos de argumentos de entrada são validados, mas o corpo da função não é validado. Se o número ou tipos não forem correspondentes (por exemplo, se o tipo de dados do Snowflake NUMBER for usado quando o argumento for um tipo não numérico), a execução do comando CREATE PROCEDURE causa um erro.
Se o código não for válido, o comando CREATE PROCEDURE terá sucesso, e os erros serão retornados quando o procedimento armazenado for chamado.
Para obter mais detalhes sobre os procedimentos armazenados, consulte Como trabalhar com procedimentos armazenados.
Java¶
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:
11
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 armazenados, portanto deve ser sempre referenciado na cláusula PACKAGES. Para obter mais informações sobre o Snowpark, consulte Snowpark API.
Por padrão, o ambiente no qual o Snowflake executa procedimentos armazenados 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. Você também pode especificar a versão do pacote.
Para a lista de pacotes e versões suportados para Java, consulte a exibição INFORMATION_SCHEMA.PACKAGES para linhas, especificando a linguagem. Por exemplo:
SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'java';
Para 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.
HANDLER = 'fully_qualified_method_name'
Use o nome totalmente qualificado do método ou função para o procedimento armazenado. 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;
Python¶
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:
3.9
3,10
3,11
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 armazenados, portanto deve ser sempre referenciado na cláusula PACKAGES. Para obter mais informações sobre o Snowpark, consulte Snowpark API.
Por padrão, o ambiente no qual o Snowflake executa procedimentos armazenados 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. Você também pode especificar a versão do pacote.
Para a lista de pacotes e versões suportados para Python, consulte a exibição INFORMATION_SCHEMA.PACKAGES para linhas, especificando a linguagem. Por exemplo:
SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = '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.
Para 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.
HANDLER = 'fully_qualified_method_name'
Use o nome da função ou método do procedimento armazenado. 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:
CREATE OR REPLACE PROCEDURE MYPROC(from_table STRING, to_table STRING, count INT) ... HANDLER = 'run' AS $$ def run(session, from_table, to_table, count): ... $$;
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>
.CREATE OR REPLACE PROCEDURE MYPROC(from_table STRING, to_table STRING, count INT) ... IMPORTS = ('@mystage/my_py_file.py') HANDLER = 'my_py_file.run';
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:
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 armazenados, portanto deve ser sempre referenciado na cláusula PACKAGES. Para obter mais informações sobre o Snowpark, consulte Snowpark API.
Por padrão, o ambiente no qual o Snowflake executa procedimentos armazenados 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. Você também pode especificar a versão do pacote.
Para a lista de pacotes e versões suportados para Scala, consulte a exibição INFORMATION_SCHEMA.PACKAGES para linhas, especificando a linguagem. Por exemplo:
SELECT * FROM INFORMATION_SCHEMA.PACKAGES WHERE LANGUAGE = 'scala';
Para 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 armazenado 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 armazenado.
HANDLER = 'fully_qualified_method_name'
Use o nome totalmente qualificado do método ou função para o procedimento armazenado. 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¶
SECURE
Especifica que o procedimento é seguro. Para obter mais informações sobre procedimentos seguros, consulte Proteção de informações sensíveis com UDFs e procedimentos armazenados seguros.
[ [ NOT ] NULL ]
Especifica se o procedimento armazenado pode retornar valores NULL ou deve retornar somente valores NON-NULL.
O padrão é NULL (ou seja, o procedimento armazenado pode retornar NULL).
CALLED ON NULL INPUT
ou .{ RETURNS NULL ON NULL INPUT | STRICT }
Especifica o comportamento do procedimento armazenado quando chamado com entradas nulas. Ao contrário das funções definidas pelo sistema, que sempre retornam nulo quando qualquer entrada é nula, os procedimentos armazenados podem lidar com entradas nulas, retornando valores não nulos mesmo quando uma entrada é nula:
CALLED ON NULL INPUT
sempre chamará o procedimento armazenado 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 armazenado se qualquer entrada for nula, por isso as instruções dentro do procedimento armazenado 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
VOLATILE | IMMUTABLE
Obsoleto
Atenção
Estas palavras-chave são obsoletas para procedimentos armazenados. Estas palavras-chave não se destinam à aplicação em procedimentos armazenados. Em um lançamento futuro, estas palavras-chave serão removidas da documentação.
COMMENT = 'string_literal'
Especifica um comentário para o procedimento armazenado, que é exibido na coluna DESCRIPTION na saída SHOW PROCEDURES.
Padrão:
stored procedure
EXECUTE AS OWNER
ou .EXECUTE AS CALLER
ou .EXECUTE AS RESTRICTED CALLER
Especifica se o procedimento armazenado é executado com os privilégios do proprietário (um procedimento armazenado “direitos do proprietário”) ou com os privilégios do chamador (um procedimento armazenado “direitos do chamador”):
Se você executar CREATE PROCEDURE … EXECUTE AS OWNER, então o procedimento será executado como um procedimento de direitos do proprietário.
Se você executar a instrução CREATE PROCEDURE … EXECUTE AS CALLER, então, no futuro, o procedimento será executado como um procedimento de direitos do chamador.
Se você executar a instrução CREATE PROCEDURE … EXECUTE AS RESTRICTED CALLER no futuro, o procedimento será executado como um procedimento com direitos do chamador, mas talvez não possa ser executado com todos os privilégios do chamador. Para obter mais informações, consulte Direitos restritos do chamador.
Se
EXECUTE AS ...
não for especificado, o procedimento será executado como um procedimento armazenado de direitos do proprietário. Os procedimentos armazenados de direitos do proprietário têm menos acesso ao ambiente do chamador (por exemplo, as variáveis de sessão da pessoa que faz a chamada), e o Snowflake tem como padrão este nível mais alto de privacidade e segurança.Para obter mais informações, consulte Procedimentos armazenados com direitos do chamador e direitos do proprietário.
Padrão:
OWNER
COPY GRANTS
Especifica para manter os privilégios de acesso do procedimento original quando um novo procedimento é criado usando CREATE OR REPLACE PROCEDURE.
O parâmetro copia todos os privilégios, exceto OWNERSHIP os do procedimento existente para o novo procedimento. O novo procedimento não herdará as concessões futuras definidas para o tipo de objeto no esquema. Por padrão, a função que executa a instrução CREATE PROCEDURE é a proprietária do novo procedimento.
Nota:
A saída SHOW GRANTS para o procedimento de substituição relaciona o cessionário para os privilégios copiados como a função que executou a instruçãoCREATE PROCEDURE, com o carimbo de data/hora atual quando a instrução foi executada.
A operação de cópia de concessões ocorre atomicamente no comando CREATE PROCEDURE (ou seja, dentro da mesma transação).
Java¶
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 armazenado dependa:
Se você estiver escrevendo um procedimento armazenado inline, você pode omitir esta cláusula, a menos que seu código dependa de classes definidas fora do procedimento armazenado ou dos arquivos de recursos.
Se você estiver escrevendo um procedimento armazenado com um manipulador em estágio, você também deve incluir um caminho para o arquivo JAR contendo o código do manipulador do procedimento armazenado.
A definição IMPORTS não pode fazer referência a variáveis de argumentos que são passados para o procedimento armazenado.
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.
TARGET_PATH = stage_path_and_file_name_to_write
Especifica o local no qual o Snowflake deve gravar o arquivo JAR com o resultado da compilação do código-fonte do manipulador especificado em
procedure_definition
.Se esta cláusula for inclusa, o Snowflake gravará o arquivo JAR resultante no local do estágio especificado pelo valor da cláusula. Se esta cláusula for omitida, o Snowflake recompila o código fonte sempre que o código é necessário. Nesse caso, o arquivo JAR não é armazenado permanentemente e o usuário não precisa limpar o arquivo JAR.
O Snowflake retorna um erro se o TARGET_PATH corresponder a um arquivo existente; você não pode usar TARGET_PATH para substituir um arquivo existente.
Se você especificar as cláusulas IMPORTS e TARGET_PATH, o nome do arquivo na cláusula TARGET_PATH deve ser diferente de cada nome de arquivo na cláusula IMPORTS, mesmo que os arquivos estejam em subdiretórios diferentes ou em estágios diferentes.
O arquivo JAR gerado permanece até que você o exclua explicitamente, mesmo que abandone o procedimento. Ao abandonar o procedimento, você deve remover separadamente o arquivo JAR porque o JAR não é mais necessário para oferecer suporte ao procedimento.
Por exemplo, o seguinte exemplo TARGET_PATH resultaria em um arquivo
myhandler.jar
gerado e copiado para o estágiohandlers
.TARGET_PATH = '@handlers/myhandler.jar'
Ao executar esse procedimento para removê-lo, também precisará remover o arquivo manipulador JAR, por exemplo, executando o comando REMOVE.
REMOVE @handlers/myhandler.jar;
EXTERNAL_ACCESS_INTEGRATIONS = ( integration_name [ , ... ] )
Os nomes das integrações de acesso externo necessárias para que este código do manipulador do procedimento acesse redes externas.
Uma integração de acesso externo especifica regras de rede e segredos que especificam locais externos e credenciais (se houver) permitidos para uso pelo código do manipulador ao fazer solicitações de uma rede externa, como uma rede externa REST API.
SECRETS = ( 'secret_variable_name' = secret_name [ , ... ] )
Atribui os nomes dos segredos às variáveis para que você possa usar as variáveis para fazer referência aos segredos ao recuperar informações dos segredos no código do manipulador.
Os segredos que você especificar aqui devem ser permitidos pela integração de acesso externo especificada como um valor deste comando CREATE PROCEDURE do parâmetro EXTERNAL_ACCESS_INTEGRATIONS
O valor deste parâmetro é uma lista separada por vírgulas de expressões de atribuição com as seguintes partes:
secret_name
como o nome do segredo permitido.Você receberá um erro se especificar um valor SECRETS cujo segredo também não esteja incluído em uma integração especificada pelo parâmetro EXTERNAL_ACCESS_INTEGRATIONS.
'secret_variable_name'
como a variável que será usada no código do manipulador ao recuperar informações do segredo.
Para obter mais informações, incluindo um exemplo, consulte Uso da integração de acesso externo em uma função ou procedimento.
Python¶
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 armazenado dependa:
Se você estiver escrevendo um procedimento armazenado inline, você pode omitir esta cláusula, a menos que seu código dependa de classes definidas fora do procedimento armazenado ou dos arquivos de recursos.
Se o código de seu procedimento armazenado estiver em um estágio, você também deve incluir um caminho para o arquivo do módulo em que seu código está.
A definição IMPORTS não pode fazer referência a variáveis de argumentos que são passados para o procedimento armazenado.
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.
EXTERNAL_ACCESS_INTEGRATIONS = ( integration_name [ , ... ] )
Os nomes das integrações de acesso externo necessárias para que este código do manipulador do procedimento acesse redes externas.
Uma integração de acesso externo especifica regras de rede e segredos que especificam locais externos e credenciais (se houver) permitidos para uso pelo código do manipulador ao fazer solicitações de uma rede externa, como uma rede externa REST API.
SECRETS = ( 'secret_variable_name' = secret_name [ , ... ] )
Atribui os nomes dos segredos às variáveis para que você possa usar as variáveis para fazer referência aos segredos ao recuperar informações dos segredos no código do manipulador.
Os segredos que você especificar aqui devem ser permitidos pela integração de acesso externo especificada como um valor deste comando CREATE PROCEDURE do parâmetro EXTERNAL_ACCESS_INTEGRATIONS
O valor deste parâmetro é uma lista separada por vírgulas de expressões de atribuição com as seguintes partes:
secret_name
como o nome do segredo permitido.Você receberá um erro se especificar um valor SECRETS cujo segredo também não esteja incluído em uma integração especificada pelo parâmetro EXTERNAL_ACCESS_INTEGRATIONS.
'secret_variable_name'
como a variável que será usada no código do manipulador ao recuperar informações do segredo.
Para obter mais informações, incluindo um exemplo, consulte Uso da integração de acesso externo em uma função ou procedimento.
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 armazenado dependa:
Se você estiver escrevendo um procedimento armazenado inline, você pode omitir esta cláusula, a menos que seu código dependa de classes definidas fora do procedimento armazenado ou dos arquivos de recursos.
Se você estiver escrevendo um procedimento armazenado com um manipulador em estágio, você também deve incluir um caminho para o arquivo JAR contendo o código do manipulador do procedimento armazenado.
A definição IMPORTS não pode fazer referência a variáveis de argumentos que são passados para o procedimento armazenado.
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.
TARGET_PATH = stage_path_and_file_name_to_write
Especifica o local no qual o Snowflake deve gravar o arquivo JAR com o resultado da compilação do código-fonte do manipulador especificado em
procedure_definition
.Se esta cláusula for inclusa, o Snowflake gravará o arquivo JAR resultante no local do estágio especificado pelo valor da cláusula. Se esta cláusula for omitida, o Snowflake recompila o código fonte sempre que o código é necessário. Nesse caso, o arquivo JAR não é armazenado permanentemente e o usuário não precisa limpar o arquivo JAR.
O Snowflake retorna um erro se o TARGET_PATH corresponder a um arquivo existente; você não pode usar TARGET_PATH para substituir um arquivo existente.
Se você especificar as cláusulas IMPORTS e TARGET_PATH, o nome do arquivo na cláusula TARGET_PATH deve ser diferente de cada nome de arquivo na cláusula IMPORTS, mesmo que os arquivos estejam em subdiretórios diferentes ou em estágios diferentes.
O arquivo JAR gerado permanece até que você o exclua explicitamente, mesmo que abandone o procedimento. Ao abandonar o procedimento, você deve remover separadamente o arquivo JAR porque o JAR não é mais necessário para oferecer suporte ao procedimento.
Por exemplo, o seguinte exemplo TARGET_PATH resultaria em um arquivo
myhandler.jar
gerado e copiado para o estágiohandlers
.TARGET_PATH = '@handlers/myhandler.jar'
Ao executar esse procedimento para removê-lo, também precisará remover o arquivo manipulador JAR, por exemplo, executando o comando REMOVE.
REMOVE @handlers/myhandler.jar;
Requisitos de controle de acesso¶
A função usada para executar essa operação deve ter, no mínimo, os seguintes privilégios:
Privilégio |
Objeto |
Notas |
---|---|---|
CREATE PROCEDURE |
Esquema |
|
USAGE |
Procedimento |
Concedendo o privilégio USAGE no procedimento recém-criado a uma função permite que os usuários com essa função chamem o procedimento em outro lugar no Snowflake. |
USAGE |
Integração de acesso externo |
Necessário nas integrações, se houver, especificadas ao criar o procedimento. Para obter mais informações, consulte CREATE EXTERNAL ACCESS INTEGRATION. |
READ |
Segredo |
Necessário em segredos, se houver, especificados ao criar o procedimento. Para obter mais informações, consulte Criação de um segredo para representar credenciais e Uso da integração de acesso externo em uma função ou procedimento. |
USAGE |
Esquema |
Necessário nos esquemas que contêm segredos, se houver, especificados ao criar o procedimento. Para obter mais informações, consulte Criação de um segredo para representar credenciais e Uso da integração de acesso externo em uma função ou procedimento. |
O privilégio USAGE no banco de dados e no esquema pai é necessário para executar operações em qualquer objeto de um esquema.
Para instruções sobre como criar uma função personalizada com um conjunto específico de privilégios, consulte Criação de funções personalizadas.
Para informações gerais sobre concessões de funções e privilégios para executar ações de SQL em objetos protegíveis, consulte Visão geral do controle de acesso.
Notas de uso geral¶
Instruções CREATE OR REPLACE <object> são atômicas. Ou seja, quando um objeto é substituído, o objeto antigo é excluído e o novo objeto é criado em uma única transação.
Para obter notas de uso adicionais, consulte o seguinte.
Todas as linguagens de manipuladores¶
Os procedimentos armazenados oferecem suporte à sobrecarga. Dois procedimentos podem ter o mesmo nome se eles tiverem um número diferente de parâmetros ou tipos de dados diferentes para seus parâmetros.
Os procedimentos armazenados não são atômicos; se uma instrução em um procedimento armazenado falhar, as outras instruções no procedimento armazenado não são necessariamente revertidas. Para obter mais informações sobre procedimentos armazenados e transações, consulte Gerenciamento de transações.
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.
Dica
Se sua organização utiliza uma mistura de procedimentos armazenados de direitos do chamador e de direitos de proprietário, você pode querer usar uma convenção de nomes para seus procedimentos armazenados para indicar se um procedimento armazenado é um procedimento armazenado de direitos do chamador ou um de direitos do proprietário.
Java¶
Consulte as limitações conhecidas.
Javascript¶
Um procedimento armazenado em JavaScript 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.
Python¶
Consulte as limitações conhecidas.
Scala¶
Consulte as limitações conhecidas.
Notas de uso de CREATE OR ALTER PROCEDURE¶
Todas as limitações do comando ALTER PROCEDURE se aplicam.
Todas as limitações descritas em Notas de uso de CREATE OR ALTER FUNCTION se aplicam.
Exemplos¶
Isso cria um procedimento armazenado trivial que retorna um valor embutido em código. Isso não é realista, mas mostra a sintaxe básica SQL com um código JavaScript mínimo:
CREATE OR REPLACE PROCEDURE sp_pi()
RETURNS FLOAT NOT NULL
LANGUAGE JAVASCRIPT
AS
$$
return 3.1415926;
$$
;
Isso mostra um exemplo mais realista que inclui uma chamada para API JavaScript. Uma versão mais extensa deste procedimento poderia permitir que um usuário inserisse dados em uma tabela para a qual não tinha privilégios para inserir diretamente. As instruções JavaScript poderiam verificar os parâmetros de entrada e executar SQL INSERT
somente se certos requisitos fossem atendidos.
CREATE OR REPLACE PROCEDURE stproc1(FLOAT_PARAM1 FLOAT)
RETURNS STRING
LANGUAGE JAVASCRIPT
STRICT
EXECUTE AS OWNER
AS
$$
var sql_command =
"INSERT INTO stproc_test_table1 (num_col1) VALUES (" + FLOAT_PARAM1 + ")";
try {
snowflake.execute (
{sqlText: sql_command}
);
return "Succeeded."; // Return a success/error indicator.
}
catch (err) {
return "Failed: " + err; // Return a success/error indicator.
}
$$
;
Para obter mais exemplos, consulte Como trabalhar com procedimentos armazenados.
Manipulador em linha¶
O código no exemplo a seguir cria um procedimento chamado my_proc
com uma função de manipulador Python inline run
. Através da cláusula PACKAGES, o código faz referência à biblioteca Snowpark incluída para Python, cujo Session
é necessário quando Python é a linguagem do manipulador de procedimentos.
CREATE OR REPLACE PROCEDURE my_proc(from_table STRING, to_table STRING, count INT)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'run'
AS
$$
def run(session, from_table, to_table, count):
session.table(from_table).limit(count).write.save_as_table(to_table)
return "SUCCESS"
$$;
Manipulador em estágio¶
O código no exemplo a seguir cria um procedimento chamado my_proc
com um método do manipulador de Java em estágio MyClass.myMethod
. Através da cláusula PACKAGES, o código faz referência à biblioteca Snowpark incluída para Java, cujo Session
é necessário quando Java é a linguagem do manipulador de procedimentos. Com a cláusula IMPORTS, o código faz referência ao arquivo preparado JAR contendo o código do manipulador.
CREATE OR REPLACE PROCEDURE my_proc(fromTable STRING, toTable STRING, count INT)
RETURNS STRING
LANGUAGE JAVA
RUNTIME_VERSION = '11'
PACKAGES = ('com.snowflake:snowpark:latest')
IMPORTS = ('@mystage/myjar.jar')
HANDLER = 'MyClass.myMethod';
Criação e alteração de um procedimento usando o comando CREATE OR ALTER PROCEDURE¶
Crie um procedimento armazenado em Python de direitos do proprietário com integrações de acesso externo e privilégios padrão em OWNER.
CREATE OR ALTER PROCEDURE python_add1(A NUMBER)
RETURNS NUMBER
LANGUAGE PYTHON
HANDLER='main'
RUNTIME_VERSION=3.10
EXTERNAL_ACCESS_INTEGRATIONS=(example_integration)
PACKAGES = ('snowflake-snowpark-python')
EXECUTE AS OWNER
AS
$$
def main(session, a):
return a+1
$$;
Alterar os segredos do procedimento armazenado e mudar o procedimento armazenado para um procedimento de direitos do chamador:
CREATE OR ALTER PROCEDURE python_add1(A NUMBER)
RETURNS NUMBER
LANGUAGE PYTHON
HANDLER='main'
RUNTIME_VERSION=3.10
EXTERNAL_ACCESS_INTEGRATIONS=(example_integration)
secrets=('secret_variable_name'=secret_name)
PACKAGES = ('snowflake-snowpark-python')
EXECUTE AS CALLER
AS
$$
def main(session, a):
return a+1
$$;