Escolar Documentos
Profissional Documentos
Cultura Documentos
GESTÃO DO SGBD
• “Segurança significa proteger os dados contra utilizadores não autorizados; integridade
significa proteger os dados contra utilizadores autorizados.” O significado de segurança,
torna-se mais evidente quando temos em atenção o conceito de ownership, isto é,
posse, de objectos. Tudo o que existe num SGBD é um objecto: a BD, os atributos (ex:
tabelas), os registos das tabelas.
• O conceito de Autenticação é a base para se definir a forma como se vai assegurar a
segurança dentro de um SGBD. Existem 2 métodos para se proceder à autenticação de
ligações:
o SQL Server Authentication, recorrendo às credenciais criadas dentro do SQL
Server ou às credenciais do Windows
o Windows Authentication, recorrendo à autenticação previamente efectuada no
sistema operativo com recurso à funcionalidade Kerberos (método preferencial).
Este inicia-se no momento que um utilizador ou serviço tentar aceder a um
domínio. Nesta fase da autenticação, o Kerbros assume que a rede não é segura e
que é possível a qualquer pessoa infiltrar a comunicação entre o servidor e o
cliente.
• Utilizadores:
o Built-In Users e System Roles – quando criamos uma instância do SQL Server, o
1º login que é criado é o System Administrator (SA). Todos os membros do grupo
Administrator são colocados por defeito no role Sysadmin, o qual concede aos seus
membros os mesmos privilégios que o SA
o DataBase Users – são os utilizadores que estão associados a cada login tendo de
ser definidos para cada uma das bases de dados. Resumindo Login permite
efectuar ligações ao Servidor Users, possibilitam a ligação às bases de dados e aos
seus objectos
o Guest Users – este é um utilizador que está predefinido no SQL Server quando
este é instalado, tendo automaticamente permissões à base de dados Master sem
ter no entanto capacidade de efectuar qualquer acção sobre os dados
• Roles:
o Public Roles – é adicionada a todas as BDs que criamos, sendo igualmente
adicionada às BDs de sistema. Sempre que um utilizador obtém permissões de
acesso a uma BD fica automaticamente atribuído a esta role
o Server Roles – estão predeterminadas na instalação do SQL Server e são
aplicadas ao nível do Servidor e não ao nível das Bases de Dados, permitindo aos
seus membros a gestão do servidor.
SysAdmin (faz tudo dentro do sistema), ServerAdmin (pode alterar as
configurações do servidor, iniciando-o e parando-o), SetupAdmin (gere os
servidores remotos e os procedimentos de arranque), SecurityAdmin
(gere os logins e lê os erros existentes nos logs de sistema), 2
ProcessAdmin (gere os processos existentes no servidor), dbCreator 3
(cria BDs), diskAdmin (gere os ficheiros no disco), bulkAdmin (invoca o
SELECT INTO e o TRUNCATE)
o Database Roles – roles predeterminadas que se aplicam às BDs. Existem 9 roles
deste género as quais permitem a realização de um conjunto de tarefas de
administração das BDs
Db_owner (efectua operações na BD), Db_accessadmin (adiciona/remove
users), Db_datareader (define possibilidades de efectuar SELECTs dentro
de uma BD), Db_datawriter (efectuar INSERT, DELETE, UPDATE),
Db_denydatareader (nega a capacidade de fazer SELECT),
Db_denydatawriter (nega INSERT, DELETE, UPDATE), Db_ddlAdmin (corre
instruções de uma DLL: create, drop, alter), Db_securityAdmin (gere roles
e permissões), Db_backupOperador (efectuar backups e restores)
o User Defined Application Roles – concede permissões para que estas possam
trabalhar com as BDs
o User Defined Standard Roles – cria o nosso conjunto de Roles, com as
permissões necessárias de forma a facilitar o acesso a cada uma das BDs
CRIAÇÃO DE BDS
• Podemos criar pelo modo gráfico ou por TSQL:
CREATE DATABASE Sales
ON
( NAME = Sales_Data,
FILENAME = ‘c:\sales.mdf’,
SIZE = 20MB,
MAXSIZE = 40MB,
FILEGROWTH = 5MB)
LOG ON
( NAME = Sales_Log,
FILENAME = ‘c:\sales.ldf’
SIZE = 10MB,
MAXSIZE = 20MB,
FILEGROWTH = 1MB )
• Alter Database – para alterar o tamanho de uma BD
ALTER DATABASE Sales
MODIFY FILE (NAME = Sales_Data, SIZE = 30MB)
• Drop – para apagar uma BD
DROP DATABASE Sales
• Os dados quando são armazenados numa BD relacional como o SQL Server, são
guardados numa tabela com 2 dimensões. As colunas e as linhas de uma tabela já são
familiares aos utilizadores de BDs. As tabelas foram escolhidas como a estrutura lógica
para o armazenamento, devido à sua facilidade de utilização, de acesso e de manipulação
dos dados. Pode criar tabelas através da instrução CREATE TABLE ou com o
Management Studio. A parte principal envolve a definição dos tipos de dados das colunas.
• Tipos de dados:
• Números: int ou interger, smallint, tinyint
• Vírgula flutuante (pode ser dados decimais): real, float, decimal, numeric
• Caracteres: char, varchar
• Dados especiais: bit, timestamp, binary
CREATE TABLE Niveis
(
IdNivel char(10) Primary Key Not Null,
[Designação] char(20) Not Null
)
• Só pode existir uma chave primária por tabela e os campos que fazem parte da PK não
podem ser NULLS. Maneiras de criar chaves primárias: ao nível da coluna (definindo
que campo é que é a PK) e ao nível da tabela (após a definição dos campos da tabela)
CREATE TABLE Exames
(
IdAluno char(10) not null,
IdNivel char(10) not null, 2
Data DateTime not null,
3
Nota Integer Not Null,
Localidade char(30) Null
Primary key (idaluno, idnivel, data)
)
• Ao nível das tabelas é possível alterar tabelas (adicionar, remover e alterar campos),
alterar o nome de uma tabela e eliminar uma tabela.
• Criar uma nova tabela na BD
Create Table Professores
(
IdProf char(4) Not Null,
Nome char(40) Not Null,
Morada char(30) Null
)
• Alterar tabela já existente (campos a adicionar não podem ser Not Null)
Alter Table Professores Add Sexo char(1) Null, Ordenado Integer Null
• Para apagar uso também o Alter Table mas em vez de Add uso Drop
Alter Table Professores Drop Column Ordenado
• Alterar o tamanho da coluna Sexo para char(10), uso o Alter Table seguido de Alter
Column
Alter Table Professores
Alter Column Sexo Char(10)
• Para alterar o nome da coluna uso o comando sp_rename:
EXEC sp_rename ‘Professores.Sexo’, ‘Sexos’
• Para alterar o nome de uma tabela, não se faz referência à coluna
EXEC sp_rename ‘Professores’, ‘Profs’
• Para eliminar uma tabela:
Drop Table Profs
INDEXES
• Principais razões para definir um index num campo: rapidez. Um index é constituído por
um conjunto de páginas: B+ tree. Opções para armazenamento físico dos indexes:
• Clustered – index que reordena fisicamente os dados. Apenas 1 index clustered
por tabela
CREATE clustered INDEX IX_Professor_ID ON Profs (idprof)
• Non-Clustered – igual ao B+ tree. Podemos definir até 249 index non-clustered
numa só tabela
CREATE NONclustered INDEX IX_Professor_PESQUISA ON Profs (nome, morada)
• Indexes Únicos – determinam se os valores duplicados são ou não permitidos no nosso
index
tabela)
MANIPULAÇÃO DE INFORMAÇÃO - II
• UPDATE – altera os dados existentes numa linha, o UPDATE só tem efeito sobre uma
única tabela
UPDATE Material
SET estado = ‘Disponível’
• Exemplo: adicionar um campo, na tabela cursos, que permita definir o custo de
cada um dos cursos existentes
Insert into cursos values
(‘C001’, ‘Curso1’, 100)
Go
Insert into cursos values
(‘C002’, ‘Curso2’, 120)
Go
Insert into cursos values
(‘C003’, ‘Curso3’, 200)
• Assumir que lhe solicitaram que aumentasse o valor dos cursos em 10%. Qual
seria a instrução que iria utilizar?
Update Cursos
Set custo = custo * 1.1
• Se desejarmos aumentar o ordenado dos funcionários existentes na tabela
FuncionariosNovos em 5% e ao mesmo tempo aumentar-lhes a categoria em uma
unidade, desde que o nome se inicie por Z, qual seria o código que teríamos que
escrever?
Update FuncionariosNovos
Set ordenado = ordenado * 1.05, codcat = codcat + 1
Where nome like ‘Z%’
• DELETE – remover uma ou mais linhas de uma tabela
DELETE authors
ou
DELETE FROM authors
WHERE au_lname = ‘McBadden’
• TRUNCATE TABLE – remove todas as linhas de uma tabela, é sempre mais rápido que o
DELETE, pois o DELETE efectua o log para cada alteração. Uma BD vazia com o Truncate
table ainda existe, é preciso o DROP TABLE. Não se pode usar numa tabela referenciada
por uma constraint do tipo FOREIGN KEY, para eliminar os dados é preciso a instrução
DELETE
TRUNCATE TABLE authors
• ORDER BY – alterar ordem dos registos. Default: ASC. DESC – descendente.
• Exemplo: ordena o resultado da query com base no campo localidade, mas
ascendentemente
SELECT *
FROM Exames
Order By localidade 2
• Ordenar descendentemente:
3
SELECT *
FROM Exames
Order By localidade desc
• Ordenar por mais do que um campo:
SELECT *
FROM Exames
Order By localidade,
IdAluno Desc
• DISTINCT – remove conjuntos repetidos.
• Alias – alterar nome de uma coluna mas que é apenas válida na execução do query
(colunas temporárias)
SELECT IdAluno, Nome As ‘Nome das Alunas’
FROM Alunoa
Where Sexo = ‘F’
• CAST – transforma um tipo de dados noutro (durante a execução do query). Como não se
pode concatenar dados do tipo char com dados numéricos
SELECT ‘O ordenado do Funcionario ‘ + idfunc +
‘é de ‘ + cast(ordenado as char(5)) as Listagem
FROM Funcionarios
2
3
MANIPULAÇÃO DE INFORMAÇÃO – III e JOINS
Funções de Descrição
Agregação
AVG Média dos valores Valor médio das
notas:
SELECT AVG(Nota)
From Exames
COUNT Nº de linhas
MAX Maior valor da
expressão
MIN Menor valor da
expressão
SUM Valor total da
expressão
• ROUND – arredondar ou eliminar valores decimais num nº. ROUND (expressão, tamanho,
[,função])
Select round(AVG(cast(Nota as float)), 2) as Media
From Exames
ROUND RESULTA
DO
ROUND(748.58, -1) 750.00
ROUND(748.58, -2) 700.00
ROUND(758.58, -2) 800.00
ROUND(748.68, 0, 1) 748
ROUND(748.58, 0, 0) 749
ROUND(150.75, 0) 151.00
• CONVERT – permite converter a informação em tipos de dados semelhantes. Semelhante
ao CAST mas este é ANSI e o convert é do TSQL
• Exemplo: determinar a maior nota dos exames que terminam em 5
Select max(nota) as media
From Exames
Where convert(char(2), nota) like ‘%5’
• @@ERROR – devolve o nº do último erro do TSQL que foi criado. É zero se não tiver
ocorrido nenhum erro.
UPDATE Employee
SET PayFrequency = 4
WHERE NationalIDNumber = 615389812;
IF @@ERROR = 547
PRINT ‘A check constraint violation occurred.’;
GO
• ISNULL – permite substituir um valor Null por outro valor
SELECT Description, DiscountPct, MinQty,
ISNULL(MaxQty, 0) AS ‘Max Quantity’
FROM SpecialOffer
• IS NULL – permite determinar se um valor de um campo é Null ou não (True: se
encontrar)
SELECT Name, Weight, Color
FROM Product
WHERE Weight < 10 OR Color IS NULL
ORDER BY Name
• JOIN – permite aceder aos dados de várias tabelas, o resultado é só uma tabela, com
várias colunas. A junção das tabelas é feita com o SELECT. Sempre que referenciarmos o
nome de uma coluna que aparece em ambas as tabelas, devemos utilizar:
nome_tabela.nome_coluna. INNER JOIN (por definição é este; incluir só as linhas que
satisfazem a condição do JOIN), CROSS JOIN (incluir todas as combinações de todas as
linhas entre as tabelas), OUTER JOIN (incluir as linhas que satisfaçam as condições do
JOIN e todas as linhas de uma das tabelas),
SELECT Nome, Nota
FROM Alunos Inner Join Exames
ON Alunos.IdAluno = Exames.IdAluno 2
3
• Para continuar com o exemplo, é necessário preencher a tabela níveis:
AGREGAÇÃO
• GROUP BY – organiza os dados em grupos, produzindo a
informação sumariada para grupos definidos na tabela
• HAVING – permite restringir as linhas que serão apresentadas no resultado
o A cláusula WHERE exclui linhas que não estão de acordo com as condições de
pesquisa. A cláusula GROUP BY recolhe as linhas que estão de acordo com a
WHERE e coloca essas linhas num grupo para cada valor único existente na
cláusula GROUP BY.
o A cláusula HAVING exclui os grupos criados na instrução anterior e que não
satisfaçam os requisitos definidos nesta instrução
• Se desejar saber o total que todos os alunos pagaram para frequentam os diferentes
cursos:
SELECT Sum(Custo)
FROM Cursos Join [Alunos-Cursos]
ON Cursos.IdCurso = [Alunos-Cursos].IdCurso
• O Custo total dos cursos frequentados por cada um dos alunos
SELECT Sum(Custo) As CustoTotal, IdAluno
FROM Cursos Join [Alunos-Cursos]
ON Cursos.IdCurso = [Alunos-Cursos].IdCurso
GROUP BY IdAluno
• O custo total dos cursos frequentados por cada um dos alunos, sendo que pretendo
visualizar somente os alunos que na totalidade pagaram mais do que 2500
SELECT Sum(Custo) As CustoTotal, IdAluno
FROM Cursos Join [Alunos-Cursos]
ON Cursos.IdCurso = [Alunos-Cursos].IdCurso
GROUP BY IdAluno
HAVING Sum(Custo) > 2500
• O custo total dos cursos frequentados por cada um dos alunos mas somente os que na
totalidade pagaram mais do que 2500, e cujo custo foi superior a 999
SELECT Sum(Custo) As CustoTotal, IdAluno
FROM Cursos Join [Alunos-Cursos]
ON Cursos.IdCurso = [Alunos-Cursos].IdCurso
WHERE Custo > 999
GROUP BY IdAluno
HAVING Sum(Custo) > 2500
• Para cada categoria dos funcionários pretendo saber quantos funcionários existem e
qual o vencimento médio por categoria. Só pretendo informação dos funcionários cujo
ordenado é superior a 950 e das categorias cujo ordenado médio é superior do que
1000
SELECT CodCat, Count(IDFunc) As TotalFuncionarios,
AVG(Ordenado) As MediaDosOrdenados
From Funcionarios
Where Ordenado > 950
Group By CodCat
Having AVG(Ordenado) > 1000
• Devolver os dois ordenados mais altos independentemente de serem iguais 2
3
SELECT Top 2 Ordenado
From Funcionarios
Order By Ordenado Desc
• TOP – pode ser usada com o SELECT, UPDATE, INSERT e DELETE e o valor do TOP pode
ser especificado em valores absolutos ou em percentagem.
o Devolver os dois ordenados mais altos retirando os repetidos sem utilizar a
cláusula distinct
SELECT Top 2 Ordenado
From Funcionarios
Group By ordenado
Order By Ordenado Desc
SUBQUERIES
• SubQueries – Quando as instruções de SELECT estão dentro de outras. Uma instrução de
SELECT com subquery pode efectuar o mesmo tipo de instrução que o JOIN. Os subqueries
são definidos entre parênteses e têm uma sintaxe mais restrita: as colunas do tipo Image
ou Text não podem ser incluídas, a cláusula DISTINCT não pode ser usada em subqueries
com o GROUP BY, não pode incluir ORDER BY, COMPUTE, nem INTO.
SELECT [Designação]
From Cursos
Where IdCurso =
(SELECT IdCurso From [Alunos-Cursos]
Where IdAluno = ‘A001’)
o Saber o IdAluno dos alunos que efectuaram exame de nível 1
SELECT Distinct IdAluno
From Exames
Where IdNivel =
(SELECT IdNivel
From niveis
Where [designação] = ‘Nivel 1’)
o Saber os id’s dos alunos que tiveram a melhor nota nos exames já
realizados desde sempre (sem distinção de nível):
SELECT Distinct IdAluno
From Exames
Where Nota =
(SELECT Max (Nota)
From Exames)
o Transformar este join de 3 tabelas num subquery + um join:
SELECT Nome, Nota
From (Alunos Join Exames)
On Alunos.IdAluno = Exames.IdAluno)
Join Niveis
On Niveis.IdNivel = Exames.IdNivel
o Seria:
SELECT Nome, Nota
From Alunos Join Exames
On Alunos.IdAluno = Exames.IdAluno
Where Exames.IdNivel In
(Select IdNivel
From Niveis)
o Transformar o join seguinte num subquery sem utilizar nenhum join:
SELECT Ac.IdAluno, [data-matricula]
From ([Alunos-Cursos] Ac Join Cursos C
On Ac.IdCurso = C.IdCurso) Join Alunos a
On a.IdAluno = Ac.IdAluno
o Seria:
SELECT IdAluno, [data-matricula]
From [Alunos-Cursos] Ac
Where Ac.IdCurso In
(Select IdCurso
From Cursos)
And
IdAluno In
(Select IdAluno
From Alunos)
o Pretende saber os Id’s dos alunos que tiveram melhor nota nos exames e
dos alunos que efectuaram exame em Lisboa
SELECT IdAluno
From Exames
Where Localidade = ‘Lisboa’ And Nota =
( Select Max(Nota)
From Exames )
o Ou então:
SELECT IdAluno 2
3
From Exames
Where Nota =
(Select Max(nota)
From Exames
Where Localidade = ‘Lisboa’ )
o Pretende saber os Id’s e o nome dos alunos que efectuaram exame em
Lisboa:
SELECT IdAluno.nome
From alunos
Where IdAluno = ANY
( Select IdAluno
From Exames
Where Localidade = ‘Lisboa’)
o Saber o nº de exames realizados, mas somente se já tiver existido uma
matrícula no curso C003. Dado que não existe nenhuma relação entre
exames e níveis, poderíamos utilizar o EXISTS:
SELECT COUNT(*) as ‘Numero Exames’
From Exames
Where exists
(Select *
From [Alunos-Cursos]
Where IdCurso = ‘C003’)
UNIONS e VIEWS
• UNION
• Efectuar uma listagem única com os nomes dos funcionários e dos alunos.
SELECT nome FROM alunos
UNION
SELECT nome FROM funcionarios
• Efectue uma listagem única com os nomes dos funcionários, dos alunos e o seu sexo.
(Caso não exista informação sobre o sexo, deve surgir o char ‘I’)
SELECT nome, isnull(sexo, ‘I’) as sexo
FROM alunos
UNION
SELECT nome, ‘I’
FROM funcionarios
ORDER BY nome
• INTERSECT
• Criar listagem com os nomes repetidos na tabela funcionários e na tabela Alunos sem
utilizar SubQueries
SELECT nome FROM alunos
INTERSECT
SELECT nome FROM funcionarios
• EXCEPT
• Criar listagem com os nomes dos alunos, mas sem incluir os nomes que também
existissem na tabela funcionários:
SELECT nome FROM alunos
EXCEPT
SELECT nome FROM funcionarios
• VIEWS – permitem a partição horizontal e vertical dos dados, de uma ou mais tabelas de
uma BD. A vertical está relacionada com os campos que compõem a view e a horizontal à
existência de uma cláusula de selecção.
o CreateView – tem duas opções: WITH CHECK OPTION (força que todas as
modificações de dados, efectuadas através da view utilizem o critério definido
dentro da instrução SELECT) e WITH ENCRYPTION (encripta a instrução CREATE
VIEW na tabela syscomments, não poderá ser visualizada por mais ninguém após a
definição da view).
o Não podem conter ORDER BY, COMPUTE ou COMPUTE BY na instrução SELECT.
Nem SELECT INTO.
o Definir uma view:
CREATE VIEW V_Func
As
SELECT nome, codcat
FROM funcionarios
o Para usar o resultado da view: 2
3
SELECT *
FROM V_Func
o Em alternativa:
CREATE VIEW Elearning
As
SELECT *
FROM sysobjects
WHERE Type = ‘u’
o Aceder ao conteúdo da view
SELECT *
FROM Elearning
o Criar uma view que liste os alunos que efectuaram dois exames com um intervalo
inferior a 30 dias.
CREATE VIEW dias
As
SELECT DISTINCT e.idaluno
FROM exames e JOIN exames x
ON e.idaluno = x.idaluno
WHERE datediff(day, e.data, x.data) > 30
• DATEDIFF – permite manipular os dados de colunas do tipo DateTime. Exige que sejam
passados 3 parâmetros, um referente ao intervalo em análise, um que indique a data
inicial e o outro a data final.
STORED PROCEDURES I
• São instruções pré-compiladas de SQL, são objectos extremamente rápidos
• Para criar o procedimento podemos usar PROCEDURE ou PROC e CREATE PROC, ALTER
PROC e DROP PROC
• Não podem ser utilizados numa SP: CREATE DEFAULT, CREATE PROCEDURE, CREATE
TRIGGER, CREATE RULE e CREATE VIEW
• Só se pode criar outros objectos na SP se os criarmos antes de os referenciar. Podemos
referenciar tabelas temporárias numa SP
• O tamanho máximo é de 128 MB e o nº máximo de variáveis locais está limitado à
memória disponível, o nº máximo de parâmetros é de 1024
• Tipos de SP:
o System – são criadas quando se procede à instalação do SQL Server e não podem
ser alteradas, fornecem informação sobre o sistema
o Local – são as SP escritas pelos programadores do SGBD
o Temporary – mesma função que as Local, mas o seu ciclo termina quando se
termina a ligação à BD
o Remote – existem em servidores remotos e podem ser referenciadas pelo servidor
nativo
o Extended – semelhantes às Local podendo no entanto referenciar funcionalidades
externas ao SQL Server
CREATE PROC sp_alunas
AS
SELECT nome
FROM alunos
WHERE sexo = ‘F’
• Para executar um procedimento: EXEC sp_alunas 2
3
• Para obter o texto que é utilizado com a instrução CREATE PROCEDURE, podemos usar o
SP_HELPTEXT
sp_helptext sp_alunas
• Podemos utilizar a stored procedure SP_DEPENDS para obter um relatório sobre um
objecto de que a sp depende:
sp_depends sp_alunas
• ALTER PROC: Para alterar uma sp
ALTER PROC sp_alunas
AS
SELECT *
FROM alunos
WHERE sexo = ‘F’ AND Morada = ‘Porto’
• DROP PROC: remover procedimento: DROP PROC sp_alunas
• Exemplo: criar um procedimento que devolva os nomes dos alunos que não
fizeram exame de nível 3
CREATE PROC N3
AS
SELECT DISTINCT nome
FROM alunos
WHERE IdAluno NOT IN
(SELECT IdAluno
FROM exames
WHERE IdNivel = ‘N003’)
• Criar um procedimento que liste os IdAluno dos alunos que podendo ter feito
exames de outro nível, só fizeram um de ‘N001’
CREATE PROC N1
AS
SELECT IdAluno
FROM exames
WHERE IdNivel = ‘N001’
GROUP BY IdAluno
HAVING COUNT (IdAluno) = 1
• Seleccionar os alunos que só fizeram exames de nível1
CREATE PROC Nivel1
AS
SELECT DISTINCT IdAluno
FROM Exames
WHERE IdAluno NOT IN
(SELECT IdAluno
FROM exames
WHERE IdNivel <> ‘N001’)
STORED PROCEDURES II
• Variáveis
CREATE PROC XPTO
@var1 int, @var2 char(4)
AS
SELECT *
FROM [TabelaX]
Where Campo1 = @var1 and campo2 = @var2
• Podemos passar os parâmetros por posição (EXEC XPTO 1, ‘ABC’) e por referência (EXEC
XPTO @var1 = 1, @var2 = ‘ABC’)
• Criar um procedimento que devolve o nome dos funcionários cujo ordenado é
superior a um determinado montante e que pertence a uma categoria X
CREATE PROC FuncMont
@vmontante int,
@vcod int
AS
SELECT nome
FROM funcionarios
WHERE CodCat = @vcod AND ordenado > @vmontante
• Para executar o código:
EXEC FuncMont 1000,2
2
3
• Criar um procedimento que devolve o nome dos alunos, o nível dos exames e a
respectiva nota, que determinado aluno (idaluno) obteve, desde que essa nota
seja superior a um valor X
CREATE PROC ExamesProc
@i_idaluno varchar(5),
@i_nota tinyint
AS
SELECT nome, nota, idnivel
FROM exames JOIN alunos
ON exames.idaluno = alunos.idaluno
WHERE exames.idaluno = @i_ialuno AND nota > @i_nota
• Para executar o código, uma destas opções:
EXEC examesproc ‘A002’, 89
EXEC examesproc @i_nota=89, @i_idaluno=’A002’
If @nt < 0 2
3
Begin
Rollback Transaction
Print ‘Valor do campo nota apenas pode ser positiva’
End
• Criar um trigger que verifique se determinado IdAluno existe na tabela Alunos, antes de
permitir a inserção/actualização na tabela Exames
CREATE TRIGGER TG4
ON exames
For insert, update
As
Declare @cont int
Select @cont = Count(Alunos.IDAluno)
From Alunos.Join Inserted
On Alunos.IdAluno = Inserted.IdAluno
If @cont < 1
Begin
Rollback Transaction
Print ‘Esse aluno não existe!”
End
TRIGGERS II
• Exemplo prático: criar tabela que contenha média de cada aluno:
SELECT IDALUNO, AVG(NOTA) AS MEDIA
INTO MEDIAS
FROM EXAMES
GROUP BY IDALUNO
• Criar um trigger para a tabela Exames que valide:
o Quando é efectuada uma inserção de nota de uma exame, actualize a informação
correspondente na tabela Medias ou insira um novo registo
o Quando é actualizada uma nota na tabela Exames, actualize a média do aluno na
tabela Medias
CREATE TRIGGER EXAMESTG
ON EXAMES
FOR INSERT.UPDATE
AS
DECLARE
@MIN_LVL INT, @IDALUNO CHAR(4),
@CONTADOR INT, @CONT1 INT
SELECT @IDALUNO = EXAMES.IDALUNO, @MIN_LVL=AVG(EXAMES.NOTA),
@CONTADOR=COUNT(EXAMES.IDALUNO)
FROM EXAMES JOIN INSERTED
ON EXAMES IDALUNO=INSERTED.IDALUNO
GROUP BY EXAMES.IDALUNO
IF @CONTADOR > 1
UPDATE MEDIAS SET MEDIA=@MIN_LVL
FROM MEDIAS JOIN INSERTED
ON EXAMES.IDALUNO=INSERTED.IDALUNO
ELSE
BEGIN
SELECT @COUNT1=COUNT(DELETED.IDALUNO)
FROM EXAMES JOIN INSERTED
ON EXAMES.IDALUNO = DELETED.IDALUNO
JOIN DELETED ON EXAMES.IDALUNO = INSERTED.IDALUNO
GROUP BY DELETED.IDALUNO
IF @COUNT1 = 1
UPDATE MEDIAS SET MEDIA = @MIN_LVL
FROM MEDIAS JOIN INSERTED
ON MEDIAS.IDALUNO = INSERTED.IDALUNO
ELSE
INSERT INTO MEDIAS VALUES (@IDALUNO, @MIN_LVL)
END
• Vantagens da utilização dos Triggers do tipo INSTEAD OF é a possibilidade de
trabalhararem com VIEWS
• Exemplo que actualiza 2 tabelas com base em informação existente numa view.
Adicionalmente são apresentadas as seguintes abordagens para tratar os erros:
2
3
o Entradas duplicadas na tabela Pessoas, são ignoradas e transformadas registadas
numa tabela de log, chamada PessoasDuplicadas
o Inserções duplicadas na tabela FuncionariosT, são transformadas num update,
utilizando a informação fornecida, sem que ocorra um erro de violação de chave
primária.
o Criar tabela Pessoas:
CREATE TABLE Pessoas
(
NSS char(11) PRIMARY KEY,
Nome varchar(100),
Morada varchar(100),
DataNascimento datetime
)
o Criar tabela FuncionariosT:
CREATE TABLE FuncionariosT
(
FuncionarioID ,int PRIMARY KEY,
NSS char(11) UNIQUE,
Departamento varchar(10),
Salario money
CONSTRAINT FKEmpPer FOREIGN KEY (SSN)
REFERENCES Pessoas (SSN)
)
o Criar uma view que liste todos os dados relevantes de uma pessoa:
CREATE VIEW V_Empregado AS
SELECT P.NSS, Nome, Morada
DataNascimento, FuncionarioID, Departamento, Salario
FROM Pessoas P, FuncionariosT F
WHERE P.NSS = F.NSS
o Para guardarmos as tentativas de inserção de nºs de segurança social duplicados,
iremos guardar informação da pessoa e do funcionário que tentou efectuar a
inserção:
CREATE TABLE PessoasDuplicadas
(
NSS char(11),
Nome varchar(100),
Morada varchar(100),
DataNascimento datetime,
InsertSNome char(100),
QuantoInserted datetime
)
FUNCTIONS
• A criação de funções é feita com recurso ao comando CREATE FUNCTION. Alteradas
com o ALTER FUNCTION e eliminadas com o DROP FUNCTION. As funções podem ser
encadeadas, o nº máximo de encadeamento são 32 níveis. Este tipo de função pode ser
de 2 tipos:
o Escalares – implica que exista uma clausula RETURNS que devolva um dos tipos
de dados escalares existentes.
o Tipo tabelas – é quando o RETURNS especifica a opção TABLE, dado retornarem o
tipo de dados Tabela, podendo ser inline ou multistatement
Multi-Statement Inline
o RETURNS define uma variável local para a o RETURNS contém somente a instrução
tabela que será devolvida pela função, TABLE. Não tem de definir o formato da
definindo igualmente o formato da tabela. O variavel de retorna, dado este depender da
ambito da variavel a ser devolvida cinge-se instrução SELECT que faz parte da clausula
ao âmbito da função RETURNS
As instruções TSQL existentes no corpo da Não existe nenhum corpo da função delimitada
função criam e inserem registos na tabela por BEGIN e END
que será definida na cláusula REUTNRS
Quando a instrução RETURN é executada, as A clausula RETURN contem uma simples
linhas inseridas nas variáveis são devolvidas instrução SELECT dentro de parênteses. O
dentro do formato tabular que a função resultado da execução do SELECT, cria a tabela
devolve. A instrução RETURNS não admite que será retornada pela função. Aplica-se as
nenhum argumento mesmas restrições a estes SELECT, que aos
que são utilizados em VIEWS
as
begin
insert @medias
on e.idaluno = a.idaluno
union
on e.idaluno = a.idaluno
group by idnivel
return
end
2
• A invocação desta função poderia ser SELECT curso, media from F_Notas (‘Pedro’)
3
• O resultado da execução do código seria:
Curs Médi
o a
Gera 88
l
N00 86
1
N00 90
3
N00 87
4
returns Table
as
return (
select ‘Geral’ as tipo, avg(cast(nota as decimal)) as media
from exames e join alunos a
on e.idaluno = a.idaluno
where a.nome = @NomeA
union
select idnivel, avg(cast(nota as decimal))
from exames e join alunos a
on e.idaluno = a.idaluno
where a.nome = @NomeA
group by idnivel
)
• A invocação desta função poderia ser SELECT * FROM F_Notas2(‘Pedro’)
EXAME EXEMPLO
• Apresentar o código necessário para criar uma tabela lojas com a seguinte esturutra:
o IdLojas Integer PK
o Nome char(40) PK
o CentroComercial char(20)
• A solução será:
CREATE TABLE Lojas
(
IdLoja Integer Not Null,
Nome char(40) not null,
CentroComercial Char(20) null
Primary Key (idloja, Nome)
)
• Apresentar o código necessário para criar uma View chamada VCC, que apresente
somente os campos Nome e CentroComercial da tabela Lojas:
CREATE VIEW VCC
As
SELECT Nome, CentroComercial
From Lojas
• Apresentar o código necessário para adicionar o campo Renda e o campo Piso à tabela
Lojas. Indique o tipo de dados mais indicado.
ALTER TABLE Lojas
ADD Renda Money Null,
Piso SmallInt Null
• Apresentar o código necessário para adicionar criar uma Stored Procedure que devolva
todas as lojas que pertencem a determinado CentroComercial. O utilizador da Stored
Procedure irá indicar somente a primeira letra do CentroComercial:
CREATE PROC SPCC
AS 2
DECLARE @letra2 char(2)
3
Set @letra2 = @letra + ‘%’
Select Nome
From Lojas
Where CentroComercial Like @letra2
2
3