Escolar Documentos
Profissional Documentos
Cultura Documentos
degas@uesc.br http://alvarodegas.cjb.net/
Programao em SGBD
Empregado(nominic, nomint, nomefim, idemp, empdtnasc, ender, empsexo, salario, idsuper, iddep) Departamento (nomedep, iddep, idchefe, dtinchef) Projeto (nomeproj, idproj, locproj, iddep) Dependente (idemp, depend, depsexo, depdtnasc, tipo) LocalDepto (iddep, locdep) TrabalhaEm (idemp, idproj, horas)
Chaves primrias
iddep
idproj: varia de 10 at 99
Chaves estrangeiras
idsuper e idchefe matrcula do supervisor do empregado e do chefe do departamento em Projeto: departamento controlador em Empregado: departamento de lotao
iddep
Estas restries s podem ser idemp: varia de 101 at 999 implementadas Automtico atravs de iddep programao Automtico idproj: varia de 10 at 99 de gatilhos Automtico (triggers), e usando chaves estrangeiras: idsuper e idchefe matrcula do supervisor estruturas do adicionais empregado e do chefe do departamento chamadas iddep em Projeto: departamento controlador sequncias (sequences) em Empregado: departamento de lotao chaves primrias:
Novos Scripts
newcreatetables.sql inserttables.sql
newaltertables.sql newconsultas.sql
Algumas consultas
Reformulando o BD Empresa
/i <nome_do_arquivo>
calcs c:/UESC/Ensino/bd1/bd_empresa/scripts/createdatabase.sql \i c:/UESC/Ensino/bd1/bd_empresa/scripts/newcreatedatabase.sql \i c:/UESC/Ensino/bd1/bd_empresa/scripts/droptables.sql \i c:/UESC/Ensino/bd1/bd_empresa/scripts/newcreatetables.sql \i c:/UESC/Ensino/bd1/bd_empresa/scripts/newinserttables.sql \i c:/UESC/Ensino/bd1/bd_empresa/scripts/newaltertables.sql \i c:/UESC/Ensino/bd1/bd_empresa/scripts/newconsultas.sql
Problemas adicionais
E sequencialmente
Sequencias (sequences)
NEXTVAL('nome_sequencia')
Incrementa a sequencia (usando seu incremento) Retorna o valor Recupera o ultimo valor gerado Altera o valor
CURRVAL('nome_sequencia')
SETVAL('nome_sequencia', valor)
Exemplo
SEQUENCE Empregado_idemp_seq; nextval('Empregado_idemp_seq'); nextval('Empregado_idemp_seq'); currval('Empregado_idemp_seq'); setval('Empregado_idemp_seq', 100); nextval('Empregado_idemp_seq'); * FROM Empregado_idemp_seq;
No BD_Empresa
idemp INTEGER NOT NULL PRIMARY KEY, iddep idproj SMALLINT NOT NULL PRIMARY KEY, INT NOT NULL PRIMARY KEY,
Criar as sequncias:
Ajustando
SELECT max(idemp) FROM empregado; SELECT max(iddep) FROM departamento; SELECT max(idproj) FROM projeto; SELECT setval('empregado_idemp_seq', 112); SELECT setval('departamento_iddep_seq', 5); SELECT setval('projeto_idproj_seq', 19);
Um gatilho, que dispara antes da incluso Este gatilho altera o valor da chave primria usando a sequencia correta
Procedimentos
Procedimentos
Porque usar?
Regras de negcio (acesso a dados) Camada de acesso a dados Encapsulamento (acoplamento baixo entre BD e Programas)
Procedimentos
Funes no PostGres
PostGres
http://pgdocptbr.sourceforge.net/pg80/
select soma(2,3);
CREATE or REPLACE FUNCTION SalarioTotal(INT) RETURNS FLOAT AS $$ SELECT SUM(salario) FROM Empregado WHERE iddep = $1; $$ LANGUAGE 'SQL'; select salariototal(3);
Language plpgSQL
Tratamento de Erros
Instruo SQL pode executar com sucesso ou no SGBD retorna uma mensagem (valor) Categorias de mensagens:
SQLERROR valores menores que zero SUCESS valor igual a zero NOT FOUND valor igual a 100 nenhum registro foi recuperado pela instruo SQL
Erros em plpgSQL
Nveis possveis:
DEBUG, LOG, INFO, NOTICE, WARNING e EXCEPTION RAISE EXCEPTION administra um erro que aborta a transao corrente
RAISE EXCEPTION
RAISE EXCEPTION
Suponha que o comando NEW ser mostrado INSERT INTO Dependente VALUES (113, 'Luana', junto com gatilhos
'F', '05-APR-1998', 'filha');
Desvio e Repetio
IF boolean-expression THEN statements [ ELSIF boolean-expression THEN statements [ ELSIF boolean-expression THEN statements ...]] [ ELSE statements ] END IF;
IF boolean-expression THEN result := 'zero'; statements ELSIF number > 0 THEN [ ELSIF boolean-expression THEN statements result := 'positive'; [ ELSIF boolean-expression THEN ELSIF number < 0 THEN statements result := 'negative'; ...]] ELSE [ ELSE statements ]-- number is null? result := 'NULL'; END IF;
END IF;
e Repetio WHILEDesvio amount_owed > 0 AND IF boolean-expression THEN > 0 LOOP gift_balance statements -- some computations here [ ELSIF boolean-expression THEN END LOOP; statements
[ ELSIF boolean-expression THEN statements WHILE NOT done LOOP ...]] -- some computations [ ELSE END LOOP; statements ] END IF;
here
FOR LOOP
FOR var IN [ REVERSE ] expression .. expression [ BY expression ] LOOP statements END LOOP;
FOR LOOP
FOR var IN [ REVERSE ] expression .. expression [ BY expression ] LOOP statements END LOOP;
FOR xfuno in 1..10 LOOP Pode repetir em de uma consulta (select) END LOOP; FOR target IN query LOOP
FOR LOOP
Para executar s uma repetio DECLARE RECORD; FOR var IN [ REVERSE ] expression .. expression ... BY expression ] LOOP FOR s in select distinct sal statements from empregado END LOOP; order by 1 LOOP Pode repetir em funo de uma consulta END LOOP; (select)
Gatilhos
Gatilhos
Mudar o estado de um objeto (tupla) Completar dados omissos / incorretos Verificar restries semnticas
Regras de Negcio
Disparando Gatilhos
INSERT, DELETE ou UPDATE BEFORE ou AFTER NEW - contm os valores da nova linha (record) OLD - contm os valores da linha antiga (record)
NEW.coluna / OLD.coluna
Um exemplo
A tabela departamento
nomedep iddep idchefe VARCHAR(15) NOT NULL UNIQUE, SERIAL INTEGER NOT NULL PRIMARY KEY, DEFAULT 101 NOT NULL,
dtinchef DATE );
Restries
idchefe chave estrangeira (de empregado) No pode haver salrio maior que o do chefe iddep deve ser gerado automaticamente
Criando restries
ALTER TABLE Departamento ADD CONSTRAINT departamento_idchefe_fkey FOREIGN KEY (idchefe) REFERENCES empregado (idemp);
Criando um gatilho
CREATE FUNCTION insDepto() RETURNS trigger AS $$ BEGIN IF (SELECT salario FROM Empregado WHERE idemp = NEW.idchefe) <= ANY (SELECT salario FROM Empregado WHERE iddep = NEW.iddep and idemp <> NEW.idchefe) THEN RAISE EXCEPTION 'No pode ter salario maior ou igual ao de %', NEW.idchefe; -- NO FAZ SENTIDO!!! ELSE NEW.dtinchef:= CURRENT_DATE; END IF; NEW.iddep := nextval('departamento_iddep_seq'); RETURN NEW; END; $$ LANGUAGE plpgsql;
Criando um gatilho
CREATE TRIGGER tbiDepartamento BEFORE INSERT ON Departamento FOR EACH ROW EXECUTE PROCEDURE insDepto(); Testando insert into Departamento values ('Producao', 3, 104, '03-MAR-2008'); insert into Departamento values ('Promocao', 3, 104, '03-MAR-2008'); insert into Departamento(nomedep) values ('Procissao');
Mais gatilhos
Restries
Um dependente que seja filho(s) tem que ter menos de 14 anos Um departamento pode ficar em no mximo trs locais diferentes Um projeto no pode ter mais do que 100 horas no total No se pode mudar um empregado ligado a um projeto (h que exclu-lo de um e inclu-lo em outro) No se pode mudar o ID de departamentos ou de empregados Funcionrios no podem ganhar mais que seus chefes
Um projeto no pode ter mais do que 100 horas no total/ No se pode mudar um empregado ligado a um projeto (h que exclu-lo de um e inclu-lo em outro)
CREATE FUNCTION updTrabalhaEm() RETURNS trigger AS $$ BEGIN IF (SELECT SUM(horas)+ NEW.horas-OLD.horas FROM TrabalhaEm WHERE idproj = NEW.idproj) > 100 THEN RAISE EXCEPTION 'Atualizacao nao permitida: Excede maximo de horas'; END IF; IF (NEW.idemp <> OLD.idemp OR NEW.idproj <> OLD.idproj) THEN RAISE EXCEPTION 'Ids no podem ser modificados! Rever operao!'; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;
No se pode mudar o ID de departamentos ou de empregados / funcionrios no podem ganhar mais que seus chefes
CREATE FUNCTION updDepto() RETURNS trigger AS $$ BEGIN IF (SELECT salario FROM Empregado WHERE idemp = NEW.idchefe)<= ANY (SELECT salario FROM Empregado WHERE iddep = NEW.iddep and idemp <> NEW.idchefe) THEN RAISE EXCEPTION 'Tem chefiado com salario maior ou igual ao de %', NEW.idchefe; ELSE NEW.dtinchef:= CURRENT_DATE; END IF; IF (NEW.nomedep <> OLD.nomedep OR NEW.iddep <> OLD.iddep) THEN RAISE EXCEPTION 'Nome ou Id no podem ser modificados! Rever operao!'; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;
Programao em SGBD
"A verso orientada a objeto do 'cdigo espaguete' o 'cdigo lasanha' - camadas em excesso " Roberto Waltman