

 O Amazon Redshift não permitirá mais a criação de UDFs do Python a partir do Patch 198. As UDFs do Python existentes continuarão a funcionar normalmente até 30 de junho de 2026. Para ter mais informações, consulte a [publicação de blog ](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

# CREATE PROCEDURE
<a name="r_CREATE_PROCEDURE"></a>

Cria um novo procedimento armazenado ou substitui um procedimento existente para o banco de dados atual.

Para ter mais informações e exemplos, consulte [Criar procedimentos armazenados no Amazon Redshift](stored-procedure-overview.md).

## Privilégios obrigatórios
<a name="r_CREATE_PROCEDURE-privileges"></a>

Você deve ter permissão de uma das seguintes formas para executar CREATE OR REPLACE PROCEDURE:
+ Para CREATE PROCEDURE:
  + Superusuário
  + Usuários com privilégios CREATE e USAGE no esquema no qual o procedimento armazenado é criado.
+ Para REPLACE PROCEDURE:
  + Superusuário
  + Proprietário do procedimento

## Sintaxe
<a name="r_CREATE_PROCEDURE-synopsis"></a>

```
CREATE [ OR REPLACE ] PROCEDURE sp_procedure_name  
  ( [ [ argname ] [ argmode ] argtype [, ...] ] )
[ NONATOMIC ]
AS $$
  procedure_body
$$ LANGUAGE plpgsql
[ { SECURITY INVOKER | SECURITY DEFINER } ]
[ SET configuration_parameter { TO value | = value } ]
```

## Parâmetros
<a name="r_CREATE_PROCEDURE-parameters"></a>

 OR REPLACE   
Uma cláusula que especifica que, se um procedimento com o mesmo nome e tipos de dados do argumento de entrada, ou assinatura, como esse já existir, o procedimento existente será substituído. Só é possível substituir um procedimento por um novo procedimento que defina um conjunto idêntico de tipos de dados.   
Se você definir um procedimento com o mesmo nome de um procedimento existente, mas com uma assinatura diferente, um novo procedimento será criado. Em outras palavras, o nome do procedimento é sobrecarregado. Para obter mais informações, consulte [Sobrecarga de nomes de procedimento](stored-procedure-naming.md#stored-procedure-overloading-name). 

 *sp\$1procedure\$1name*   
O nome do procedimento. Se você especificar um nome de esquema (como **myschema.myprocedure**), o procedimento será criado no esquema especificado. Caso contrário, o procedimento será criado no esquema atual. Para obter mais informações sobre nomes válidos, consulte [Nomes e identificadores](r_names.md).   
Recomendamos que você prefixe os nomes de todos os UDF com `sp_`. O Amazon Redshift reserva o prefixo `sp_` para nomes de procedimentos armazenados. Ao usar o prefixo `sp_`, você garante que o seu nome de procedimento armazenado não entra em conflito com qualquer procedimento armazenado integrado ao Amazon Redshift existente ou futuro ou nomes de função. Para obter mais informações, consulte [Nomeação de procedimentos armazenados](stored-procedure-naming.md).  
É possível definir mais de um procedimento com o mesmo nome se os tipos de dados dos argumentos de entrada, ou assinaturas, forem diferentes. Em outras palavras, nesse caso, o nome do procedimento é sobrecarregado. Para obter mais informações, consulte . [Sobrecarga de nomes de procedimento](stored-procedure-naming.md#stored-procedure-overloading-name)

*[argname] [ argmode] argtype*   
Uma lista de nomes de argumentos, modos de argumentos e tipos de dados. Somente o tipo de dados é obrigatório. O nome e o modo são opcionais e suas posições podem ser alternadas.  
O modo do argumento pode ser IN, OUT ou INOUT. O padrão é IN.  
Use argumentos OUT e INOUT para retornar um ou mais valores de uma chamada de procedimento. Quando houver argumentos OUT ou INOUT, a chamada de procedimento retorna uma linha de resultados que contém *n* colunas, onde *n* é o número total de argumentos OUT ou INOUT.  
Argumentos INOUT são argumentos de entrada e saída ao mesmo tempo. *Argumentos de entrada* incluem argumentos IN e INOUT, e *argumentos de saída* incluem argumentos OUT e INOUT.  
Argumentos OUT não são especificados como parte da instrução CALL. Especifique argumentos INOUT na instrução CALL do procedimento armazenado. Argumentos INOUT podem ser úteis ao enviar e retornar valores de uma chamada aninhada, bem como ao retornar um `refcursor`. Para obter mais informações sobre os tipos `refcursor`, consulte [Cursores](c_PLpgSQL-statements.md#r_PLpgSQL-cursors).  
Os tipos de dados de argumento podem ser qualquer tipo de dados padrão do Amazon Redshift. Além disso, um tipo de dados de argumento pode ser `refcursor`.  
Você pode especificar no máximo 32 argumentos de entrada e 32 argumentos de saída. 

AS \$1\$1 *procedure\$1body* \$1\$1   
Uma construção que delimita o procedimento a ser executado. As palavras-chave literais AS \$1\$1 e \$1\$1 são obrigatórias.  
O Amazon Redshift exige que você inclua a instrução em seu procedimento usando um formato chamado cotação de dólar. Qualquer item incluído na instrução é aprovado exatamente como está. Não é preciso inserir caracteres de escape antes dos caracteres especiais, pois o conteúdo da string é gravado literalmente.  
Com a *cotação de dólar*, um par de símbolos de cifrão (\$1\$1) deve ser usado no início e no final da instrução para que ela seja executada, conforme exibido no exemplo a seguir.  

```
$$ my statement $$
```
Como opção, entre cada par de símbolos de cifrão, você pode especificar uma string para ajudar a identificar a instrução. A string que você usa deve ser a mesma no início e no final dos pares de sinais. A sequência diferencia maiúsculas de minúsculas e segue as mesmas restrições de um identificador sem aspas, com a exceção de que não pode conter cifrões. O exemplo a seguir usa a string test.  

```
$test$ my statement $test$
```
Essa sintaxe também é útil para cotação de dólar aninhada. Para obter mais informações sobre o uso de símbolos de cifrão, consulte “Constantes de string entre símbolos de cifrão” em [Estrutura lexical](https://www.postgresql.org/docs/9.0/sql-syntax-lexical.html) na documentação do PostgreSQL.

 *procedure\$1body*   
Um conjunto de instruções válidas da PL/pgSQL. As instruções da PL/pgSQL aumentam comandos SQL com construções processuais, incluindo loops e expressões condicionais, a fim de controlar o fluxo lógico. A maioria dos comandos SQL podem ser usados no corpo do procedimento, incluindo linguagem de modificação de dados (DML), como COPY, UNLOAD e INSERT, e linguagem de definição de dados (DDL), como CREATE TABLE. Para obter mais informações, consulte [Referência da linguagem PL/pgSQL](c_pl_pgSQL_reference.md). 

LANGUAGE *plpgsql*  
Um valor de linguagem. Especifique `plpgsql`. É necessário ter permissão de uso na linguagem para usar `plpgsql`. Para obter mais informações, consulte [GRANT](r_GRANT.md). 

NONATOMIC  
Cria o procedimento armazenado em um modo de transação não atômico. O modo NONATOMIC confirma automaticamente as instruções dentro do procedimento. Além disso, quando ocorre um erro dentro do procedimento NONATOMIC, o erro não será relançado se for tratado por um bloco de exceções. Para obter mais informações, consulte [Gerenciamento de transações](stored-procedure-transaction-management.md) e [RAISE](c_PLpgSQL-statements.md#r_PLpgSQL-messages-errors).  
Ao definir um procedimento armazenado como `NONATOMIC`, considere o seguinte:  
+ Quando você aninha chamadas de procedimentos armazenados, todos os procedimentos devem ser criados no mesmo modo de transação.
+ A opção `SECURITY DEFINER` e a opção `SET configuration_parameter` não são compatíveis ao criar um procedimento no modo NONATOMIC.
+ Qualquer cursor aberto (explícita ou implicitamente) será fechado automaticamente quando uma confirmação implícita for processada. Portanto, você deve abrir uma transação explícita antes de iniciar um loop de cursor para garantir que nenhuma instrução SQL dentro da iteração do loop seja confirmada implicitamente.

SECURITY INVOKER \$1 SECURITY DEFINER  
A opção `SECURITY DEFINER` não é compatível quando `NONATOMIC` é especificado.  
O modo de segurança para o procedimento determina os privilégios de acesso do procedimento em tempo de execução. O procedimento deve ter permissão para acessar os objetos de banco de dados subjacentes.   
Para o modo SECURITY INVOKER, o procedimento usa os privilégios do usuário que chama o procedimento. O usuário deve ter permissões explícitas para os objetos de banco de dados subjacentes. O padrão é SECURITY INVOKER.  
Para o modo SECURITY DEFINER, o procedimento usa os privilégios do proprietário do procedimento. O proprietário do procedimento é definido como o usuário que possui o procedimento no tempo de execução, não necessariamente o usuário que definiu o procedimento inicialmente. O usuário que chama o procedimento precisa ter privilégio de execução no procedimento, mas não precisa de qualquer privilégio nos objetos subjacentes. 

SET configuration\$1parameter \$1 TO value \$1 = value \$1  
Essas opções não são compatíveis quando `NONATOMIC` é especificado.  
A cláusula SET faz com que o `configuration_parameter` especificado seja definido como o valor especificado quando o procedimento for inserido. Depois, essa cláusula restaurará `configuration_parameter` para seu valor anterior quando o procedimento sair. 

## Observações de uso
<a name="r_CREATE_PROCEDURE-usage"></a>

Se um procedimento armazenado tiver sido criado usando a opção SECURITY DEFINER, ao invocar a função CURRENT\$1USER de dentro do procedimento armazenado, o Amazon Redshift retornará o nome de usuário do proprietário do procedimento armazenado.

## Exemplos
<a name="r_CREATE_PROCEDURE-examples"></a>

**nota**  
Se você encontrar um erro na execução desses exemplos parecido com:  

```
ERROR: 42601: [Amazon](500310) unterminated dollar-quoted string at or near "$$
```
Consulte [Visão geral dos procedimentos armazenados no Amazon Redshift](stored-procedure-create.md). 

O exemplo a seguir cria um procedimento com dois parâmetros de entrada.

```
CREATE OR REPLACE PROCEDURE test_sp1(f1 int, f2 varchar(20))
AS $$
DECLARE
  min_val int;
BEGIN
  DROP TABLE IF EXISTS tmp_tbl;
  CREATE TEMP TABLE tmp_tbl(id int);
  INSERT INTO tmp_tbl values (f1),(10001),(10002);
  SELECT min_val MIN(id) FROM tmp_tbl;
  RAISE INFO 'min_val = %, f2 = %', min_val, f2;
END;
$$ LANGUAGE plpgsql;
```

**nota**  
 Quando você escreve procedimentos armazenados, recomendamos a prática de proteger valores confidenciais:   
 Não codifique nenhuma informação confidencial na lógica do procedimento armazenado. Por exemplo, não atribua uma senha de usuário em uma instrução CREATE USER no corpo de um procedimento armazenado. Isso representa um risco de segurança, pois valores codificados podem ser registrados como metadados de esquema nas tabelas do catálogo. Em vez disso, transmita valores confidenciais, como senhas, como argumentos ao procedimento armazenado por meio de parâmetros.   
Para obter mais informações sobre os procedimentos armazenados, consulte [CREATE PROCEDURE](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_PROCEDURE.html) e [“Criar procedimentos armazenados no Amazon Redshift”](https://docs.aws.amazon.com/redshift/latest/dg/stored-procedure-overview.html). Para obter mais informações sobre tabelas de catálogo, consulte [“Tabelas de catálogo do sistema”](https://docs.aws.amazon.com/redshift/latest/dg/c_intro_catalog_views.html).

O exemplo a seguir cria um procedimento com um parâmetro IN, um parâmetro OUT e um parâmetro INOUT.

```
CREATE OR REPLACE PROCEDURE test_sp2(f1 IN int, f2 INOUT varchar(256), out_var OUT varchar(256))
AS $$
DECLARE
  loop_var int;
BEGIN
  IF f1 is null OR f2 is null THEN
    RAISE EXCEPTION 'input cannot be null';
  END IF;
  DROP TABLE if exists my_etl;
  CREATE TEMP TABLE my_etl(a int, b varchar);
    FOR loop_var IN 1..f1 LOOP
        insert into my_etl values (loop_var, f2);
        f2 := f2 || '+' || f2;
    END LOOP;
  SELECT INTO out_var count(*) from my_etl;
END;
$$ LANGUAGE plpgsql;
```

O exemplo a seguir cria um procedimento que usa o parâmetro `SECURITY DEFINER`. Esse procedimento é executado usando os privilégios do usuário proprietário do procedimento.

```
CREATE OR REPLACE PROCEDURE sp_get_current_user_definer()
AS $$
DECLARE curr_user varchar(250);
BEGIN
  SELECT current_user INTO curr_user;
  RAISE INFO '%', curr_user;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER;
```

O exemplo a seguir cria um procedimento que usa o parâmetro `SECURITY INVOKER`. Esse procedimento é executado usando os privilégios do usuário que executa o procedimento.

```
CREATE OR REPLACE PROCEDURE sp_get_current_user_invoker()
AS $$
DECLARE curr_user varchar(250);
BEGIN
  SELECT current_user INTO curr_user;
  RAISE INFO '%', curr_user;
END;
$$ LANGUAGE plpgsql
SECURITY INVOKER;
```