Ciência da Computação GBC043 Sistemas de Banco de Dados Programando com SQL s Avisos Vista da segunda prova Data: 03/06 das 13:40 às 15:00h Local: sala 1B137 Profa. Maria Camila Nardini Barioni camila.barioni@ufu.br Bloco B - sala 1B137 1 semestre de 2019 2 Sumário Discussão exercícios aula anterior Gatilhos EXERCÍCIO LAB SP Exercícios 3 8 Atividade em lab Aula 29 Modelo Relacional: Cliente = { CodCli, NomeCli, Endereco, Cidade, CEP, UF, CGC} Vendedor = { CodVend, NomeVend, Salfixo, FaixaComis} Atividade em lab Aula 29 /* (b) Atualizar a Tabela Cliente, alterando para cada cliente um campo TOTALCOMPRAS, em que fique armazenada a quantidade total de pedidos realizados pelo mesmo. Se o campo não existir, crie-o. */ ALTER TABLE CLIENTE ADD COLUMN TOTALCOMPRAS INTEGER; Produto = { CodProd, Unidade, Descri, ValoUnit } Pedido = {NumPed, Prazoentr, CodCli(Cliente.CodCli), CodVend(Vendedor.CodVend) } ItemPedido = { NumPed(Pedido.NumPed), CodProd(Produto.CodProduto), Quant} 9 10 1
Atividade em lab Aula 29 CREATE OR REPLACE FUNCTION AtualizaCliente() RETURNS VOID AS $$ DECLARE AUX cliente%rowtype; BEGIN FOR AUXINSELECT CODCLI FROM CLIENTE LOOP UPDATE CLIENTE SET TOTALCOMPRAS = (SELECT COUNT(NUMPED) FROM PEDIDO WHERE CODCLI = AUX.CODCLI) WHERE CODCLI = AUX.CODCLI; TRIGGER GATILHO END LOOP; END $$ LANGUAGE 'plpgsql'; SELECT * FROM AtualizaCliente() 11 12 Gatilho ou Disparador É uma sub-rotina, semelhante as stored procedures, que tem como característica operacional ser executada automaticamente quando uma determinada ação (INSERT/UPDATE/DELETE) for realizada no banco de dados Uma das maneiras mais práticas de implementar rotinas para garantir a integridade de dados ou de operações Principal diferença entre e Stored Procedure é executado automaticamente Stored Procedure precisa ser explicitamente invocada 13 14 Exemplo... Voltando ao exercício da aula anterior Podem ser utilizados para gerenciar informações do banco de dados Automatizar a geração de dados Fazer a auditoria das modificações Implantar as restrições complexas de integridade Personalizar as autorizações complexas de segurança Modelo Relacional: Cliente = { CodCli, NomeCli, Endereco, Cidade, CEP, UF, CGC} Vendedor = { CodVend, NomeVend, Salfixo, FaixaComis} Produto = { CodProd, Unidade, Descri, ValoUnit } Pedido = {NumPed, Prazoentr, CodCli(Cliente.CodCli), CodVend(Vendedor.CodVend) } ItemPedido = { NumPed(Pedido.NumPed), CodProd(Produto.CodProduto), Quant} Quais gerações de dados poderiam ser automatizadas? 15 16 2
Componentes de um Aciona stored procedures para executar determinadas tarefas Está associado a uma tabela ou uma visão 1. Comando SQL que aciona o trigger O disparo do trigger pode ser ocasionado pelo comando SQL ou por um evento do usuário Em uma tabela, pelos comandos INSERT, UPDATE ou DELETE Em um objeto de esquema, por meio dos comandos CREATE, ALTER ou DROP No carregamento/shutdown do BD por uma mensagem de erro No logon/logoff de um usuário 17 18 Componentes de um 2. Limitador de ação do trigger Representado pela cláusula WHEN Especifica qual condição deve ser verdadeira para que o trigger seja disparado Componentes de um 3. Ação executada pelo trigger É o bloco de comandos que é executado pelo trigger Chama uma stored procedure 19 20 Para criar um trigger é preciso Definir um trigger procedure Criar o trigger propriamente dito, que definirá quando o trigger procedure será executado 21 O trigger procedure é muito similar a um stored procedure, mas é um pouco mais restrito devido à maneira como é chamado Não possui parâmetros de entrada na função Mas pode receber dados de entrada (ver slides à frente) Deve retornar o tipo especial trigger Exemplo: CREATE FUNCTION trigger_procedure_name() -- Sem parâmetros de entrada RETURNS trigger AS -- Retorna tipo trigger $$ BEGIN -- Aqui entra o corpo da trigger_procedure END; $$ language plpgsql; 22 3
Para criar um trigger é preciso Definir um trigger procedure Criar o trigger propriamente dito, que definirá quando o trigger procedure será executado : FORMA GERAL 23 24 : Evento : Evento O trigger dispara quando um evento específico ocorre (INSERT, DELETE ou UPDATE) Mais de um evento pode ser especificado na criação do trigger (separados por OR) CREATE TRIGGER check_salario BEFORE INSERT OR UPDATE /* o trigger é chamando quando ocorre um INSERT ou UPDATE */ ON empregado FOR EACH { ROW STATEMENT } EXECUTE PROCEDURE função ( argumentos ) 25 26 : BEFORE ou AFTER : BEFORE ou AFTER O trigger dispara quando um evento específico ocorre (INSERT, DELETE ou UPDATE) Opção BEFORE: A chamada do trigger é feita antes do evento ocorrer Tipicamente usada para verificação ou modificação dos dados antes deles serem inseridos ou atualizados Opção AFTER: É possível requisitar o disparo do trigger depois que o evento ocorreu Tipicamente usada para propagar atualizações para outras tabelas ou fazer verificação de integridade com outras tabelas 27 28 4
: ROW ou STATEMENT : ROW ou STATEMENT Algumas consultas SQL podem afetar várias linhas de dados. Nesses casos, o trigger pode ser chamado de duas formas: Opção ROW: Nesse caso, o trigger procedure é executado múltiplas vezes, uma para cada linha afetada pelo evento (Insert / Delete / Update) per-row trigger Exemplo: uma atualização pelo comando UPDATE pode afetar diversas linhas da tabela 29 30 : ROW ou STATEMENT Algumas consultas SQL podem afetar várias linhas de dados. Nesses casos, o trigger pode ser chamado de duas formas: Opção STATEMENT: O trigger procedure é chamado somente uma vez independente do número de linhas afetadas na consulta Particularmente, quando nenhuma tupla é afetada o trigger ainda é chamado per-statement trigger Exemplo: gerar um simples registro de auditoria proveniente de uma alteração : WHEN 31 32 : WHEN Uma expressãobooleana que determina se o trigger deve ser executado ou não Se a cláusula WHEN for especificada, a função só será chamada se a condição for verdadeira Nas triggers definidas com FOR EACH ROW, a condição especificada na cláusula WHEN pode referenciar colunas com valores antigos (old) ou novos (new) usando a sintaxe OLD.column_name ou NEW.column_name respectivamente 33 Alteração Recriar com o comando CREATE Desativação ALTER TABLE table_namedisable TRIGGER trigger_name Ativação ALTER TABLE table_nameenable TRIGGER trigger_name Exclusão DROP TRIGGER trigger_name ON table_name 34 5
- Exemplo Suponha que seja necessário auditar a alteração de preço quando o novo preço é inferior a 25% do preço antigo É necessário especificar uma condição do trigger para comparar o preço novo com o preço antigo - Exemplo CREATE TABLE products ( product_id INTEGER CONSTRAINT products_pk PRIMARY KEY, product_type_id INTEGER, name VARCHAR(30) NOT NULL, description VARCHAR(50), price NUMERIC(5, 2) ); 35 36 - Exemplo CREATE TABLE product_price_audit ( product_id INTEGER CONSTRAINT price_audit_fk_products REFERENCES products(product_id), * old_price NUMERIC(5, 2), new_price NUMERIC(5, 2) ); * Chave estrangeira que referencia a tabela que contém os produtos 37 - Exemplo CREATE OR REPLACE FUNCTION audit_product_price() RETURNS trigger AS $$ BEGIN RAISE NOTICE 'product_id = %, old_price = %, new_price = %', old.product_id, old.price, new.price ; RAISE NOTICE 'A redução de preço é de mais de 25 porcento'; -- insert row into the product_price_audit table INSERT INTO product_price_audit (product_id, old_price, new_price) VALUES (old.product_id, old.price, new.price); RETURN NULL; -- sempre deve ter um retorno END $$ language 'plpgsql'; CREATE TRIGGER before_product_price_update BEFORE UPDATE OF price ON products FOR EACH ROW WHEN (new.price < old.price * 0.75) EXECUTE PROCEDURE audit_product_price(); 38 - Exemplo BEFORE UPDATE OF price Significa que o trigger é disparado antes da atualização de price FOR EACH ROW Significa que isso é um trigger em nível de tupla, isto é, o código do trigger é executado uma vez para cada tupla atualizada A condição do trigger é (new.price< old.price * 0.75) O trigger é disparado somente quando o novo preço é menor do que 25 % do preço antigo Os valores novos e antigos do atributo são acessados por meio dos apelidos old e new no trigger 39 - Exemplo per-statement (por sentença): deve retornar sempre NULL row-level (por linha). Duas situações: BEFORE e AFTER BEFORE NEW/OLD para que a operação continue normalmente RETURN NEW nos casos de INSERT e UPDATE OBS: você pode alterar os atributos na variável NEW RETURN OLD para DELETE Para cancelar a operação deve retornar NULL RETURN NULL; AFTER o tipo retornado é ignorado, podendo então ser NULL 40 6
- Exemplo - Exemplo Disparando o trigger Disparando o trigger Para disparar o trigger do exemplo anterior é necessário reduzir o preço de um produto em mais de 25% Para disparar o trigger do exemplo anterior é necessário reduzir o preço de um produto em mais de 25% UPDATE products SET price = price *.7 WHERE product_id IN (5, 10); UPDATE products SET price = price *.7 WHERE product_id IN (5, 10); 41 42 Exemplo 2 - Exemplo Disparando o trigger Para ver o conteúdo da tabela que guarda as informações de auditoria for each row para armazenar data/hora e nome do usuário que inseriu ou modificou empregado SELECT * FROM product_price_audit ORDER BY product_id; PRODUCT_ID OLD_PRICE NEW_PRICE ----------------- -------------- --------------- 5 49.99 34.99 10 15.99 11.19 43 44 Exemplo 2 Exemplo 2 45 46 7
Exercícios Modelo Relacional FUNCIONARIO (idfunc, nome, idade, salario) TRABALHA (idfunc (FUNCIONARIO.idFunc), iddepto (DEPARTAMENTO.idDepto), nro_horas) DEPARTAMENTO (iddepto, nome, orçamento, idgerente (FUNCIONARIO.idFunc), qtdefuncionario, custofpagamento) Exercícios Analise cada uma das restrições de integridade e verifique se elas podem ser expressas em SQL (restrição de domínio, chave primária, chave estrangeira ou restrições CHECK) elas precisam ser impostas por um gatilho Nesse caso, indique quais operações (inserções, exclusões ou atualizações em relações específicas) devem ser monitoradas para forçar a restrição e explique 47 48 Exercícios 1. O número total de horas/semanais que um funcionário trabalha na empresa não pode ser inferior a 20 horas e não pode ultrapassar 44 horas 2. Os funcionários devem ter um salário mínimo de R$ 954,00 3. Todo gerente também deve ser um funcionário 4. A contratação de funcionários por um departamento não pode fazer com que o custo com a folha de pagamento exceda o orçamento do departamento Leitura Adicional para Casa ELMASRI-NAVATHE Sistemas de Banco de Dados Capítulo 5 (Seção 5.2) Manual de SQL do PostgreSQL http://www.postgresqltutorial.com/postgresql-triggers/ 49 51 8