Você está na página 1de 25

SGBD – fotocópias dos powerpoints

INTRODUÇÃO AO SQL SERVER 2005


• O primeiro ponto que deve ser referido, é que o SQL SERVER é muito mais do que um
conjunto de bases de dados.
• Conforme iremos comprovar, ele incorpora um conjunto de funcionalidades, facilidades e
de serviços que estão muito além da pura armazenagem de dados.
• No entanto, o primeiro ponto que podemos apresentar passa pela descrição dos tipos de
base de dados existentes:
o De sistema
o Definidas pelo utilizador
• O primeiro tipo de base de dados é criado automaticamente quando se cria a base de
dados e serve de suporte ao funcionamento do SGBD como um todo
• O segundo tipo destina-se às bases de dados criadas pelos utilizadores, e servem para
armazenar a solução de dados de suporte às aplicações empresariais que são
implementadas.
• As bases de dados d sistema são as seguintes:
1. Master
• Utilizada para guardar a informação sobre o que se passa no sistema
• Guarda igualmente informação sobre as outras BDs existentes no sistema,
espaço em disco disponível e espaço utilizado
• Configurações de sistema são igualmente guardadas aqui, no entanto, ao
contrário de outras edições do SQL Server, os objectos de sistema não são aqui
guardados
2. MSDB
• Utilizada pelos Serviço Server Notification e pelo Serviço Server Agent, os quais
são utilizados para efectuarem tarefas predeterminadas no tempo, como sejam
backups de BDs e transformação e importação de dados
3. Model
• Serve de modelo a todas as novas BD que vierem a ser criadas
• Se necessitar de repetir alguma configuração em todas as BDs, deve fazê-lo
aqui
4. Tempdb
• Armazena todos os dados temporários necessários ao correcto funcionamento
do SQL Server
• A informação não fica armazenada permanentemente, dado que é recriada
sempre que se reiniciar o serviço do SQL Server
5. MsSqlSystemResource
• Não surge no Object Explorer e não é possível efectuar backups ou restores.
Esta base de dados é read-only e contém todos os objectos de sistema que são
criados quando o SQL server é instalado.
• As bases de dados criadas pelos utilizadores para servirem de repositório de informação
às aplicações, chamam-se user databases.
• Cada uma destas bases de dados contém pelo menos os seguintes ficheiros:
o Primary data file, os quais normalmente têm a extensão mdf, e que servem para
guardar os dados
o Log files, os quais guardam a informação sobre as transacções existentes em
cada base de dados, possibilitando a recuperação da informação.
• Eventualmente podem existir outros ficheiros para armazenar os dados da BD. Esses tipos
de ficheiros têm o nome de secondary data files e são nomeados com a extensão .ndf
• O Transation Log, guarda a informação sobre as transacções que ocorrem numa base de
dados. O SQL Server assegura que nenhum dado é escrito na base de dados sem antes
ser escrito no Log.
• O conceito de Transacção pode ser o seguinte:
o Todos os comandos dentro do mesmo bloco iniciam-se com sucesso e terminam
com sucesso.
o Quando ocorre alguma falha, desfaz tudo o que foi feito (Rollback), dentro do 2
mesmo bloco.
3
o Faz Commit quando passa as operações para os dados, ou seja, escreve no Data
File, isto quer dizer que altera fisicamente os dados.
• Se ocorrer uma falha no sistema a meio, os dados ficam inconsistentes. Quando o sistema
voltar, o Log File verifica o estado e desfaz todas as operações da transacção, colocando
os dados de forma a ficarem consistentes.
• O Log serve ainda quando associado a cópias de segurança, permite recolocar o sistema
para além dos últimos backups, sendo feito um backup do Log e não dos ficheiros, pois
estes são bem mais pesados que o ficheiro de Log. Então o backup é constantemente
feito ao Log File.
• A arquitectura de armazenamento de dados no SQL Server 2005 está ligada a dois
conceitos principais: Pages e Extents.
o Pages são o elemento fundamental de armazenamento de informação. Cada
página tem 8kb, sendo que o SQL consegue armazenar 128 páginas num
megabyte.
o Se o tipo de dados for superior a este limite (text, image, …) são armazenados em
tipos de páginas específicos, chamadas Pages Text/Image.
o Os extents são utilizados para armazenar o espaço necessário para as tabelas e
os indexes.
o Cada extent contém até 8 páginas contíguas, o que significa que cada extent pode
ter até 64 kb.
• O SQL Server 2005 está dividido em 4 grandes componentes:
o O Relation Engine, o qual contém um conjunto de módulos que interagem uns
com os outros de forma a interpretarem o código T-SQL e comandos XML.
o Os comandos dos clientes serão recebidos através dos eventos criados pela Net-
libraries, sendo verificado o código SQL, compilados e criados planos de execução,
os quais são enviados para o Storage Engine, o qual por sua vez devolve a
informação numa forma tabular, sendo esta informação devolvida para os clientes
das Net-libraries.
o O Storage Engine, é um conjunto de componentes que é responsável pela gestão
da base de dados e o espaço disponível dentro de cada ficheiro. É igualmente
responsável pela escrita no Log e pela recuperação da Base de Dados.
o Transaction Architecture, existem dois tipos de transacções: as locais, criadas
quando se invoca um comando Update, Delete ou Insert e as remotas, quando
temos informação de várias fontes.
o Gestão de concorrência e de transacções, é um sistema de algoritmos e
métodos que permitem que vários utilizadores utilizem a informação em
simultâneo sem ocorrerem problemas, nomeadamente “dirty reads”.
• Os serviços do SQL Server 2005 são os seguintes:
o Database Engine, implementado sobre o serviço MSSQLServer
o SQL Server Agent, implementado sobre o serviço SQLServerAgent
o Full-text Search, implementado sobre o SQLServer FullText
o Microsoft Distributed Transaction Coordinator, implementado sobre o serviço
Distributed Transaction Coordinator.
• As principais ferramentas disponíveis no SQL Server são:
o SQL Server Management Studio, permite-nos desenvolver um conjunto de
tarefas administrativas, como seja a adição de servidores, gerir os utilizadores,
criar e gerir bases de dados, tabelas, … Possui igualmente uma ferramenta de
query que nos permite trabalhar com os dados existentes no SGBD.
o Import/Export Wizard, pode ser iniciada dentro do Management Studio, que
permite importar ou exportar dados de e para Bases de Dados ODBC ou OLE DB.
• O componente core da automatização das tarefas administrativas é o SQL Server Agent
• É executado num layer separado sendo responsável pelos Jobs e Alertas associados às
referidas tarefas
• Um Job é a parte central das tarefas executadas pelo Agent. Cada Job é composto por
uma ou várias tarefas encadeadas 2
3
• Cada passo pode ser um conjunto de instruções TSQL, um comando do Sistema
Operativo, ou um script de VB ou C#
• O Agent pode executar os Jobs num horário predefinido, sem a necessidade de
qualquer intervenção humana
• É igualmente responsável pelo registo de todos os eventos significativos que ocorrem
no servidor
• O Agent compara os eventos existentes no Application Log, com os alertas que foram
definidos
Existem 3 estados possíveis para os serviços do SQL Server:
• Running, indica que o serviço está a funcionar correctamente
• Paused, indica que o serviço está num estado que vai permitir aos utilizadores ligados
terminem as suas tarefas, não possibilitando no entanto que sejam efectuadas novas
ligações ao servidor.
• Stopped, serviço está parado, ou por não ter sido iniciado ou porque teve um erro
durante a sua utilização

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

BACKUP & RESTORE


• Opções para efectuar cópias de segurança dos dados:
• Full database Backups – é feita uma cópia integral dos objectos da BD. Todas as
transacções concluídas mas ainda no log são escritas para disco e copiadas. As
que se iniciarem depois do início do backup não serão copiadas.
• Backups de Transaction Log – a única forma de garantirmos que recuperamos
até à ocorrência de um desastre é fazermos cópia de segurança do log. Para
recuperar informação deve-se repor um full backup e depois aplicar o log.
• Differential DataBase Backups – guarda somente as partes dos dados que se
alteraram após o último backup
• File Group Backups – efectua cópias de segurança dos ficheiros que suportam a
BD
• SnapShot Backup – possibilita a realização de uma cópia quase instantânea dos
dados e dos logs
• Operações de backup & restore:
• USE master – device local
EXEC sp_addumpdevice ‘disk’, ‘mydiskdump’, ‘c:\dump\dump1.bak’;
• USE master – device remoto 2
EXEC sp_addumpdevice ‘disk’
3
‘networkdevice’, ‘\\<servername>\sharename>\<path>\<filename>.bak’;
• USE master – tape device
sp_addumpdevice ‘tape’, ‘tapedump1’, ‘\\.\tape0’;
• Criar o dump device
EXEC sp_addumpdevice ‘disk’, ‘AdvWorksData’, ‘C:\Program Files\Microsof SQL
Server\MSSQL.1\MSSQL\BACKUP\AdvWorksData.bak’;
• Efectuar o backup total da BD
BACKUP DATABASE AdventureWorks TO AdvWorksData
• Criar o dump device para o log
EXEC sp_addumpdevice ‘disk’, ‘AdvWorksLog’, ‘C:\Program Files\Microsoft SQL
Server\MSSQL.1\MSSQL\BACKUP\AdvWorksLog.bak’
• Efectuar o back do log
BACKUP LOG AdventuresWorks TO AdvWorksLog – é necessário activar o full backup mode
• Restore de uma BD
RESTORE DATABASE MyAdvWorks FROM MyAdvWorks_1
• Restore de um backup completo seguido de um backup diferencial
RESTORE DATABASE MyAdvWorks FROM MyAdvWorks_1
WITH NORECOVERY
• essencial sempre que existem restores subsequentes. Não tenta
recuperar transacções que tenham ficado instáveis

RESTORE DATABASE MyAdvWorks FROM MyAdvWorks_1


WITH FILE = 2
• indica que vai utilizar o 2º ficheiro de backup set do dump device

INTEGRIDADE DOS DADOS


• Consistência dos dados armazenados numa BD. Diferentes tipos de integridade:
• Entity Integrity – requer que todas as linhas de uma tabela possuam um identificador
único, o valor da PK
• Domain Integrity – especifica um conjunto de valores que são válidos para essa coluna e
determina se são permitidos NULLs
• Referencial Integrity – assegura que os relacionamentos entre as chaves primárias e as
chaves estrangeiras são sempre mantidas
• Identity – pode ser usada para criar colunas que contem valores gerados pelo sistema, os
quais identificam cada linha que é inserida na tabela. Pode ser definida para qualquer
coluna em qualquer sequência. Não pode ser actualizada, não permite NULLS e deve ser
usada com integer, decimal ou numeric
IDENTITY[(seed, increment)] – seed: valor inicial
• Exemplo:
CREATE TABLE formação
(
Exemplo INT IDENTITY (100,5)
)
• Defaults – criam objectos que são ligados a uma coluna ou a um tipo de dados definido
pelo user. Um default especifica um valor que será inserido numa coluna, a que o objecto
está ligado, caso não seja indicado nenhum valor.
CREATE DEFAULT phonedfit AS ‘desconhecido’
Sp_bindefault ‘phonedfit’ – ligar default a uma ou várias colunas
‘Empregados.Contactos.Telefone’
• Use um default em vez de uma constraint quando o default for utilizado várias
vezes em múltiplas colunas. Se especificar NOT NULL para uma coluna e não
especificar um default para essa coluna, vai dar erro sempre que tentar inserir
uma nova linha e não especificar valor para coluna. Pode receber 2 valores (0:
sucesso, 1: falha) quando efectuar ligação de um default a uma coluna.
• Constraints – regras aplicacionais que o SQL Server assegura que serão mantidas.
Limitam os valores possíveis que os users podem introduzir numa coluna. Podem ser
alteradas, adicionadas ou eliminadas com o ALTER TABLE. Podem ser aplicadas ao nível
da coluna ou da tabela.
ALTER TABLE [database.[owner.]]table_name 2
[WITH {CHECK | NOCHECK}]
3
{{CHECK | NOCHECK} CONSTRAINT {constraint_name | ALL}
|
[ADD
{col_name column_properties[column_constraints]
| [[, ] table_constraint]}
[, {next_col_name | next_table_constraint}]...]
|
[DROP CONSTRAINT]
constraint_name [, constraint_name2]...]}
• Por defeito quando as constraints são definidas numa tabela que contenha dados,
estes serão verificados automaticamente para verificar se estão de acordo com as
definições da constraint. Para eliminar esta verificação, devemos adicionar a opção
WITH NOCHECK, na instrução ALTER TABLE. A opção WITH NOCHECK não pode ser
aplicada às constraints do tipo PRIMARY KEY, UNIQUE e DEFAULT, mas permite que
nas constraints do tipo FOREIGN KEY e CHECK não se verifique os dados já
existentes, quando a constraint é adicionada à tabela. Antes de efectuar qualquer
operação devemos verificar se a constraint está activa (sp_help), depois fazemos
ALTER TABLE com uma cláusula de CHECK ou com CHECK ALL. Exemplos:
• Desliga a constraint ssn_constraint da tabela authors
ALTER TABLE authors
NOCHECK CONSTRAINT ssn_constraint
• Liga a constraint desliga anteriormente
ALTER TABLE authors
CHECK CONSTRAINT ssn_constraint
• Liga todas as constraints existentes na tabela authors
ALTER TABLE authors
CHECK CONSTRAINT ALL
• O SQL Server tem as seguintes constraints:
Constraint Outras implementações
1. PRIMARY KEY CREATE UNIQUE CLUSTERED índex (numa coluna que não permita
NULLs)
2. UNIQUE CREATE UNIQUE NONCLUSTERED índex (numa coluna que não permita
NULLs)
3. FOREIGN KEY CREATE trigger ou stored procedure
4. DEFAULT CREATE default
5. CHECK(nível da CREATE trigger ou stored procedure

tabela)

• PRIMARY KEY – a PK é uma coluna ou combinação de colunas que identifica


univocamente uma linha. Quanto a esta constraint pode ser criada ao nível da tabela
ou da coluna; é assegurada com a criação de um índex UNIQUE, nas colunas
especificadas; por defeito cria um índex clustered a não ser que já exista um; só pode
ser definida com base em campos que não permitam NULLS, só pode ser uma PK por
tabela, o WITH NOCHECK não impede a verificação dos dados existentes
ALTER TABLE authors
ADD CONSTRAINT au_ident
PRIMARY KEY (au_lname, au_fname, address)
• UNIQUE – especifica que duas linhas não podem ter o mesmo valor.
Adiciona uma constraint unique a uma tabela
ALTER TABLE authors
ADD CONSTRAINT UN_Csk
UNIQUE (au_lname, au_fname)
Adiciona uma nova coluna definindo automaticamente uma constraint
para essa coluna do tipo UNIQUE
ALTER TABLE doc_exc ADD column_b VARCHAR(20) NULL
CONSTRAINT exb_unique UNIQUE
• FOREIGN KEY – define uma referência a uma outra coluna existente noutra tabela
ALTER TABLE titles
ADD
CONSTRAINT FK_pub_id
FOREIGN KEY (pub_id) REFERENCES
Publishers(pub_id)
2
3
• DEFAULT – permite definir tabela a tabela, para cada um dos campos, o valor de
defeito em caso de falha na indicação do valor do campo. Não podemos utilizar em
tipos de dados timestamp, com a propriade IDENTITY ou que já tenham um DEFAULT
ou um objecto default
ALTER TABLE doc_exz
ADD CONSTRAINT col_b_def
DEFAULT 50 FOR column_b
• CHECK – determina os tipos de dados que podem ser utilizados numa coluna
ALTER TABLE authors
ADD
CONSTRAINT CK_zip CHECK (zip LIKE ‘[1-9][0-9][0-9][0-9]’)
• Alias Types – são igualmente uma forma de assegurar a integridade da informação,
nomeadamente do domínio.
• Para criar um tipo de dados:
Create Type dbo.telefone
From varchar(10) not Null
• Ou:
Create Table TelefoneClientes
(telefoneC telephone null)

INSERIR E MANIPULAR INFORMAÇÃO - I


• INSERT – permite inserir dados numa tabela
Insert Into Nome_da_tabela
(Nome_das_Colunas)
Values
(Valores_a_Atribuir_a_cada_coluna)
• Para inserir um registo na tabela funcionários:
Insert Into Funcionarios
Values (‘XPTO’, ‘Alvaro’, 2000, 1)
• Se o 3º campo (ordenado) admitisse NULLs e não o quisesses especificar:
Insert Into Funcionarios
(IDFunc, Nome, Categoria)
Values (‘XPTO’, ‘Alvaro’ 1)
• As instruções são separadas pela instrução GO
Insert Into Funcionarios
Values (‘XPTO’, ‘Al1’, 2001, 2)
Go
Values (‘XPTO’, ‘Al2’, 2002, 3)
• Para seguirmos com o nosso exemplo é necessário criar a coluna Sexo char(1) e adicionar
registos à tabela alunos. Para criar a coluna:
Alter Table Alunos Add Sexo
Char(1) Null
• E inserimos os registos:
Insert Into Alunos A001 João 1978-07-11 M
Values ('A001’, 'João’, '1978-07-11’, 'M’) A002 Pedro 1982-05-19 M
Go A003 Filipa 1980-10-12 F
Insert Into Alunos A004 Ana 1980-10-07 F
Values ('A002’, 'Pedro’, '1982-06-19’, 'M’) A005 Carlos 1983-05-11 M
Go A006 Matos 1982-06-12 M
Insert Into Alunos A007 Patos 1981-11-07 M
Values ('A003’, 'Filipa’, '1980-10-12’, 'F’)
A008 Zatos 1980-05-20 M
Go
Insert Into Alunos
Values ('A004’, 'Ana’, '1980-10-07’, 'F’)
Go
Insert Into Alunos
Values ('A005’, 'Carlos’, '1983-05-11’, 'M’)
Go
Insert Into Alunos
Values ('A006’, 'Matos’, '1982-06-12’, 'M’)
Go
Insert Into Alunos
Values ('A007’, 'Patos’, '1981-11-07’, 'M’)
Go
Insert Into Alunos
Values ('A008’, 'Zatos’, '1980-06-20', 'M')
• Agora é necessário criar a tabela Funcionários na BD e efectuar o preenchimento das
respectivas colunas 2
Create Table Funcionarios
3
(
IdFunc Char(4) Primary Key Not Null,
Nome Char(30) Not Null,
Ordenado Int,
CodCat Int
)
• Os registos:
Insert Into Funcionarios Values (‘F001’, ‘Maria’, 2000, 1)
Go
Insert Into Funcionarios Values (‘F002’, ‘Manuel’, 2500, 1)
Go
Insert Into Funcionarios Values (‘F003’, ‘Eduarda’, 1100, 2)
Go
Insert Into Funcionarios Values (‘F004’, ‘Paulo’, 1300, 2)
Go
Insert Into Funcionarios Values (‘F005’, ‘Francisco’, 1900, 2)
Go
Insert Into Funcionarios Values (‘F006’, ‘Cristovão’, 1800, 2)
Go
Insert Into Funcionarios Values (‘F007’, ‘Afonso’, 980, 3)
Go
Insert Into Funcionarios Values (‘F008’, ‘Maria’, 990, 3)
Go
Insert Into Funcionarios Values (‘F009’, ‘Inês’, 950, 3)
Go

• SELECT - para aceder à informação. Podemos ver de várias formas:


• Restrição Vertical – vou restringir num corte vertical, ou seja, só vou visualizar as
colunas IdAluno e Sexo da tabela Alunos
SELECT IdAluno, Sexo
From Alunos
 Para ver toda a tabela, a sintaxe geral
SELECT *
From Nome_da_Tabela
• Restrição Horizontal – feita tendo em base a cláusula Where (cláusula de
restrição)
SELECT IdAluno, Sexo
From Alunos
Where Sexo = ‘F’
• Operadores de comparação (>, <, >=, <=, <>) e lógicos:
• AND – tem de ser ambas verdadeiras para ser verdadeiras, OR – basta uma
verdadeira, NOT – nega o que vier à frente deste operador, EXISTS – verifica se a
sub-query devolve algo e se sim efectua a de cima, IN – verifica se determinado
campo existe, serve para evitar o OR, BETWEEN – verifica se está dentro de um
determinado intervalo, LIKE – comparação de strings (% - substitui qualquer
conjunto de caracteres, _ - substitui somente um carácter)
• Exemplos: seleccionar os registos da tabela alunos que contenham a string
Pedro no nome:
SELECT * 2
From Alunos
3
Where Nome Like ‘%Pedro%’
• Mostrar todos os alunos que não nasceram entre 1 Janeiro 1980 e 31
Dezembro 1981
SELECT *
From Alunos
Where [Data-Nascimento] Not Between ‘1980-01-01’ And ‘1981-12-31’
• Seleccionar todos os alunos que terminem em “atos”, mas cujo nome não
comece com nenhuma letra compreendida entre x e y
SELECT *
From Alunos
Where nome like ‘[^x-y]%atos’
• Seleccionar todos os alunos que sejam do sexo Feminino, e que tenham
nascido durante 1980 ou após 1985
SELECT *from Alunos
where Sexo = ‘F’ and
(
Year ([data-nascimento]) = 1980 or
Year ([data-nascimento)] > 1985
)

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:

• Se pretender obter a seguinte informação sobre os


exames relizados pelos alunos:
 IdAluno, Nota, Descrição do Nível,
Localidade do exame.
• O código teria de ser:
SELECT IdAluno, Nota, [Designacao], Localidade
FROM Exames Inner Join Niveis
ON Exames.IdNivel = Niveis.IdNivel

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 Criar uma view que liste todas as tabelas da BD E-Learning


CREATE VIEW Elearning1
As
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE [Table_type] = ‘Base table’
o Aceder ao conteúdo da view
SELECT *
FROM Elearning1

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’

• Calcular a nota máxima de um determinado IdAluno. Esse valor deverá ser


utilizado posteriormente para imprimir uma mensagem no ecrã: “O aluno
teve…”
CREATE PROC NotaMax
@ida char(4),
@vnota int output
AS
SELECT @vnota = max(nota)
FROM exames
WHERE idaluno = @ida
• Para executar o código:
Declare @macnota int
EXEC NotaMax @ida = ‘A001’, @vnota = @macnota output
Print ‘O aluno teve: ‘ + convert(char(4), @macnota)

• Criar um procedimento que devolva qual seria o impacto do aumento dos


funcionários seguindo a distribuição seguinte:
o CODCAT = 1 -> aumento = 5%
o CODCAT = 2 -> aumento = 10%
o Outras CODCAT -> aumento = 2%
o Dado que o valor do aumento para cada categoria se pode alterar, estas 3
percentagens devem ser passadas dinamicamente
CREATE PROC [dbo.[proctest]
@int1 as float, @int2 as float, @int3 as float, @vl float Output
AS
IF OBJECT_ID(N’tempdb..”valor’, N’U’) IS NOT NULL
DROP TABLE#valor;

Create table #valor


(valorl float not null)

Insert into #valor


Select sum(ordenado*@int1) from funcionarios
Where codcat=1
UNION
Select sum(ordenado*@int2) from funcionarios
Where codcat=2
UNION
Select sum(ordenado*@int3) from funcionarios
Where idfunc not in
(select idfunc
From funcionarios where codcat=1 or codcat=2)

Select @vl = sum(valor)


From #valor

• Para executar o código:


Declare @macnota decimal
EXEC proctest 0.05,0.01,0.02, @vl = @macnota output
Print @macnota
2
3
TRIGGERS I
• Não pode ser invocado dinamicamente, como se faz com uma Stored Procedure. Os
triggers são usados em: accções em cascata (propagar eventos e alterações em tabelas
relacionadas), para verificação (pode fazer o mesmo que as check constraints, mas o
trigger é mais recomendado), para garantir a aplicação de regras e como um mecanismo
de avaliação (avaliar o estado dos dados antes e depois de uma instrução DML: o INSERT,
DELETE e UPDATE)
• Esta instruções não dão num trigger:
o Alter, Create, Drop, Load e Restore Database; Disk Init e Disk Resize,
Reconfigure, Load Log e Restore Log.
• 2 tipos de execução dos triggers que permite determinar quando um trigger é executado:
o After – o trigger é executado somente após a instrução que o activou ser
concluída
o Instead Of – o trigger é executado em vez de determinada acção
• As operações de Update são registadas em ambas as tabelas auxiliares
• Para alterar um trigger temos de utilizar o comando ALTER TRIGGER
• A eliminação é com o comando Drop
• Se executar o código:
INSERT INTO
Tab1 Values
(1, ‘ABC’)
o Explicação: corre o código, o trigger activa-se, cria registo na tabela INSERTED,
executa o código de TRIGGER e faz o COMMIT da transacção se passar a validação
do trigger, caso contrário desfaz o que foi feito

• Posso criar um trigger utilizando a seguinte sintaxe


CREATE TRIGGER TG1
ON funcionarios
FOR UPDATE
AS
IF UPDATE (CodCat)
Begin
Print ‘Actualização Efectuada’
END
o Explicação: vai controlar os updates nesta tabela, sempre que acontecer um
update na tabela Funcionarios, este vai ser controlado com um trigger. If…. – vai
verificar se existe tentativa de actualizar o campo CodCat e se houver vai mostrar
a mensagem.

• Criar um trigger que não permita a inserção de novos funcionários


CREATE TRIGGER TG2
ON funcionarios
FOR INSERT
AS
BEGIN
Print ‘operação não é permitida’
Rollback Transaction
END
o Ao querer inserir um novo registo na tabela funcionarios, é mostrada a mensagem.
INSERT INTO FUNCIONARIOS
VALUES (‘F010’, ‘Miguel’, 3000, 2)

• Criar um trigger que não permita a inserção/actualização de notas negativas


CREATE TRIGGER TG3
ON exames
For insert, update
As
Declare @nt int
Select @nt = Inserted.Nota
From Inserted

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
)

CREATE TRIGGER IO_Trig_INS_Employee ON V_empregado


INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON
--verifica se existem duplicadas. Se não existir faz insert
IF (NOT EXISTS (SELECT P.SSN
FROM PESSOAS P JOIN inserted I
ON P.NSS = I.NSS))
INSERT INTO Pessoas
SELECT NSS, Nome, Morada, DataNascimento
FROM inserted
ELSE
--regista a tentativa de inserir uma pessoa com nº de Ssocial duplicado
na tabela PessoasDuplicadas
INSERT INTO PessoasDuplicadas
SELECT NSS, Nome, Morada, DataNascimento, SUSER_SNAME(), GETDATE()
FROM inserted
--verifica se existe um funcionario duplicado se não existir faz insert
IF (NOT EXISTS (SELECT E.SSN
FROM FuncionariosT E JOIN inserted
ON E.NSS = inserted.NSS))
INSERT INTO FuncionariosT
SELECT FuncionarioID, NSS, Departamento, Salario
FROM inserted
ELSE 2
3
--se existe uma duplicação altera o comando para um Update para que
não ocorra um erro de violação da chave
UPDATE FuncionariosT
SET E.FuncionarioID = I.FuncionarioID,
E.Departamento = I.Departamento,
E.Salario = I.Salario
FROM FuncionariosT E JOIN inserted I
ON E, NSS = I.NSS
END

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

• Estas instruções são validas numa função:


o Instruções de atribuição – SET
o Instruções de controlo de fluxo de execução do código (excepto TRY… CATCH)
o Instruções de DECLARE para variáveis locais ou cursores locais
o Instruções de SELECT que contenham SELECT LIST com expressões que atribuam
valores a variáveis locais
o Operações de cursores que referenciem cursores locais
o Instruções de INSERT, UPDATE e DELETE que modifiquem dados locais
o Instruções de EXECUTE que invoquem STORED PROCEDURES

• exemplo seguinte pretende apresentar o valor de aumento de determinado funcionário. A


função é uma função escalar:
CREATE FUNCTION aumento (@idf char(4))
returns int
with execute as owner
as
begin
declare @localo as int
declare @localc as int
select @localo = ordenado@localc=codcat
from funcionarios
where idfunc = @idf
if @localc = 1
begin
2
set @localo = @localo * 1.10
3
end
else
if @localc = 2
begin
set @localo = @localo * 1.05
end
else
set @localo = @localo * 1.02
return (@localo)
end

• Uma alternativa seria substituir a condição IF por um Case


ALTER FUNCTION aumento (@idf char(4))
returns int
with execute as owner
as
begin
declare @localo as int
declare @localc as int
select @localo = ordenado, @localc = codcat
from funcionarios
where idfunc = @idf
set @localo =
case @localc
when 1 then @localo * 1.10
when 2 then @localo * 1.05
else @localo * 1.02
end
return (@localo)
end
• A invocação desta função seria SELECT elearning.dbo.aumento(‘F001’)

• O código seguinte apresenta uma função multi-statement table.


CREATE FUNCTION F_Notas (@NomeA char(30))

returns @medias table

(curso char(30) primary key not null,

media decimal not null)

as

begin

insert @medias

select ‘Geral’, avg(cast(nota as decimal))

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

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

• O código seguinte apresenta uma função inline table:


CREATE FUNCTION F_Notas2 (@NomeA char(30))

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

• Se existisse a tabela Funcionario com a seguinte estrutura:


o IdLoja, este campo é a ligação com a tabela Lojas
o Nome
o IdFuncionario (primary key)
• Apresente o código necessário para saber quantos funcionários existem, por loja, tendo
em atenção os seguintes pontos:
o Pretendo saber o nome da loja
o Só pretendo visualizar a informação das lojas com mais do que 3 funcionários
o Só pretendo a informação das lojas cuja renda é superior a 3000 €
SELECT Lojas.Nome, Count(IdFuncionario)
From (Lojas Inner Join Funcionarios)
On Lojas.IdLoja = Funcionario.IdLoja
Where Renda > 3000
Group By Lojas.Nome
Having Count(IdFuncionario) > 3

2
3

Você também pode gostar