Mostrando postagens com marcador PostgreSQL. Mostrar todas as postagens
Mostrando postagens com marcador PostgreSQL. Mostrar todas as postagens

quarta-feira, 1 de novembro de 2023

Functions, Triggers e Procedures no PostgreSQL

   

       Nesse artigo vou trazer um exemplo de Functions, Triggers e Procedures no PostgreSQL. Antes vamos entender um pouco a diferença entre eles:

         

1.   Funções (Functions):

·         As funções são rotinas ou subprogramas que recebem um ou mais parâmetros de entrada, realizam cálculos ou operações e retornam um valor.

·         Elas podem ser chamadas a partir de instruções SQL, expressões ou outras funções.

·         As funções podem ser usadas para encapsular lógica de negócio complexa e fornecer um resultado computado.

·         Exemplo: Uma função que calcula a idade com base na data de nascimento.

2.   Triggers:

·         Triggers são procedimentos armazenados que são automaticamente invocados em resposta a um evento específico que ocorre no banco de dados.

·         Eles são acionados por ações, como inserção, atualização ou exclusão de dados em uma tabela.

·         Os triggers podem ser usados para impor regras de negócio, manter integridade referencial, auditar alterações de dados, entre outras funcionalidades.

·         Exemplo: Um trigger que atualiza um campo de data de modificação sempre que uma linha é atualizada em uma tabela.

3.   Procedimentos (Procedures):

·         Os procedimentos são rotinas ou subprogramas que podem receber parâmetros de entrada, executar um conjunto de instruções e, opcionalmente, retornar valores.

·         Eles são usados para agrupar um conjunto de instruções que podem ser executadas repetidamente ou como uma unidade lógica.

·         Os procedimentos podem ser chamados a partir de outros procedimentos, instruções SQL ou de uma aplicação externa.

·         Exemplo: Um procedimento que insere um registro em uma tabela e atualiza um contador.

 

Agora vamos aos exemplos:

 

1 – Function

 

-- Função

CREATE OR REPLACE FUNCTION calcularIdade(data_nascimento DATE) RETURNS INTEGER AS

DECLARE

  idade INTEGER;

BEGIN

  idade := EXTRACT(YEAR FROM CURRENT_DATE) - EXTRACT(YEAR FROM data_nascimento);

  RETURN idade;

END;

LANGUAGE plpgsql;

 

--Chamada da função

SELECT calcularIdade('1990-05-10');

 

2 – Trigger

 

-- Temos uma tabela

CREATE TABLE produtos (

  id SERIAL PRIMARY KEY,

  nome VARCHAR(50),

  quantidade INTEGER,

  data_atualizacao DATE

);

 

-- Criação da função usada pelo Trigger

CREATE OR REPLACE FUNCTION atualizarDataAtualizacao()

  RETURNS TRIGGER AS

DECLARE

BEGIN

  NEW.data_atualizacao := CURRENT_DATE;

  RETURN NEW;

END;

LANGUAGE plpgsql;

 

-- Criação da Trigger

CREATE TRIGGER trigger_atualizar_data

  BEFORE INSERT OR UPDATE ON produtos

  FOR EACH ROW

  EXECUTE FUNCTION atualizarDataAtualizacao();

 

-- Utilização da Trigger ocorre automaticamente

INSERT INTO produtos (nome, quantidade) VALUES ('Produto A', 10);

UPDATE produtos SET quantidade = 20 WHERE id = 1; 

 

Note nesse trecho de código, na criação da função da trigger, o uso da palavra NEW. NEW é uma referência a uma variável especial em PL/pgSQL usada em gatilhos (triggers) no PostgreSQL. Quando um gatilho é acionado, ele tem acesso a duas variáveis especiais: OLD e NEW.

 

OLD contém os valores anteriores das colunas afetadas pela ação que disparou o gatilho.

NEW contém os novos valores que serão inseridos ou já foram inseridos devido à ação que disparou o gatilho.

 

No trecho de código acima, NEW.data_atualizacao está sendo usado para atribuir a data atual à coluna data_atualizacao da linha que está sendo inserida ou atualizada.

 

3 – Procedure

-- Criação da Procedure

CREATE OR REPLACE PROCEDURE inserirProduto(nome VARCHAR(50), quantidade INTEGER)

  AS

DECLARE

BEGIN

  INSERT INTO produtos (nome, quantidade, data_atualizacao)

  VALUES (nome, quantidade, CURRENT_DATE);

END;

LANGUAGE plpgsql;

 

-- Utilização da Procedure

CALL inserirProduto('Produto B', 15);

quarta-feira, 24 de maio de 2023

Uso de transações e variáveis em SQL Server, Oracle e PostgreSQL

Neste artigo vou mostrar o uso de transação e de declaração de variável nos Bancos de Dados mais utilizados: SQL Server, Oracle e PostgreSQL.

 

As vezes você pode por exemplo usar um SELECT pra retornar um ID e guardar ele em uma variável para depois fazer várias ações com ele, e essas ações precisam ser feitas por completo ou então você precisa desfazer o que foi executado parcialmente. Nos exemplos a seguir, o trecho que executa o DELETE serve como exemplo para aonde as ações seriam colocadas.

 

Segue o exemplo para SQL Server:

 

BEGIN TRANSACTION;

      DECLARE @nomeVariavel tipoVariavel; (alguns tipos como CHAR e VARCHAR precisam do tamanho entre parenteses junto ao tipo : varchar(30))


      SELECT @nomeVariavel = coluna

      FROM tabela WHERE condição;


      DELETE FROM tabela

      WHERE coluna = @nomeVariavel;

 

IF @@ERROR <> 0

      BEGIN

      ROLLBACK TRANSACTION;

      END

ELSE

      BEGIN

            COMMIT TRANSACTION;

      END

 

Segue o exemplo para Oracle:

 

DECLARE nome_da_variavel datatype;

BEGIN

nome_da_variavel := valor;

 

DELETE FROM tabela WHERE coluna = nome_da_variavel;

              

BEGIN

                

EXCEPTION WHEN others THEN

                 ROLLBACK;

                 RAISE;

              

END;

COMMIT;

END;

 

E por fim, segue o exemplo para PostgreSQL:

 

BEGIN;

DECLARE nome_da_variavel datatype;

nome_da_variavel := valor;

 

DELETE FROM tabela WHERE coluna = nome_da_variavel;

 

BEGIN

    EXCEPTION WHEN others THEN

        ROLLBACK;

        RAISE;

END;

COMMIT;

 

Pra esse artigo é isso, espero que ajude.

terça-feira, 1 de junho de 2021

Exemplo de UPDATE com SELECT em uma outra tabela

       Nesse post rápido eu trago o exemplo de um UPDATE com dados de um SELECT em outra tabela. Note que o where faz ligação entre a tabela do update e a tabela do FROM. Isso é importante para evitar que todas as linhas fiquem com dados repetidos.


update t_agendamento set id_paciente = paciente.id_paciente from t_agendamento agc inner join t_paciente paciente on agc.num_prontuario = paciente.num_prontuario where agc.id_agendamento = t_agendamento.id_agendamento

terça-feira, 20 de abril de 2021

Exemplo de função SQL para atualizar vários registros que usam sequence

       Nesse artigo trago um exemplo de uma função para atualização de vários registros com dados de uma sequence. Caso não seja criada uma função o que acontece é que apesar de chamar-mos a sequence, todos os os registros receberiam o mesmo valor. Por isso se faz necessário o uso de uma função.


CREATE OR REPLACE FUNCTION cria_num_boletim_pacientes_em_atendimento()

 RETURNS void

 LANGUAGE plpgsql

AS $function$

declare

internacao record;

        begin

for internacao in

(select il.id_internacao from t_internacao_leito il

inner join t_internacao it on il.id_internacao = it.id_internacao

where it.id_tipo_atendimento = 2 and il.data_alta is null

group by il.id_internacao)

loop

update t_internacao set num_boletim = (select nextval('s_numero_boletim'))  where id_internacao = internacao.id_internacao;

end loop;

         end;

$function$;

segunda-feira, 30 de novembro de 2020

Acessando Tabela Externa dentro do seu Banco de Dados

As vezes precisamos fazer a leitura de dados de um banco que não é o da nossa aplicação, seja um acesso permanente como uma integração ou uma leitura pontual para importação de dados, e é isso que vou mostrar aqui. Esse acesso pode ser feito inclusive para Bancos de Dados diferentes. 

 

Os passos são os seguintes: 

 

  1. 1 - Instalar uma extensão usando CREATE EXTENSION. 

  1. 2 - Criar um servidor externo, usando CREATE SERVER, para representar cada banco de dados remoto ao qual deseja se conectar. 

  1. 3 - Criar um mapeamento de usuário, usando CREATE USER MAPPING, para cada usuário do banco de dados que você deseja permitir o acesso para cada servidor externo. 

  1. 4 - Criar as tabelas externas, usando CREATE FOREIGN TABLE  

 

Para acessar outros bancos dentro do nosso, é preciso de plugins para isso. Os plugins já estão no Postgre e precisam ser “ativados”. Neste exemplo vou mostrar um banco PostgreSQL acessar outro banco PostgreSQL. 

 

Os comandos abaixo exibem os plugins (extensões) disponíveis (o segundo traz um breve comentário sobre o plugin): 

 

SELECT * FROM pg_available_extensions; 

Ou 

SELECT * FROM pg_available_extension_versions 

 

O plugin que vamos usar é o postgres_fdw. Esse comando a seguir vai ativar o plugin e deixá-lo disponível para uso: 

 

CREATE EXTENSION postgres_fdw 

    SCHEMA "public" 

    VERSION "1.0"; 

 

Como essa extensão trata de acesso a um banco de dados, precisamos de um passo a mais que é o de criar o wrapper que vai ficar fazendo a tradução da linguagem de um banco para o outro. 

 

CREATE FOREIGN DATA WRAPPER postgres_fdw 

    HANDLER postgres_fdw_handler 

    VALIDATOR postgres_fdw_validator 

    OPTIONS (); 

 

Caso o wrapper já tenha sido criado, precisamos ver se o handler e o validator foram especificados, caso não, precisamos atualizar. 

 

ALTER FOREIGN DATA WRAPPER postgres_fdw 

    HANDLER public.postgres_fdw_handler 

    VALIDATOR public.postgres_fdw_validator; 

 

Para criar o servidor, vamos precisar do nome do banco, endereço e porta. Para o servidor vamos fazer: 

 

CREATE SERVER nome_servidor 

    FOREIGN DATA WRAPPER postgres_fdw 

  OPTIONS (dbname 'nome_banco', host 'ip_banco', port 'porta'); 

 

Para o(s) usuário(s) 

 

CREATE USER MAPPING 

    FOR postgres 

    SERVER nome_servidor 

    OPTIONS (password 'senha', user 'usuario'); 

 

Agora basta criar as tabelas. Aconselho criar um schema separado para suas tabelas de servidores externos para não misturar com as tabelas internas. Se o usuário tiver permissão de escrita, os comandos de UPDATE, INSERT, e DELETE vão funcionar normalmente. 

 

CREATE FOREIGN TABLE seu_schema.sua_tabela ( 

    id bigserial, 

    nome varchar(70) NOT NULL, 

    dt_nascimento date 

) 

SERVER nome_servidor 

OPTIONS (schema_name 'nome_schema_externo', table_name 'nome_tabela_externa'); 

 

Pode ser necessário dar permissão de acesso no banco externo caso ele esteja restringindo por IP o acesso. Você verá o erro: no pg_hba.conf entry for host "ip_seu_banco", user "usuario_que vc definiu", database "nome_banco_que_quer_acessar". 

 

Pronto, basta usar as tabelas como se estivessem localmente. 

 

Links: