Banco de Dados I 2007 MóduloIII: Linguagens de Consulta ...clodis/BDI/BDI_2007_Modulo3_3.pdf ·...

84
Módulo III: Linguagens de Consulta (Aulas 3, 4, 5 e 6) Clodis Boscarioli Banco de Dados I 2007

Transcript of Banco de Dados I 2007 MóduloIII: Linguagens de Consulta ...clodis/BDI/BDI_2007_Modulo3_3.pdf ·...

Módulo III: Linguagens de Consulta

(Aulas 3, 4, 5 e 6)

Clodis Boscarioli

Banco de Dados I

2007

Agenda:

� O módulo de Consultas de um SGBD;� SQL – Structured Query Language;� Introdução;� Operadores e cláusulas de manipulação;� Funções agregadas;� Operadores e cláusulas de modificação;� Visão;� Asserções e gatilhos;� Exemplos.

Visão Geral de um SGBD

SGBD

Usuários

Dicionáriode dados

Interface comaplicações

Programas deaplicações

Consultas

(queries)

Esquema de Banco de Dados

Usuáriosnavegantes

Programadoresde aplicações

Usuáriossofisticados

Administra-dores de BD

Processadorde consultas

Gerenciadorde memória

Gerenciadorde transações

Gerenciador de buffer

Gerenciadorde arquivos

InterpretadorDDL

CompiladorDML

Pré-compiladorde comandosDML

Programas deaplicações em código objeto

Componentes de execuçãode consultas

Armazenamento

em disco Índices

Arquivos dedados

Dados estatísticos BD

Relembrando!

Linguagens de Sistemas de BDs

1. Linguagem de Definição de Dados

Um esquema de dados é especificado por uma conjunto de definições expressas por uma linguagem especial chamada Linguagem de definição de dados (do inglês Data-Definition Language – DDL).

O resultado da compilação dos parâmetros/comandos DDL geram os dicionário de dados (arquivo de metadados).

2. Linguagem de Manipulação de Dados

Manipulação de dados = recuperação de informações do banco de dados e inserção, remoção e alteração de dados no banco de dados.

A linguagem de manipulação de dados (do inglês data-manipulation language – DML) é a linguagem que viabiliza o acesso e a manipulação do dados. Podem ser:

Procedurais: o usuário especifica procedimentos para recuperar os dados que necessita.

Não-procedurais: o usuário descreve os dados que necessita.

Linguagens de Sistemas de BDs

Processamento de Consultas

� Compilador DML: traduz comandos DML em instruções de baixo nível, entendidos pelo componente de execução de consultas. Alémdisso, otimiza a solicitação do usuário.

� Pre-compilador para comandos DML inseridos em programas de aplicação: convertem comandos DML em chamadas de procedimentos normais da linguagem hospedeira. Interage com o compilador DML e modo a gerar o código apropriado.

� Interpretador DDL: interpreta os comandos DDL e os registra no dicionário de dados.

� Componentes para tratamento de consultas: executa instruções de baixo nível gerada pelo compilador DML.

SQL - Introdução

� A SQL (Structured Query Language - Linguagem de Consulta Estruturada) pode ser considerada uma das maiores razões para o sucesso dos sistemas de banco de dados relacionais.

� É suportada por todos os SGBDs relacionais comerciais. Estes “deveriam” suportar a SQL padrão. Alguns fornecedores incluem outros comandos próprios.

� A vantagem do SQL padrão é não ter problemas com migração de SGBD para SGBD.

� SQL combina construtores da álgebra relacional e do cálculo relacional de tuplae proporciona uma interface declarativa e amigável.

� Inicialmente chamada de SEQUEL (Structured English Query Language), foi projetada e implementada pela IBM.

� Num esforço conjunto da ANSI (American Nacional Standars Institute) e da ISO (International Standards Organization) criou-se a primeira versão padrão da SQL, a SQL-86, substituída posteriormente pela SQL-92 e depois pela SQL-99. � abordada nesse Curso!

� O atual projeto da SQL é o padrão 200n.

SQL - Introdução

� Possui comandos para definição de dados, consultas e atualizações, abrangendo uma DDL e uma DML.

� Além disso, define mecanismos para criação de visões, especificações de segurança, autorizações, definições de restrições e controle de transações.

� Também possui regras para embutir os comandos SQL em linguagens de programação genérica como Java, COBOL, ou C/C++.

� O padrão SQL-99 foi divido em uma especificação de núcleo mais pacotes opcionais. O núcleo deve ser implementado por todos os vendedores de SGBD’s relacionais compatíveis com este padrão. Os pacotes podem ser implementados como módulos opcionais, que podem ser adquiridos independentemente para aplicações específicas de um BD, como data mining, dados espaciais, dados temporais, entre outros.

Definição de Dados e Tipos de Dados SQL

� Termos usados: tabela, linha e coluna.� Principal comando para definição de dados: CREATE

� Pode ser usado para criar esquemas, tabelas, domínio, asserções,gatilhos, visões.

� Esquema: agrupa tabelas e outros construtores que pertencem à mesma aplicação de um banco de dados.

� Um esquema SQL é identificado por um nome de esquema e inclui uma identificação de autorização, que indica o usuário ou a conta a qual o esquema pertence, bem como os descritores de cada elemento do esquema.

� Os elementos do esquema incluem tabelas, restrições, visões, domínios.

� Exemplo:Create schema Empresa authorization JSmith

� Um catálogo é uma coleção de esquemas em um ambiente SQL (um SGBD).

Definição de Dados e Tipos de Dados SQL

� CREATE TABLE:� Usado para especificar uma nova relação (tabela), dando-lhe um nome e especificando seus atributos e restrições iniciais.

� Forma geralcreate table empregado.

� De maneira geral, o esquema SQL, no qual as relações são declaradas, está implicitamente definido dentro do ambiente no qual os comandos CREATE TABLE serão executados.

� Alternativamente pode-se anexar de maneira explícita o nome do esquema ao nome da relação.

� Forma geralcreate table empresa.empregado

create table empregado( Fnome Varchar(15) not null,Minicial Char,Lnome Varchar(15) not null,SSN Char(9), not null,DataNasc Date,Endereço Varchar(30), Sexo Char,Salario Decimal(10,2),SuperSSN Char(9),DNO Int not null,

Primary Key (SSN),Foreign Key (DNO) references Departamento(DNum));

create table departamento( Dnome Varchar(15) not null,Dnumero Int not null,GerSSN Char(9) not null,GerDataInicio Date,

Primary Key (DNum),Unique (Dnome),Foreign Key (GerSSN) references empregado(SSN));

create domain tipo_ssn as char(9)

Restrições básicas

� Not null: valores nulos não são permitidos no atributo.

� Default <value>: valor padrão para um atributo.

� Check: restringe os valores permitidos para um atributo.� Suponha que os números dos departamentos estejam restritos aos números inteiros entre 1 e 20.

... Dnum int not null check (Dnum > 0 and Dnum < 21);create domain D_num as integer check (D_num > 0 and D_num < 21)

� Primary Key: especifica um ou mais atributos que definem a chave primária da relação.

� Unique: define chaves alternativas.

� Foreign Key: define os atributos de chaves estrangeiras e de onde (qual tabela e atributo) elas vieram.

� Set Null, Cascade e Set Default para on delete ou on update: ações que devem ser tomadas quando da exclusão ao ateração do atributo de chave estrangeira em sua tabela original).

create table empregado( ...,

Dno Int not null Default 1,constraint emppk

primary key (SSN),constraint empdeptfk

foreing key (Dno) referencesdepartamento(Dnumero) on delete set default on update cascade);

Restrições básicas

Restrições básicas

� Restrições de tuplas

� Exemplo: poder-se-ia adicionar a cláusula check ao final da declaração create table da tabela Departamento para ter certeza de que a data da nomeação do seu gerente é posterior à data de criação do departamento.

check (dep_cria_data < Ger_data_inicio)

Comandos para alterações de esquemas

� Drop: elimina elementos de esquema nomeados, como tabelas, domínios ou restrições, ou até mesmo o esquema propriamente dito.

drop schema empresa cascade

drop schema empresa restrict

drop table dependente cascade

� Alter: as definições de uma tabela básica (em meio estável) ou de outros elementos do esquema que possuírem denominação poderão ser alteradas pelo comando ALTER.

alter table empresa.empregado add funcao varchar(12);

alter table empresa.empregado drop endereco cascade;

alter table empresa.empregado alter gersn drop default;

alter table empresa.empregado alter gersn set default “334455”;

alter table empresa.empregado drop constraint empfk cascade;

Comandos para alterações de esquemas

SQL - Estrutura Básica

•A estrutura básica de uma expressão SQL consiste em três cláusulas: select, from e where, da seguinte forma:

select A1, A2, ..., Anfrom r1, r2, ... , rnwhere P

onde, cada Ai representa um atributo e cada riuma relação e P é um predicado a ser satisfeito.

- A cláusula select corresponde à operação de projeção da álgebra relacional. Usada para relacionar os atributos desejados no resultado de uma consulta.

- A cláusula from corresponde à operação de produto cartesiano da álgebra relacional. Associa as relações que serão pesquisadasdurante a evolução de uma expressão.

- A cláusula where corresponde à seleção do predicado da álgebra relacional. Consiste em um predicado envolvendo atributos da relação que aparece na cláusula from.

SQL - Estrutura Básica

� Considere o Esquema:

empregado (pnome, mnome, unome, ssn, datanasc, endereco, sexo, salario, superssn, dno)

departamento (dnome, dnumero, gerssn, gerdatainicio)

depto_localizações (dnumero, dlocalização)

projeto (pjnome, pnumero, plocalizaçao, dnum)

trabalha_em (essn, pno, horas)

dependente (essn, nome_dependente, sexo, datanasc, parentesco)

Exemplificando...

� Encontre o aniversário e o endereço dos empregados cujo nome seja ‘John B. Smith’.

select datanasc, endereco

from empregado

where pnome = “John” and mnome = “B” andunome = “Smith”;

Obs: o comando select não elimina tuplasrepetidas!

� Encontre o nome e o endereço de todos os empregados que trabalham no departamento ‘Pesquisa’.

select pnome, unome, endereco

from empregado, departamento

where dnome = “Pesquisa” and Dnumero = DNO;

Obs: na cláusula from estão as tabelas que serão combinadas (“juntadas”) com um produto cartesiano.

� Para cada projeto localizado em ‘Stanford’, relacione o número do projeto, o número do departamento responsável e o último nome do gerente do departamento, seu endereço e sua data de aniversário.

select pnumero, dnum, unome, endereco, datanasc

from projeto, departamento, empregado

where dnum = dnumero and gerssn = ssn and

plocalizacao = ‘Stanford’;

Operação Rename

Em SQL proporciona um mecanismo para renomear tanto atributos quanto relações, usando a cláusula as, como segue:

select Atributo as Novo_nomefrom relação;

Exemplo:

� Selecione todos os SSN de empregados

select ssn as seguro_socialfrom empregado;

� Selecione todas as combinações de um SSN de empregado e um Dnome de departamento

select ssn, dnome as Departamentofrom empregado, departamento;

Variáveis Tuplas

A cláusula asas é particularmente útil na definição de variável tupla, como é feito no cálculo relacional.

Uma variável tupla em SQL precisa estar associada a uma relação.

Variáveis tuplas são definidas na cláusula from por meio do uso da cláusula asas.

� Para cada empregado, recupere o primeiro e o último nome do empregado e o primeiro e o último nome de seu superior imediato.

select e.pnome, e.unome, s.nome, s.unome

from empregado as E, empregado as S

where E.superssn = S.ssn;

� Alternativa (na cláusula FROM):

Empregado as E(PN, MN, UM, SSN, DT, END, SEX, SAL, SSSN, DNO)

� Recupere todos os valores dos atributos de empregado que trabalham no departamento de número 5

select *from empregadowhere DNO = 5;

� Recupere o salário de todos os empregados

select all salariofrom empregado;

� Recupere todos os diferentes valores de salários

select distinct salariofrom empregado;

� Faça uma lista com todos os números de projetos nos quais esteja envolvido algum empregado cujo último nome seja ‘Smith’; ou como empregado, ou como gerente do departamento que controla o projeto.

(select distinct pnumerofrom projeto, departamento, empregadowhere Dnum = Dnumero and GerSSN = ssn andunome = ‘Smith’)union

(select distinct pnumerofrom trabalha_em, projeto, empregadowhere pnumero = Pno and essn = SSN andunome = ‘Smith’);

Obs: Diferença entre conjuntos � exceptInterseção de conjuntos � intersect

Operações em Strings

As operações de strings mais usadas são as checagens para verificação de coincidências de pares, usando o operador like. Identificamos esses pares por meio do uso de dois caracteres especiais:

( %) porcentagem: o caracter % compara qualquer substring;

( _ ) sublinhado: o caracter _ compara qualquer caracter.

� Recupere todos os empregados cujos endereços sejam em Houston,Texas.

select pnome, mnome, unomefrom empregadowhere endereço like ‘%Houston,TX%’;

� Recupere todos os empregados que nasceram na década de 50.

select pnome, mnome, unomefrom empregadowhere datanasc like ‘_ _ _ _ _ _ _ _ 5 _’;

� Suponha que se deseja ver qual será o resultado de aumentar em 10% o salário de todos os empregados que trabalham com o projeto ‘ProdutoX’.

select pnome, unome, 1.1*salário asaumento_sal

from empregado, trabalha_em, projeto

where ssn = essn and pno = pnumero and

pnome = ‘ProdutoX’;

� Recupere todos os empregados do departamento 5 que ganham entre 30 mil e 40 mil reais.

select *

from empregado

where (salario between 30000 and 40000) and dno = 5;

Ordenação e Apresentação de Tuplas

• Para listar uma relação em ordem ascendente usa-se:order by nome do campo asc

• Para listar uma relação em ordem descendente o comando é:

order by nome do campo desc

• Por default a relação dos itens é efetuada em ordem ascendente.

� Recupere a lista dos empregados e os respectivos projetos nos quais eles trabalham, ordenada por departamento e , dentro de cada departamento, também por ordem alfabética do último nome, e depois, pelo primeiro nome do empregado.

select dnome, unome, pnome, pjnomefrom departamento, empregado, trabalha_em, projetowhere dnumero = dno and ssn = essn and pno = pnumeroorder by dnome, unome, pnome;

Obs: order by dnome desc, unome asc, pnome asc

� Recupere os nomes de todos os empregados que não têm supervisor.

select pnome, unome

from empregado

where superssn is null;

� Faça uma lista com todos os números de projetos nos quais esteja envolvido algum empregado cujo último nome seja “Smith”; ou como empregado, ou como gerente do departamento que controle o projeto.

select distinct pnumero

from projeto

where pnumero in (select pnumero

from projeto, departamento, empregado

where dnum = dnumero and gerssn = ssnand unome = ‘Smith’)

or

pnumero in (select pno

from trabalha_em, empregado

where essn = ssn and unome = ‘Smith’);

� Selecione o número do seguro social de todos os empregados que trabalham com a mesma combinação (projeto, horas) em algum dos projetos em que o empregado ‘John Smith’ (ssn = ‘123456789’) trabalhe.

select distinct essn

from trabalha_em

where (pno, horas) in (select pno, horas

from trabalha_em

where ssn = ‘123456789’)

� Encontre os nomes dos empregados cujos salários são maiores que os salários de todos os empregados do departamento 5.

select unome, pnomefrom empregadowhere salario > all (select salario

from empregadowhere dno = 5);

� Obs: alternativas� = any (ou = some)� Uso de operadores (<, >, >=, <=, <>)� Combinações: >all, <all

� Recupere o nome de cada um dos empregados que tenham um dependente cujo primeiro nome e sexo sejam o mesmo do empregado em questão.

select pnome, unome

from empregado

where ssn in (select essn

from dependente

where pnome= dependente_nome

and empregado.sexo = dependente.sexo);

� Recupere o nome de cada um dos empregados que tenham um dependente cujo primeiro nome e sexo sejam o mesmo do empregado em questão.

select pnome, unome

from empregado

where exists (select *

from dependente

where ssn = essn and

empregado.sexo = sexo

and pnome = dependente_nome);

� Recupere o nome dos empregados que não possuam nenhum dependente.

select pnome, unome

from empregado

where not exists (select *

from dependente

where ssn = essn);

� Relacione os nomes de gerentes que possuam ao menos um dependente.

select pnome, unome

from empregado

where exists (select *

from dependente

where ssn = essn)

and

exists (select *

from departamento

where ssn = gerssn);

� Encontre todos os empregados que trabalham em todos os projetos controlados pelo departamento 5.

select pnome, unome

from empregado

where not exists

( (select pnumero from projeto where dnum = 5)

except

(select pno from trabalha_em where ssn = essn));

� Recupere os números dos seguros sociais de todos os empregados que trabalham nos projetos 1, 2 ou 3.

select distinct essn

from trabalha_em

where pno in (1, 2, 3);

� Recupere o nome e o endereço de todos os empregados que trabalham no departamento ‘Pesquisa’.

select pnome, unome, endereco

from (empregado join departamento on dno = dnumero)

where dnome = ‘Pesquisa’;

select pnome, unome, endereco

from (empregado natural join (departamento asdept(dnome, dno, gerssn, gerdatain)))

where dnome = ‘Pesquisa’;

� Para cada empregado, recupere o primeiro e o último nome do empregado e o primeiro e o último nome de seu superior imediato. Caso o empregado não tenha um superior imediato, inclua apenas o primeiro e o ultimo nome dele.

select e.unome as nome_empregado s.unome as

nome_supervisor

from (empregado as e left outer join empregado as s ons.superssn = s.ssn);

Obs: ainda tem-se o right outer join, full outer join

� SQL provê algumas funções de sumarização de dados.

� Exemplos: � Encontre a soma dos salários, o maior salário, o menor salário e a média salarial de todos os empregados.

select sum (salario), max (salario), min (salario), avg (salario)

from empregado;

Funções Agregadas

� Encontre a soma dos salários de todos os empregados do departamento ‘Pesquisa’, bem como o maior salário, o menor salário e a média salarial desse departamento.

select sum (salario), max (salario), min (salario), avg (salario)

from (empregado join departamento on dno = dnumero)

where dnome = ‘Pesquisa’;

� Recupere o número total de empregados da empresa

select count(*)

from empregado

� Recupere o número de empregados do departamento ‘Pesquisa’.

select count(*)from empregado, departamentowhere dno = dnumero and dnome = ‘pesquisa’

� Recupere o nome de todos os empregados que possuem dois ou mais dependentes.

select unome, pnomefrom empregadowhere (select count(*)

from dependentewhere ssn = essn) >= 2

� Conte o número de valores diferentes de salário contidos no banco de dados

select count (distinct salario)from empregado

� Para cada departamento, recupere o número de empregados que nele trabalham e a média de seus salários

select dno, count (*), avg (salario)from empregadogroup by dno;

� Para cada projeto, recupere seu número, seu nome e o número de empregados que nele trabalham.

select pnumero, pjnome, count (*)

from projeto, trabalha_em

where pnumero = pno

group by pnumero, pjnome

� Para cada projeto em que trabalhem mais de dois empregados, recupere o número do projeto, seu nome e o número de empregados.

select pnumero, pjnome, count (*)

from projeto, trabalha_em

where pnumero = pno

group by pnumero, pjnome

having count (*) > 2;

� Para cada departamento que tenha mais de cinco empregados, recupere o número do departamento e o número dos empregados que recebem mais de 40 mil.

select dnumero, count (*)from departamento, empregadowhere dnumero = dno and salario > 40000 and dno in(select dno

from empregadogroup by dnohaving count (*) > 5)

group by dnumero;

� Adicione uma nova tupla à relação empregado.

insert into empregado

values (‘Richard’, ‘K’, ‘Marini’, ‘4830672’, ’13-06-1953’, ’98, Oak Forest, TX’, ’M’, 37000, ‘3468345’, ‘4’);

� Insira uma tupla, de um novo empregado, para o qual sabe-se apenas os atributos pnome, unome, dno e ssn.

insert into empregado(pnome, unome, dno, ssn)

values (‘Richard’, ‘Marini’, 4, ‘4830672’);

SQL - Inserção, exclusão e Atualização

� Crie uma tabela que contenha o total de empregados e o total de salários e cada departamento.

create table depts_info(dept_nome varchar(15),no_de_emps integer,total_sal integer);

insert into depts_info (dept_nome, no_de_emps, total_sal)select dnome, count (*), sum (salario)from (departamento join empregado on dnumero = dno)group by dnome;

� Exemplos de uso do comando delete:

delete from empregadowhere unome = ‘Brown’;

delete from empregadowhere ssn = ‘1234530’;

delete from empregadowhere dno in (select dnumero

from departamentowhere dnome = ‘Pesquisa’);

delete from empregado

� Exemplos de uso do comando update:

update projeto

set plocalização = ‘Bellaire’, dnum = 5

where pnumero = 10;

update empregado

set salario = salario * 1,1

where dno in (select dnumero

from departamento

where dnome = ‘Pesquisa’);

Visões

� Na terminologia SQL, uma visão é uma tabela única, derivada de outra tabela, que pode ser uma tabela básica ou uma visão previamente definida.

� Uma visão não existe de forma física, ela é considerada uma tabela virtual, em contraste com as tabelas básicas, cujas tuplas são realmente armazenadas no BD.

� Isso limita as operações de atualização possíveis para as visões, embora não imponha nenhuma limitação para as consultas.

Visões

� Supõe-se que uma visão esteja sempre atualizada; se modificarmos as tuplas das tabelas básicas sobre as quais a visão foi construída, a visão deverá, automaticamente, refletir essas alterações.

� Conseqüentemente, a visão não é realizada no instante de sua definição, mas quando especificarmos uma consulta sobre ela.

� É responsabilidade do SGBD, e não do usuário, ter a certeza de que uma visão está atualizada.

� Se não precisarmos mais de uma visão poderemos usar o comando drop view:

drop view trabalha_em1;

Visão

� Materialização de visões: criar fisicamente uma tabela temporária a partir da primeira consulta a essa visão e mantê-la, considerando que poderão seguir-se outras consultas.

� Nesse caso, deve-se ter uma estratégia eficiente para a atualização da tabela da visão sempre que as tabelas básicas forem atualizadas, de modo a garantir que a visão esteja sempre atualizada.

Problemas de atualizações sobre Visões

Suponha que seja emitido um comando de atualização do atributo pjnome de ‘ProdutoX’ para ‘ProdutoY’, para o empregado ‘John Smith’.

update trabalha_em1set pjnome = ‘ProdutoY’where unome = ‘Smith’ and pnome ‘John’ and pjnome = ‘ProdutoX’;

Essa consulta pode ser mapeada em diversas atualizações das relações básicas para chegar ao efeito desejado pela atualização da visão.

...

(a)update trabalha_emset pno = (select pnumero

from projetowhere pjnome = ‘produtoY’)

where essn in (select ssnfrom empregadowhere unome = ‘Smith’ and pnome = ‘John’)

and

(select pnumerofrom projetowhere pjnome = ‘ProdutoX’ );

(b)update projeto set pnome = ‘ProdutoY’where pjnome = ‘ProdutoX’;

Obs: (a) e (b) podem produzir resultados diferentes... Provavelmente, o resultado de (a) será o mais adequado.

Problemas de atualizações sobre Visões

Visões� Em resumo:

� Uma visão de uma única tabela é atualizável se a visão contiver, entre seus atributos, a chave primária, bem como todos os atributos com restrição not null que não contiverem valores default especificados.

� As visões definidas a partir de diversas tabelas (utilizando-se de junções), em geral, não são atualizáveis.

� As visões definidas usando-se as funções de agrupamento e agregadas não são atualizáveis.

� Em SQL, a cláusula with check option precisa ser adicionada ao final da definição da visão se ela puder ser atualizada. Isso permite que o sistema cheque a capacidade de atualização da visão e planeje a estratégia de execução das atualizações das visões.

Asserções

� Permite a determinação de restrições genéricas sobre o banco de dados, via asserções declarativas, usando a declaração createassertion da DDL.

� Em uma asserção é dado um nome à restrição especificada por meio de uma condição semelhante à cláusula WHERE de um consulta SQL.

� Exemplo:� “O salário de um empregado não pode ser maior que o salário do gerente do departamento em que ele trabalha.”

Asserções

create assertion limite_saláriocheck (not exists

(select *from empregado as E, empregado as S, departamento Dwhere e.dno = d.numero andd.ssnger = s.ssn and e.salario >

s.salario));

Asserções� A restrição limite_salário é seguida da palavra-chave check, que é seguida da condição entre parênteses que precisa ser verdadeira em todos os estados do banco de dados para que a asserção seja satisfeita.

� O nome da restrição pode ser usado posteriormente para sua referência, modificação ou eliminação.

� O SGBD é responsável por garantir que a condição não seja violada.

� Sempre que alguma tupla no banco de dados fizer com que a condição ASSERTION evolua para FALSE, a restrição será violada.

� A técnica básica para a formulação de asserções é especificar uma consulta que selecione as tuplas que violem a condição desejada. Por meio da inclusão dessa consulta em uma cláusula NOT EXISTS, a asserção especificará que o resultado dessa consulta deverá ser vazio. Logo, a asserção será violada se o resultado da consulta não for vazio.

� As asserções devem ser utilizadas somente nos casos em que não for possível usar check em atributos, nos domínios e nas tuplas.

Triggrers (Gatilhos)

� Regras que especificam ações disparadas automaticamente por meio de certos eventos (modificações no banco de dados);

� Considerados um importante avanço para os sistemas de banco de dados.

� Embora haja definição padrão, cada SGBD define a sintaxe para os gatilhos. No PostgreSQL, por exemplo, os gatilhos executam procedimentos ou “funções sem retorno”. Já no Oracle, a especificação é bastante parecida com a SQL-99.

CREATE OR REPLACE FUNCTION idade(char)

RETURNS integer AS '

DECLARE

idade integer;

BEGIN

select (current_date - datanasc)/365 into idade from aluno where nome = $1;

RETURN idade;

END;

' LANGUAGE plpgsql;

Funções e Gatilhos no PostgreSQL

CREATE OR REPLACE FUNCTION media(char)

RETURNS numeric AS '

DECLARE

med numeric;

BEGIN

select avg(quantidade) into med from fornecimentowhere cod_fornec = $1;

RETURN med;

END;

' LANGUAGE plpgsql;

Funções e Gatilhos no PostgreSQL

CREATE OR REPLACE FUNCTION projetos.aumenta(numeric)returns numeric

AS $BODY$

BEGIN

update projetos.fornecimento set quantidade = quantidade + $1;

return null;

END; $BODY$

LANGUAGE 'plpgsql';

SELECT projetos.aumenta(2000);

Funções e Gatilhos no PostgreSQL

CREATE OR REPLACE FUNCTION backupfor() RETURNS trigger AS

$$

BEGIN

insert into bakfornec (SELECT * FROM FORNECEDOR);

RETURN NULL;

END;

$$

LANGUAGE plpgsql;

CREATE TRIGGER tbackup

AFTER DELETE ON fornecedor

FOR EACH ROW EXECUTE PROCEDURE backupfor();

O gatilho indicado é responsável por

executar a função que faz uma cópia das linhas

da tabela fornecedor para uma tabela auxiliar,

toda vez que uma exclusão é executada.

Funções e Gatilhos no PostgreSQL

Modelo generalizado para BD Ativos e Gatilhos Oracle

� Modelo: evento-condição-ação ou modelo ECA. Uma regra no modelo ECA tem três componentes:

� O evento (ou eventos) que ativa (ativam) a regra: esses eventos normalmente são operações de atualização de banco de dados aplicadas explicitamente. Porém, no modelo geral, eles poderiam também ser eventos temporais* ou outros tipos de eventos externos;

� A condição que determina se a ação da regra deve ser executada: uma vez ocorrido o evento, uma condição opcional pode ser avaliada. Se nenhuma condição for especificada, a ação será disparada peloevento. Se uma condição for especificada, primeiro ela será avaliada, e somente se seu resultado for verdadeiro a ação da regra será executada.

� A ação a ser executada que normalmente é uma sucessão de declarações SQL, mas também poderia ser uma transação de banco de dados ou um programa externo que será executado automaticamente.

* Exemplo: dê este comando diariamente as 5:30.

Exemplos

� Considere o seguinte esquema simplificado:

� Empregado (nome, ssn, salario, *dno, *supervisor_ssn)

� Considere que é permitido o valor null para dno, indicando que um empregado pode estar temporariamente sem departamento.

� Departamento (dnome, dno, total_sal, *gerente_ssn)

� Note que o atributo total_sal é derivado, e seu valor corresponde à soma de salários dos empregados locados naquele departamento em particular. A manutenção do valor correto de tal atributo pode ser tarefa de uma regra ativa.

Projetando a regra ativa

� Primeiro é necessário determinar os eventos que possam causar uma mudança no valor de total_sal, que podem ser do seguinte tipo:

1. Inserindo uma ou mais tuplas de novos empregados;

2. Mudando o salário de um ou mais empregados existentes;

3. Realocando um ou mais empregados entre os departamentos;

4. Excluindo uma ou mais tuplas de empregados.

Projetando a regra ativa

� Evento 1: será necessário apenas recalcular total_salse o empregado novo for imediatamente nomeado para um departamento - isto é, se o valor do atributo de dnopara a tupla do novo empregado não for null. Conseqüentemente, essa será a condição a ser checada.

� Uma condição semelhante poderia ser atribuída ao evento 2 e 4: determinar se o empregado cujo salário é alterado (ou que está sendo excluído) está alocado no departamento.

� Para o evento 3, sempre será executada uma ação que mantém o valor correto de total_sal, assim, nenhuma condição é necessária (a ação sempre será executada).

Projetando a regra ativa

� A ação para os eventos 1, 2 e 4 é atualizar o valor de total_sal automaticamente para que o departamento do empregado reflita as recentes inserções, atualizações e remoções de salário dos empregados .

� No caso do evento 3, é necessária uma ação dupla: uma para atualizar o total_sal do departamento antigo e outra para atualizar o total_sal do novo departamento.

Sintaxe (Oracle – PL/SQL)

<trigger> ::= create trigger <nome gatilho>(after | before) <eventos

ativadores> on <nome tabela>[ for each row ][ when <condição> ]<ações disparadas>

<eventos ativadores> ::= <evento ativador> {or <evento ativador>}<evento ativador> ::= insert | delete | update [of <nome coluna> {, <nome coluna>}]<ação disparada> ::= <bloco PL/SQL>

A especificação

R1 : create trigger totalsal1after insert on empregadofor each row

when (new.dno is not null)update departamentoset total_sal = total_sal + new.salariowhere dno = new.dno;

New: palavra chave usada para se referir à tuplaque foi inserida ou atualizada.

A especificação

R2 : create trigger totalsal2after update of salario on empregadofor each row

when (new.dno is not null)update departamentoset total_sal = total_sal + new.salario –

old.salariowhere dno = new.dno;

Old: palavra chave usada para se referir à tupla excluída ou à tupla antes de sua atualização.

A especificação

R3 : create trigger totalsal3

after update of dno on empregadofor each row

begin

update departamentoset total_sal = total_sal + new.salariowhere dno = new.dno;update departamentoset total_sal = total_sal - old.salariowhere dno = old.dno;end;

A especificação

R4 : create trigger totalsal4

after delete on empregado

for each row

when (old.dno is not null)

update departamento

set total_sal = total_sal – old.salario

where dno = old.dno;

A especificação

R5 : create trigger inform_supervisor1before insert or update of ssn, supervisor_ssn on

empregadofor each row

when

(new.salario > (select salario from empregadowhere ssn = new.supervisor_ssn))

inform_supervisor(new.supervisor_ssn, new.ssn)

Onde inform_supervisor é um procedimento externo previamente declarado.

PostgreSQL:Outras funcionalidades SQL

� Como já dito, cada SGBD pode implementar outras funcionalidades SQL, para além da SQL-padrão. No PostgreSQL, por exemplo, estão definidas algumas funções matemáticas, de manipulação de strings, data e hora e endereçamento de rede.

Referências Bibliográficas

� Sistemas de Banco de Dados. (Cap. 5) Abraham Silberchatz, Henry F.Korth e S. Sudarshan. 3ª Edição. Makron Books, 1999.

� Sistemas de Banco de Dados. (Cap. 8) Ramez Elsmari, 4ª Edição. Shamkant B. Navathe. Pearson Addison Wesley, 2005.

� Introdução a Banco de Dados (Apostila). (Cap. 8) Osvaldo Kotaro Takai, Isabel Cristina Italiano, João Eduardo Ferreira. DCC-IME-USP, 2005.

� A First Course in Database Systems. (Cap. 5) Jeffrey D. Ullman, Jennifer Widom. Prentice Hall, 1997.

� PostgreSQL: Funcionalidades Básicas. Monica T. T. Pereira. Minicurso CONGED 2007.

� Notas de Aula sobre Gatilhos no Oracle, Prof. Sarajane Marques Peres.