Restrições de Integridade Integridade Semântica - DIMAp
Restrições de Integridade Integridade Semântica - DIMAp
Restrições de Integridade Integridade Semântica - DIMAp
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Restrições</strong> <strong>de</strong> Integrida<strong>de</strong><br />
• Integrida<strong>de</strong> <strong>de</strong> dados<br />
– garantia <strong>de</strong> dados sempre corretos com<br />
relação ao domínio da aplicação<br />
– garantia <strong>de</strong> dados tolerantes a falhas e à ação<br />
<strong>de</strong> usuários maliciosos<br />
• Violações <strong>de</strong> integrida<strong>de</strong><br />
– falhas em transações<br />
– interferência entre transações<br />
– acessos não autorizados<br />
– valores incorretos na atualização <strong>de</strong> dados<br />
• exige controle <strong>de</strong> integrida<strong>de</strong> semântica<br />
Integrida<strong>de</strong> <strong>Semântica</strong><br />
• Controle <strong>de</strong> valores válidos para os dados<br />
– estados dos dados condizentes com os<br />
requisitos da aplicação<br />
– transições <strong>de</strong> estados corretas<br />
• O SGBD <strong>de</strong>ve controlar esta integrida<strong>de</strong><br />
– subsistema <strong>de</strong> integrida<strong>de</strong> semântica<br />
1
Subsistema <strong>de</strong> Integrida<strong>de</strong> <strong>Semântica</strong><br />
• Funções básicas<br />
– especificação <strong>de</strong> regras <strong>de</strong> integrida<strong>de</strong> (DDL)<br />
– monitoração das atualizações <strong>de</strong> dados<br />
– tratamento <strong>de</strong> violações <strong>de</strong> integrida<strong>de</strong><br />
ocasionadas por estas operações<br />
• Definição <strong>de</strong> uma Regra <strong>de</strong> Integrida<strong>de</strong> (RI)<br />
– para quais dados <strong>de</strong>ve-se verificar a regra<br />
– quando a regra <strong>de</strong>ve ser verificada<br />
– que ação <strong>de</strong>ve ser tomada<br />
• Garantia <strong>de</strong> in<strong>de</strong>pendência <strong>de</strong><br />
gerenciamento <strong>de</strong> integrida<strong>de</strong> <strong>de</strong> dados para<br />
as aplicações<br />
Classificação <strong>de</strong> RIs<br />
1. Quanto ao seu alcance<br />
– volume <strong>de</strong> dados investigado pela RI<br />
2. Quanto ao momento <strong>de</strong> verificação<br />
– imediato ou postergado<br />
3. RIs <strong>de</strong> transição <strong>de</strong> estado<br />
– verificação somente quando o dado muda<br />
4. RIs <strong>de</strong> ativação explícita<br />
– verificação in<strong>de</strong>pen<strong>de</strong>nte da ocorrência <strong>de</strong><br />
operações <strong>de</strong> atualização<br />
2
Classificação <strong>de</strong> RIs<br />
1. Quanto ao seu alcance<br />
1.1) Atinge um atributo <strong>de</strong> uma tabela<br />
Exemplos: dados <strong>de</strong> empregados<br />
a) salário > 0<br />
b) 16 Salário dos seus<br />
subordinados<br />
1.4) Atinge tuplas <strong>de</strong> tabelas diferentes<br />
Exemplos: a) RI Referencial<br />
b) Orçamento Departamento > = Soma<br />
salários pagos aos seus empregados<br />
3
Classificação <strong>de</strong> RIs<br />
2. Quanto ao momento <strong>de</strong> verificação<br />
2.1) Imediato<br />
– verificação feita no momento da ocorrência <strong>de</strong><br />
uma operação <strong>de</strong> atualização<br />
2.2) Postergado<br />
– verificação feita após o término da transação<br />
– executa rollback em caso <strong>de</strong> violação<br />
Exemplos:<br />
a) alteração <strong>de</strong> código dos <strong>de</strong>partamentos:<br />
d0,d1,d2,...,dn d1,d2,d3,...,dn+1<br />
b) alteração do salário <strong>de</strong> vários empregados e<br />
verificação do orçamento do <strong>de</strong>partamento<br />
Classificação <strong>de</strong> RIs<br />
3. RIs <strong>de</strong> transição <strong>de</strong> estado<br />
– analisa os valores novo e antigo do dado<br />
Exemplos: a) reajustes <strong>de</strong> salário não po<strong>de</strong>m diminuir o<br />
valor do salário do empregado<br />
b) solteiro casado divorciado<br />
viúvo<br />
4
Classificação <strong>de</strong> RIs<br />
4. RIs <strong>de</strong> ativação explícita<br />
Exemplo: tabela Empréstimos<br />
Empréstimos(código, nomeDevedor, valorTotal,<br />
valorParcela, DiaVencimento, NroParcelasAPagar)<br />
Evento: pagamento automático<br />
SE DataAtual.Dia = Empréstimos.DiaVencimento<br />
ENTÃO INÍCIO<br />
Empréstimos.ValorTotal ← Empréstimos.ValorTotal<br />
– Empréstimos.ValorParcela;<br />
Empréstimos.NroParcelasAPagar ←<br />
Empréstimos.NroParcelasAPagar – 1;<br />
FIM;<br />
RIs em SQL<br />
• RIs associadas à criação <strong>de</strong> tabelas<br />
– cláusula not null<br />
– cláusula unique<br />
– cláusula check<br />
– restrições <strong>de</strong> integrida<strong>de</strong> <strong>de</strong> entida<strong>de</strong> e referencial<br />
• Assertivas (Assertions): predicados que <strong>de</strong>vem ser<br />
sempre verda<strong>de</strong>iros (ativação automática)<br />
• Gatilhos (Triggers): disparo <strong>de</strong> ações vinculadas à<br />
execução <strong>de</strong> uma operação específica (ativação<br />
automática)<br />
• Procedimentos (Stored Procedures): po<strong>de</strong>m<br />
usadas para verificação <strong>de</strong> integrida<strong>de</strong> (ativação pela<br />
aplicação ou pelo usuário)<br />
5
RIs na Definição <strong>de</strong> Tabelas<br />
create table Empregados (<br />
codEmp integer,<br />
nome varchar(40)not null,<br />
RG numeric(10) not null unique,<br />
ida<strong>de</strong> integer check (ida<strong>de</strong> between 16 and 90),<br />
estadoCivil char(10) check (estado_civil in<br />
‘solteiro’, ‘casado’, ‘viuvo’, ‘<strong>de</strong>squitado’,<br />
‘divorciado’),<br />
salario numeric(8,2) check (salário > 0),<br />
tempoServiço integer,<br />
codGer integer,<br />
codDepto integer,<br />
...<br />
RIs na Definição <strong>de</strong> Tabelas<br />
...<br />
constraint EmpPk primary key (codEmp),<br />
constraint EmpCodg foreign key (codGer)<br />
references Empregados on update casca<strong>de</strong><br />
on <strong>de</strong>lete set null,<br />
constraint EmpDept foreign key (codDepto)<br />
references Departamentos on update casca<strong>de</strong><br />
on <strong>de</strong>lete no action,<br />
constraint Ida<strong>de</strong>TS check(tempoServico < ida<strong>de</strong>),<br />
constraint EmpGer check(codEmp < > codGer),<br />
constraint SalarioGerente<br />
check(salario < (select salario<br />
from Empregados e<br />
where e.codEmp = codGer))<br />
);<br />
6
RIs na Definição <strong>de</strong> Tabelas<br />
create table Departamentos (<br />
codDepto integer,<br />
nome varchar(20) check (nome in ‘Vendas’,<br />
‘Pessoal’, ‘Finanças’, ‘Administrativo’),<br />
andar integer check (andar between 1 and 10),<br />
orçamento numeric(20,2),<br />
constraint DeptPk primary key (codDepto),<br />
constraint ControleOrç<br />
check( orçamento > =<br />
(select sum(salário)<br />
from Empregados e<br />
where e.codDepto = codDepto))<br />
);<br />
Assertiva - Assertion<br />
• Declaração <strong>de</strong> predicado que <strong>de</strong>ve ser<br />
sempre verda<strong>de</strong>iro<br />
– não está vinculado a uma tabela específica<br />
• geralmente é uma RI que envolve várias tabelas<br />
– in<strong>de</strong>pen<strong>de</strong> da operação <strong>de</strong> atualização<br />
• Exemplo<br />
create assertion ControleDespesas<br />
check ( (select sum(ValorTotal)<br />
from Empréstimos) +<br />
(select sum(Orçamento)<br />
from Departamentos)<br />
Gatilho - Trigger<br />
• Execução automática <strong>de</strong> modificações no<br />
BD para garantia <strong>de</strong> integrida<strong>de</strong><br />
• Princípio <strong>de</strong> funcionamento<br />
– evento-[condição]-ação<br />
• Especificação <strong>de</strong> um trigger<br />
– evento que o dispara: comando atualização<br />
– condição (opcional): predicado<br />
– ação(ões) a realizar: comandos SQL ou<br />
execução <strong>de</strong> procedimentos (stored<br />
procedures)<br />
Exemplos <strong>de</strong> Gatilho<br />
a) create trigger EmpréstimoLiquidado<br />
after update on Empréstimos<br />
(<strong>de</strong>lete from Empréstimos<br />
where valorTotal = 0)<br />
b) create trigger SalárioInjusto<br />
after insert, update on Empregados<br />
if exists (select *<br />
from Empregados<br />
where estadoCivil = ´casado´<br />
and salário < 250.00)<br />
begin<br />
print ‘salário injusto para o estado civil!’<br />
exec CorrigeSalário<br />
end<br />
c) create trigger AumentoSalário<br />
before update on Empregados<br />
referencing NEW salário as SalárioNovo when<br />
salário > SalárioNovo<br />
(Rollback Transaction)<br />
8
Transação<br />
• Princípio do “tudo ou nada”<br />
• Útil para a garantia <strong>de</strong> algumas RIs<br />
• Exemplo<br />
– todo <strong>de</strong>partamento <strong>de</strong>ve ter pelo menos um<br />
empregado lotado nele<br />
begin transaction<br />
insert into Departamentos<br />
values(1,’Vendas’, ...); codDepto<br />
insert into Empregados<br />
values(1, ‘João’, ..., 1);<br />
commit transaction<br />
Procedimento – Stored Procedure<br />
• Conjunto <strong>de</strong> comandos SQL mantido no BD<br />
• Po<strong>de</strong> ser utilizado para controle <strong>de</strong> RI<br />
– execução a cargo da aplicação ou usuário<br />
• Exemplo<br />
– débitos diários <strong>de</strong> parcelas <strong>de</strong> empréstimos<br />
create procedure PagaEmpréstimo as<br />
update Empréstimos<br />
set ValorTotal = ValorTotal – ValorParcela,<br />
NroParcelas = NroParcelas – 1<br />
where DiaVencimento = day(getdate())<br />
• Chamada <strong>de</strong> um storedprocedure<br />
exec PagaEmpréstimo<br />
9
Suporte a RIs em SQL<br />
• RIs quanto ao alcance <strong>de</strong> dados<br />
– cláusula check; asserts e triggers<br />
• RIs quanto ao momento da verificação<br />
– imediato (<strong>de</strong>fault)<br />
– postergado (SQL padrão)<br />
set integrity for Departamentos off<br />
...<br />
set integrity for Departamentos immediate checked<br />
• RIs <strong>de</strong> transição <strong>de</strong> estado<br />
– triggers (com referência a valores novos/antigos)<br />
• RIs <strong>de</strong> ativação explícita<br />
– stored procedures<br />
RIs no SQL-Server<br />
• RIs <strong>de</strong> transição <strong>de</strong> estados<br />
– duas tabelas especiais mantidas pelo SGBD<br />
• inserted<br />
– mantém o novo valor <strong>de</strong> uma tupla atualizada ou uma nova<br />
tupla inserida no BD<br />
• <strong>de</strong>leted<br />
– mantém o valor antigo <strong>de</strong> uma tupla atualizada ou uma tupla<br />
excluída do BD<br />
– exemplo: salários sempre reajustados para mais!<br />
create trigger<br />
ReajustaSalario on<br />
empregados<br />
before update as<br />
referencing NEW salário<br />
as SalárioNovo when<br />
salário > SalárioNovo<br />
(Rollback Transaction)<br />
create trigger ReajustaSalario<br />
on empregados<br />
after update as<br />
if exists<br />
(select * from empregados e1 join<br />
<strong>de</strong>leted e2 on e1.codEmp =<br />
e2.codEmp and e2.salario ><br />
e1.salario) rollback transaction<br />
10
RIs no SQL-Server<br />
• Cláusula Check<br />
– não permite subconsultas<br />
– RIs que necessitam relacionar tuplas da mesma tabela ou<br />
<strong>de</strong> outras tabelas <strong>de</strong>vem ser implementadas através <strong>de</strong><br />
gatilhos<br />
– exemplo: salário do empregado <strong>de</strong>ve ser menor que o<br />
salário do gerente<br />
create table empregados<br />
(...<br />
check(salario <<br />
(select salario<br />
from Empregados e<br />
where e.codEmp = codGer)<br />
)<br />
create trigger SalarioGer<br />
on empregados<br />
after insert,update as<br />
if exists<br />
(select * from empregados e1 join<br />
inserted e2 on e1.codEmp =<br />
e2.codGer and e2.salario ><br />
e1.salario)<br />
rollback transaction<br />
RIs no SQL-Server<br />
• Assertivas<br />
– não são suportadas<br />
– estas RIs <strong>de</strong>vem ser implementadas através <strong>de</strong> gatilhos<br />
– exemplo: soma <strong>de</strong> orçamentos e empréstimos não po<strong>de</strong><br />
ultrapassar 50000000,00<br />
create assertion<br />
ControleDespesas<br />
check (<br />
(select sum(ValorTotal)<br />
from Empréstimos) +<br />
(select sum(Orçamento)<br />
from Departamentos)<br />
50000000.00<br />
rollback transaction<br />
drop table temp1<br />
drop table temp2<br />
Obs.: prever um trigger<br />
também para Departamentos<br />
11
RIs no SQL-Server<br />
• RIs Postergadas<br />
– não são suportadas<br />
– uma forma <strong>de</strong> tratamento po<strong>de</strong> ser <strong>de</strong>sabilitar a execução<br />
da RI, habilitá-la posteriormente e tratar a RI através <strong>de</strong><br />
uma stored procedure<br />
– exemplo: alteração dos salários <strong>de</strong> empregados e<br />
verificação posterior da RI do orçamento do <strong>de</strong>partamento<br />
begin transaction<br />
alter table Departamentos nocheck constraint ControleOrç<br />
update empregados<br />
set salario = salario + 100<br />
where tempoServico > 30<br />
alter table Departamentos check constraint ControleOrç<br />
if dbo.VerificaOrçamento() > 0 rollback transaction<br />
commit transaction<br />
12