Você está na página 1de 15

SISTEMAS DE BASES DE DADOS

FUNÇÕES, RESTRIÇÕES COMPLEXAS,


TRIGGER E CURSORES

Ussimane Muieva - 2020 Faculdade de Engenharia


Conteúdo
• Funcoes
• Restrições de Integridade Complexas
• Trigger ou desencadeadores
• Cursores
Funções definidas pelo utilizador
É possivel definir funções para logo serem utilizadas desde vários lugares como qualquer
função padrão ou predefinida.

❖Função de valor escalar

Vejamos um exemplo
Na seguinte função se obtem a media do salário de todos empregados

CREATE FUNCTION mediaSalario()


RETURNS decimal
AS
BEGIN
DECLARE @avg decimal
SELECT @avg = avg(Salario)
FROM Empregado
RETURN @avg
END
Execuão:
SELECT mediaSalario() AS media
Funções definidas pelo utilizador
❖Função de valor Tabela

Vejamos um exemplo
Na seguinte função se obtem a venda feita num determinado mês
CREATE FUNCTION vendaPorMes
(
@mes int
)
RETURNS TABLE
AS
RETURN
(
SELECT * FROM venda WHERE MONTH(venda.datavenda) = @mes
)

Execuão:
SELECT * FROM [dbo].[vendaPorMes] (11)
Funções definidas pelo utilizador
❖Função de valor Tabela (Múltipla declaração)
Nesta função declara-se uma variável do tipo TABLE com várias
colunas definidas. Os valores de retorno deverão ser introduzidas nesta tabela
CREATE FUNCTION resultado
(

)
RETURNS
@resultado TABLE
(
nrresultado int ,
valor int
)
AS
BEGIN
insert into @resultado(nrresultado,valor) values(1,1)
RETURN
END
Execuão:
SELECT * FROM resultado()
Restrições de Integridade Complexas (SQL-92)
❖Restricao sobre uma única tabela

Exemplo1:

Usando restricao de tabela para garantir que a idade de um trabalhador


esteja no intervalo de 21 `a 35

CREATE TABLE Trabalhador ( idtrab INTEGER,


nome CHAR(10),
idade INTEGER,
PRIMARY KEY (idtrab),
CHECK ( idade>=21 AND idade<=35))
Restrições de Integridade Complexas
❖Restrição sobre uma única tabela
Exemplo2:
Para impor a restrição que um chefe de departamento não pode ter faltas

CREATE TABLE falta ( data datetime,


idtraba int,
foreign key (idtraba) references Trabalhador,
PRIMARY KEY (data),
constraint naoDirector
CHECK (exists (select departamento.iddep from departamento where
departamento.chefe=falta.idtraba)
)
Restrições de Integridade Complexas
❖Restrição sobre uma única tabela
Exemplo3:
Para impor a restrição que um chefe de departamento não pode ter faltas
CREATE FUNCTION naoChefe(
@traba int
)
RETURNS VARCHAR(5)
AS
BEGIN
IF not EXISTS (select departamento.iddep from departamento where
departamento.chefe=@traba)
return 'True'
return 'False'
END
go

CREATE TABLE falta ( data datetime,


idtraba int,
foreign key (idtraba) references Trabalhador,
PRIMARY KEY (data),
constraint naoDirector
CHECK (dbo.naoChefe(idtraba)='true')
)
Restrições de Integridade Complexas
❖Restrição de Dominio

Um utilizador pode criar um domínio usando a instrução CREATE DOMAIN

CREATE DOMAIN idadeval int DEFAULT 21


CHECK (VALUE>=21 AND VALUE<=35)

Nota: Para SQL Server (versao 2008 ou menor) cria-se um tipo de dado definido pelo
utilizador ao contrario de dominio
Desencadenadores ou Triggers

• São tipos especiais de procedimentos armazenados que se


disparam ou executam automaticamente quando se produzem
determinados eventos.
• Sao invocados automaticamente pelo SGBD em resposta a certas
mudancas na base de dados que sao especificadas pelo
administrador da base de dados

Por exemplo
• Para manter as regras de integridade
• Para produzir a actualização e a eliminação em cascada.
• Para invocar determinada acção quando se produzem
modificações de dados ou notificar algo, etc.
Vejamos alguns exemplos

Exemplo1
Verificar que o número do departamento exista quando inserimos ou
actualizamos um empregado
Se utiliza FOR para indicar que se faz uma inserção ou actualização.

CREATE TRIGGER INSERIR_EMPREGADO


ON Empregado
FOR INSERT, UPDATE

AS
IF EXISTS (SELECT * FROM inserted
WHERE inserted.idDpto NOT IN ( SELECT idDpto FROM Departamento))
BEGIN
PRINT 'Nao existe o codigo do departamento'
ROLLBACK TRANSACTION
END
Vejamos alguns exemplos
Exemplo 2
Para eliminar um empregado e passar seus dados a uma tabela

CREATE TRIGGER Eliminar_Empregado


ON Empregado
FOR DELETE
AS
DECLARE @idEmp int
DECLARE @Nome CHAR(30)
DECLARE @Idade SMALLINT
DECLARE @Salario MONEY
IF @@ROWCOUNT = 0 RETURN
IF (SELECT COUNT(*) FROM deleted) > 1
BEGIN
PRINT 'So pode ser eliminado um empregado'
ROLLBACK TRANSACTION
RETURN
END
SELECT @idEmp = idEmp, @Nome = Nome, @Idade = Idade, @Salario =
Salario FROM deleted
INSERT INTO EmpregadoEliminado VALUES(@idEmp, @Idade, @Nome, @Salario)
RETURN
Exemplo 3
Ao eliminar um departamento, apenas se elimina os empregados
Se utiliza INSTEAD para indicar que no lugar de eliminar o
departamento se faz o que o trigger diz

CREATE TRIGGER ELIMINAR_DPTO


ON Dpto
INSTEAD OF DELETE
AS
DECLARE @idDpto int
SELECT @idDpto = IdDpto FROM Deleted
DELETE FROM Empregado WHERE Empregado.idDpto = @idDpto
GO
Uso de cursores
Exemplo 1

CREATE PROCEDURE MEDIA_SALARIO


AS
DECLARE @S Money, @P Money, @Salario Money
DECLARE C CURSOR SCROLL FOR SELECT Salario FROM Empregados
OPEN C
FETCH FIRST FROM C INTO @Salario
SET @S = 0
WHILE @@FETCH_STATUS = 0
BEGIN
SET @S = @S + @Salario
FETCH NEXT FROM C INTO @Salario
END
SET @P = @S / @@CURSOR_ROWS
SELECT @P, @S
CLOSE C
GO
Exemplo 2
No seguinte exemplo mostraremos como copiar dados de uma tabela
para outra

CREATE PROCEDURE COPIAR_EMPREGADOS


AS
DECLARE @idEmp int, @Nome char(30), @idad int, @Salario money, @idDpto int
DECLARE C CURSOR SCROLL FOR SELECT * FROM EMPREGADOS
OPEN C
DELETE FROM Copia_De_Empregados
FETCH FIRST FROM C INTO @idEmp, @Nome, @Idade, @Salario, @idDpto
WHILE (@@FETCH_STATUS = 0)
BEGIN
INSERT INTO Copia_De_Empreados Values(@idEmp, @Nome , @Idade, @Salario,
@idDpto)
FETCH NEXT FROM C INTO @idEmp, @Nome , @Idade, @Salario, @idDpto
END
CLOSE C
GO

Você também pode gostar