0% acharam este documento útil (0 voto)
7 visualizações36 páginas

BD10 ProgrammingSQL

Enviado por

João Varela
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
7 visualizações36 páginas

BD10 ProgrammingSQL

Enviado por

João Varela
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 36

5/30/21

Base de Dados – SQL Programming

Base de Dados - 2020/21


Carlos Costa

Índice

• Script e Batch
• Cursor

• Stored Procedure
• User Defined Function
• Trigger

Baseado em SQL Server (T-SQL)


2

1
5/30/21

Script & Batch

Batch

• Definição: Grupo de uma ou mais instruções SQL


que constituem uma unidade lógica.
• Um erro sintáctico numa instrução provoca a falha
de toda a batch.
• Um erro de runtime não anula instruções SQL
prévias (nessa batch).
• Não são transações*.
• São delimitadas pela terminador GO.
§ GO não é enviada para o servidor
§ “GO n” – executa a batch n vezes
4
* vamos ver mais à frente
4

2
5/30/21

Batch - Utilização

• Terminada a batch, são eliminadas todas as


variáveis locais, tabelas temporárias e cursores
criados.
• Algumas instruções são únicas na batch.
§ i.e. só existe essa instrução
§ Exemplo:
• CREATE PROCEDURE
• CREATE DEFAULT
• CREATE RULE
• CREATE TRIGGER
• CREATE VIEW
• Para mudar de base de dados:
§ USE <dn_name>; 5

Script

• Trata-se de um ficheiro de texto contendo


uma ou mais batches delimitadas por GO.
Por exemplo: EmployeeManipulation.sql

• As batch são executadas em sequência.

3
5/30/21

Variáveis

• Declaração:
§ DECLARE @x varchar(10) = ‘Ola’
§ DECLARE @min_range int, @max_range int

• Atribuição de um valor:
§ SET @x = ’Kabung’
§ SET @min_range = 0, @max_range = 100

• Atribuição de um valor numa instrução SELECT:


§ SELECT @price = price FROM titles
WHERE title_id = 'PC2091’; 7

Variáveis – Operações Aritméticas

Adição, Subtracção e Multiplicação

Resultado

4
5/30/21

Batches e Variáveis - Exemplos

Batch Initialization and Scope

Resultado

Utilização de Variáveis em Consultas

Select to Variable

10

último tuplo

Use Variable in WHERE

10

10

5
5/30/21

PRINT

• Imprimir mensagem na consola


PRINT string

• Outras Linguagens de Programação


§ Java: System.out.print
§ C#, VB.NET: Console.WriteLine

-- Exemplos
PRINT ‘ola’;

DECLARE @Temp int = 5;


PRINT ‘TEMP value: ’ + STR(@Temp);

11

11

Instruções de Controlo de Fluxo

• BEGIN … END

• IF … ELSE

• CASE … WHEN

• WHILE

12

12

6
5/30/21

BEGIN … END

• Define um bloco de instruções


§ block_of_statements

• Outras Linguagens de Programação


§ C#, Java, C: { … }
§ Pascal, Delphi: BEGIN … END

13

13

IF … ELSE

IF Boolean_expression
statement | block_of_statements
[ELSE
statement | block_of_statements ]

-- Exemplos
IF (SELECT ytd_sales FROM titles WHERE title_id='PC1035') > 5000
PRINT 'Year-to-date sales are greater than $5,000 for PC1035.‘

IF EXISTS(SELECT * FROM [ORDER] WHERE Closed = 0)


BEGIN
PRINT ‘Process Orders’;
PRINT ‘BLA..BLA’;
END
ELSE
PRINT ‘BLE..BLE’;
14

14

7
5/30/21

WHILE

WHILE Boolean_expression
SQL_statement | block_of_statements |
[BREAK] | [CONTINUE]
-- Exemplos
WHILE (SELECT AVG(royalty) FROM roysched) < 25
BEGIN
UPDATE roysched SET royalty = royalty * 1.05;
IF (SELECT MAX(royalty) FROM roysched) > 27
BREAK;
ELSE
CONTINUE;
END;

DECLARE @i as int = 1;
WHILE @i < 100
BEGIN
IF (@i % 2) = 0
print str(@i) + ' - Par';
ELSE
print str(@i) + ' - Impar’;
SET @i += 1; 15
END;

15

CASE … WHEN

CASE input_expression
WHEN when_expression THEN result_expression
[WHEN when_expression THEN result_expression…n]
[ELSE else_result_expression ]
END

-- Exemplo
SELECT OrderID, CustomerID ,
EmployeeName =
CASE EmployeeID
WHEN 1 THEN 'Mario'
WHEN 2 THEN 'Julio'
WHEN 3 THEN 'Vasco'
WHEN 4 THEN 'Sousa'
WHEN 5 THEN 'Rui'
ELSE 'desconhecido'
END
FROM [Orders] 16

16

8
5/30/21

Tabelas Temporárias

• Há situações em que necessitámos de criar tabelas


de uso temporário.

• Criam-se da forma usual e têm as mesmas


características que as “normais” excepto a
persistência.
• Dois Tipos:
§ Temporárias Locais
§ Temporárias Globais

• Tabelas como Variáveis


17

17

Tabelas Temporárias Locais

• São sinalizadas com o carácter # antes do nome.


• São criadas na base de dados tempdb.
• Estão visíveis
§ Só na sessão que as criou
§ No level em que são criados e todos os inner level (da call stack)
• São eliminadas quando o procedimento ou função termina.
§ Podem ser eliminadas da forma normal (drop)
• No caso de uma batch ad-hoc (query editor) fica visível até
encerrar a sessão, mesmo tendo um GO pelo meio.
-- Exemplo:
GO
CREATE TABLE #Hello(
id INT PRIMARY KEY,
name VARCHAR(25));
GO 18
SELECT * FROM #Hello; -- Está visível (query editor).

18

9
5/30/21

T. Locais Temporárias – Call Stack


proc1
…..
….. proc2
EXEC proc2 …..
….. CREATE TABLE #T1 proc3
….. EXEC proc3 …..
….. ….. proc4
EXEC proc4 …..
….. …..
….. …..
…..
#T1:
- está visível para proc2, proc3 e proc4
- é destruída no final de proc2
- não está acessível em proc1 19

19

Tabelas Temporárias Globais

• Utilizamos dois ## antes do nome.


• Similares às local temporary tables (tempdb) mas têm um
scope maior.
§ Ficam visíveis para outras sessões.
• Apropriadas para partilha de dados
• Todos têm full access!!!
§ São eliminadas quando a última sessão desconecta.
-- Exemplo: Verifica se já alguém criou antes de criar
IF NOT EXISTS(SELECT * FROM tempdb.sys.objects
WHERE name = ‘##TempWork’)
CREATE TABLE ##TempWork(
PK INT PRIMARY KEY,
Col1 INT );

Alternativa: Criar a tabela normalmente na BD tempdb. Só é eliminada quando o


SQL Server reinicializa. 20

20

10
5/30/21

Tabelas como Variáveis

• São similares a tabelas temporárias locais mas têm


um scope mais limitado:
§ Tem o mesmo scope que as variáveis locais
§ Mas não estão visíveis em inner levels da call stack
• Podem ser passados como parâmetros
• Declaram-se como variáveis
§ Também têm existência na tempdb
-- Exemplo: Declaração e Utilização
DECLARE @WorkTable TABLE (PK INT PRIMARY KEY, Col1 INT NOT
NULL);

INSERT INTO @WorkTable (PK, Col1) VALUES (1, 101);

SELECT PK, Col1 FROM @WorkTable; 21

21

Tabelas como Variáveis - Limitações

• Desaparecem quando a batch, procedimento ou


função, onde foram criadas, chega ao fim.

• Limitadas em termos de restrições:


§ Não é permitido: chaves estrangeiras e check.
§ Permitido: chaves primária, defaults, nulls e unique.

• Não podem ter objetos dependentes.


§ Chaves estrangeiras ou triggers.

22

22

11
5/30/21

Cursor

23

23

Cursor

• Ferramenta que permite percorrer sequencialmente os


tuplos retornados por determinada consulta (SELECT).
• Tipicamente temos duas abordagem:
§ Set based query (AR) versus cursor operation

• Soluções set-based são, em geral, bastante mais rápidas do


que cursores.
• Usualmente os utilizadores sentem-se mais confortáveis a
pensar em termos de ciclos e ponteiros do que em
consultas baseadas em álgebra relacional.
§ Défice de formação em base de dados? Álgebra Relacional?

• Em SQL Server os cursores são server-side.


Analogia da “Pesca”: podemos ver os cursores como pesca à linha e as operações 24
set-based como pesca com rede.
24

12
5/30/21

Cursor – 5 steps
1. Declaração
-- SQL-92
DECLARE CursorName [CursorOptions] CURSOR
FOR Select Statement;
-- T-SQL
DECLARE CursorName CURSOR [CursorOptions]
FOR Select Statement;
2. Open
-- Open to retrieve data
OPEN CursorName;

3. Fetch
/* Moves to the next row and assigns the values from each column returned by
the cursor into a local variable */
FETCH [Direction] CursorName [INTO @Variable1, @Variable2, ...];
-- T-SQL offers @@fetch_status function to report the state of the cursor after
the last FETCH command (0: OK; -1: Fail, end off record set; -2: Fail, tuple not available)

4. Close
-- Close cursor. Can be opened again (2.Open)
CLOSE CursorName;

5. DEALLOCATE
-- Release cursor. 25
DEALLOCATE CursorName;

25

Cursor - Exemplo
Objectivo: Número de produtos distintos e total absoluto encomendados por cada cliente
DECLARE @custID as nchar(5), @prevCustID as nchar(5), @prodID as int,
@qty as int, @totalQty as int, @cnt as smallint;

DECLARE C CURSOR FAST_FORWARD


FOR SELECT CustomerID, ProductID, Quantity FROM CustOrderProducts ORDER BY CustomerID;

OPEN c;
CustOrdersProducts
FETCH C INTO @custID, @prodID, @qty;

SELECT @prevCustID = @custID, @totalQty = 0, @cnt = 0;

WHILE @@FETCH_STATUS = 0
BEGIN
if @prevCustID <> @custID
BEGIN
PRINT @prevCustID + ' - ' + CAST(@cnt as varchar) + ' - ' + CAST(@totalQty as
varchar);
SELECT @prevCustID = @custID, @totalQty = 0, @cnt = 0;
END;

SET @totalQty += @qty;


SET @cnt += 1

FETCH C INTO @custID, @prodID, @qty;


END;

CLOSE C;

DEALLOCATE C; 26

26

13
5/30/21

Exemplo – Implementação Alternativa

Objectivo:
Implementação Alternativa com Consulta baseada em Álgebra Relacional
SELECT CustomerID, count(ProductID) as nprod, sum(Quantity) as totalQty
FROM CustOrderProducts
GROUP BY CustomerID
ORDER BY CustomerID;

Resultados
236 ms 7 ms
pesca à linha pesca com rede

27

27

When are cursors the best solution?


• Iterating over a stored procedure: When a stored procedure must be executed several
times, once for each row or value, and the stored procedure can’t be refactored into a
set-based solution, or it’s a system stored procedure, then a cursor is the right way to
iteratively call the stored procedure.

• Iterating over DDL code: When DDL code must be dynamically executed multiple times,
using a cursor is the appropriate solution.
§ Sometimes it’s necessary to iterate over multiple rows or columns, generating a dynamic SQL statement for each
row or column.

• Cumulative Totals/Running Sums: While there are set-based solutions, a cursor is the
best-performing solution in these cases because it only has to add the next row’s value to
the cumulative value.

• Time-Sensitive Data: Some time-sensitive problems, depending on the database design,


can benefit by using a cursor to determine the duration between events. Like the
cumulative totals problem, time-sensitive data requires comparing the current row with
the last row. Although there are possible set-based solutions, in some cases I’ve seen
cursors perform better than set-based solutions.

28
Source: Microsoft SQL Server 2008 Bible

28

14
5/30/21

Cursor - [CursorOptions]

29
Lista não exaustiva

29

Stored Procedures

Procedimentos

30

30

15
5/30/21

Stored Procedure - Definição

• Trata-se de uma batch armazenada com um nome.


§ Um conjunto de instruções T-SQL que o SQL Server compila num
single execution plan.

• O SQL Server não tem de recompilar o código cada vez que


o procedimento é invocado.
• Os procedimento são guardados em memória cache na
primeira vez em que são executados.
§ Execução mais rápida

• O procedimento pode:
§ Ter parâmetros de entrada
§ Ter valor de retorno (parâmetros de saída, return success ou failure
status messages) 31
§ Devolver um conjunto de registos (tuplos)
31

Stored Procedure – Mais Valias

• Extensibility: Using stored procedures is the best means of abstracting,


or decoupling, the database. A stored procedure API contract will
encapsulate the database and provide it with long-term extensibility.

• Performance: A well-written stored procedure is the fastest possible


SQL Server code, it keeps the execution of data-centric code close to
the data, and it’s easier to index tune a database with stored
procedures.

• Usability: It’s easier for application programmers to make a stored


procedure call and consume the result than it is to write ad hoc SQL.

• Data Integrity: A stored procedure developed by the database


developer is less likely to contain data integrity errors, and easier to
unit test, than ad hoc SQL code.

• Security: Locking down the tables and providing access only through
stored procedures is a standard best practice for database 32
development. Source: Microsoft SQL Server 2008 Bible

32

16
5/30/21

SQL Statement vs. Stored Procedure

SQL Statement Stored Procedure


Creating
- Check syntax
- Compile

First Time First Time


- Check syntax - Execute
- Compile - Return data
- Execute
- Return data

Second Time Second Time


- Check syntax - Execute
- Compile - Return data
- Execute
- Return data 33

33

Stored Procedure – Create

Sintaxe:
CREATE PROC[EDURE] procedure_name
[ @parameter_name data_type] [= default] OUTPUT][,...,n]
AS
T-SQL_statement(s)

• Única instrução da batch

-- Exemplo: CREATE Storage Procedure


-- devolver um conjunto de registos (record-set)
go
CREATE PROCEDURE dbo.CategoryList
AS
SELECT ProductCategoryName, ProductCategoryDescription
FROM dbo.ProductCategory;
go
34

34

17
5/30/21

Stored Procedure – Create com Parâmetros

-- Exemplo: CREATE Storage Procedure with input parameters


CREATE PROC Department_Members @DeptName varchar(50)
AS
SELECT Dep_Name, COUNT(Emp_ID) NumberOfMember
FROM Departments D, Employees E
WHERE D.Dep_ID = E.Dep_ID and Dep_Name = @DeptName
Devolve um record-set
GROUP BY Dep_Name

-- Exemplo: CREATE Storage Procedure with parameters + RETURN


CREATE PROC GroupLeader_Members @Emp_Code varchar(10) = null
AS
IF @Emp_Code is null
BEGIN
PRINT 'Please enter Employee Code!' ?
RETURN
END
SELECT * FROM Employees
WHERE EMP_EMP_ID = (SELECT EMP_ID FROM Employees Devolve um record-set
WHERE Emp_Code = @Emp_Code)
ORDER BY Emp_Name
35
Nota: Quando temos múltiplos parâmetros de entrada devemos colocar no fim aqueles que têm valor de defeito.

35

Stored Procedure – Update e Drop

Sintaxe:
ALTER PROC[EDURE] procedure_name
[ @parameter_name data_type] [= default] [OUTPUT] [,...,n]
AS
T-SQL_statement(s)

• Susbstitui o procedimento existente com o novo código (T-


SQL_statement(s))

Sintaxe:
DROP PROC[EDURE] procedure_name

• Elimina um procedimento
-- if exists, delete the procedure
IF Object_Id('Production.ProductList', 'P') IS NOT NULL 36
DROP PROCEDURE Production.ProductList;

36

18
5/30/21

Stored Procedures - Tipos

• System stored procedure:


§ Nome começa com sp_
§ Criados na Master database
§ Podem ser utilizados em qualquer base de dados
• Muitas vezes utilizados por sysadmins

• Local stored procedure:


§ São definidos num base de dados local
§ Nome livre mas recomenda-se uma normalização por
parte do utilizador
• Aumenta a legibilidade
• Exemplos: pr_ , p_, ...
37

37

Stored Procedures - Execução

Sintaxe:
EXEC[CUTE] procedure_name [@parameter_name data_type]

-- Exemplos: Execução de Storage Procedure


-- Sem parâmetros de entrada
EXEC dbo.CategoryList;

-- Com um parâmetros de entrada


EXEC Department_Members ‘Accounting’;

-- Com múltiplos parâmetros de entrada


-- ... por posição
EXEC pr_GetTopProducts 1, 10
-- ... por nome (ordem não interessa)
EXEC GetTopProducts @EndID = 10, @StartID = 1

38

38

19
5/30/21

Stored Procedure – Parâmetros de Saída

• Utilizados para retornar non-recordset information.


• Devemos criar previamente a variável que receberá
o valor de parâmetro de saída.
-- Exemplo: Declaração e utilização de proc. com parâmetro de saída
-- Criação
CREATE PROC dbo.GetProductName (
@ProductCode CHAR(10), @ProductName VARCHAR(25) OUTPUT)
AS
SELECT @ProductName = ProductName
FROM dbo.Product
WHERE Code = @ProductCode;

-- Utilização
DECLARE @ProdName VARCHAR(25);
EXEC dbo.GetProductName ‘1001’, @ProdName OUTPUT;
PRINT @ProdName; 39

39

Stored Procedures – Return [N]

• Termina incondicionalmente o procedimento e retorna um


inteiro
§ tipicamente: success/failure status

• O valor de saída pode ser atribuído a uma variável:


EXEC @LocalVariable = StoredProcedureName;
-- Exemplo: Storage Procedure with Return
GO
CREATE PROC dbo.IsItOK ( @OK VARCHAR(10) )
AS
IF @OK = ‘OK’
RETURN 0;
ELSE
RETURN -100;
GO

DECLARE @ret as int;


EXEC @ret=dbo.IsItOK ’OK’;
SELECT @ret;
40
Também podemos ter um return sem valor de retorno

40

20
5/30/21

T-SQL Error Handling

• T-SQL oferece um conjunto de ferramentas para


detecção e tratamento de erros.
@@error: retorna um inteiro com o código de erro da
última instrução. 0 – Sucesso
-- Exemplo: @@error
UPDATE Person SET PersonID = 1 Where PersonID = 2;
Print @@error; -- Violation of PRIMARY KEY constraint ‘PK Person….
Print @@error; -- 0

@@rowcount: permite saber quantos tuplos foram


afectadas por determinada instrução SQL
-- Exemplo: @@rowcount
UPDATE Person SET LastName = ‘Johnson’ WHERE PersonID = 100;
IF @@rowCount = 0
PRINT ‘no rows affected’;
41

41

T-SQL RAISERROR

• Retorna uma mensagem de erro ao cliente


Duas Sintaxes:
RAISERROR ErrorNumber ErrorMessage;
-- Exempl: RAISERROR
RAISERROR 12345 ‘Nao foi possivel actualizar registo’;

RAISERROR ( message or number, severity, state, optional arguments )


WITH LOG;

-- Exemplo: RAISERROR
RAISERROR (’Nao foi possivel actualizar registo em %s.’, 14, 1, ‘Customer’);

42

42

21
5/30/21

T-SQL: Try … Catch

• Captura e Tratamento de Erros

BEGIN TRY -- Exemplo


GO

<SQL code>;
CREATE PROCEDURE uspTryCatchTest
AS
BEGIN TRY
SELECT 1/0
END TRY END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber

BEGIN CATCH ,ERROR_SEVERITY() AS ErrorSeverity


,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure

<error handling code>; ,ERROR_LINE() AS ErrorLine


,ERROR_MESSAGE() AS ErrorMessage;
END CATCH;

END CATCH;
GO

EXEC uspTryCatchTest;

43

43

Stored Procedures - Cifragem

• SQL Server permite ver a definição (conteúdo) do


procedimento:
EXEC sp_helptext ‘dbo.CategoryList’;

• Existe a opção de cifrar o conteúdo do SP:


-- Exemplo: Cifrar Storage Procedure criado anteriormente
ALTER PROCEDURE dbo.CategoryList
WITH ENCRYPTION
AS
SELECT ProductCategoryName, ProductCategoryDescription
FROM dbo.ProductCategory;
44

44

22
5/30/21

User Defined Functions (UDF)

Funções Definidas pelo Utilizador

45

45

UDF - Vantagens

• Os mesmos benefícios dos Stored procedures


§ São igualmente compilados e optimizados

• Podem ser utilizadas para incorporar lógica complexa


dentro de uma consulta.

• Oferecem os mesmo benefícios das vistas pois podem ser


utilizados como fonte de dados nas consultas e nas
cláusulas WHERE/HAVING.
§ Acresce o facto de aceitar parâmetros, algo impossível em views.

• Criação de novas funções contendo expressões complexas.

46

46

23
5/30/21

UDF - Tipos

SQL Server suporta 3 tipos de UDFs:


§ Escalares
§ Inline table-valued
§ Multi-statement table-valued functions

47

47

UDF Escalar

Sintaxe:
CREATE FUNCTION function_name
[ @param_name data_type] [= default] [ READONLY ][,...,n]
RETURNS return_data_type
AS
T-SQL_statement(s)

• Aceitam múltiplos parâmetros.


• Retornam um único valor.
§ Instrução RETURN

• Podem ser utilizados dentro de qualquer expressão T-SQL,


incluindo check constraint. 48

48

24
5/30/21

UDF Escalar - Exemplos


-- Exemplos: Criação e Utilização de UDF Escalar
CREATE FUNCTION dbo.Revenue_Day (@Date datetime) RETURNS money
AS
BEGIN
DECLARE @total money
SELECT @total = sum(sali_Quantity * sali_price)
FROM Sales_Orders s, Sales_Orders_Items si
WHERE s.sal_number = si.sal_number and year(sal_date) = year(@Date)
and month(sal_date) = month(@Date) and day(sal_date)= day(@Date)
RETURN @total
END

GO
SELECT dbo.Revenue_Day(GETDATE())

CREATE FUNCTION dbo.fsMultiply (@A INT, @B INT = 3) RETURNS INT


AS
BEGIN
RETURN @A * @B;
END;

GO
SELECT dbo.fsMultiply (3,4), dbo.fsMultiply (7, DEFAULT);

SELECT dbo.fsMultiply (3,4) * dbo.fsMultiply (7, DEFAULT);


49
Nota: O nome da schema (dbo) é obrigatório na invocação da UDF

49

UDF Escalares – Algumas Limitações

• Determinísticas
§ Os mesmos parâmetros de entrada produzem o mesmo valor de
retorno.
§ Não são permitidas funções não-determinísticas dentro das UDF.
• newid(), rand(), etc
• Não são permitidos updates à base de dados ou invocação
do comando DBCC.
• Em termos de valor de retorno não permite:
§ BLOB (binary large object) - text, ntext, timestamp, image data-
type, etc.
§ Table variables
§ Cursores
• Não permite TRY...CATCH ou RAISERROR.
• Recursividade limitada a 32 níveis. 50

50

25
5/30/21

UDF - Inline Table-valued

Sintaxe:
CREATE FUNCTION function_name
[ @param_name data_type] [= default] [ READONLY ][,...,n]
RETURNS TABLE
AS
T-SQL_statement {RETURN SELECT statement}

• Similares a vistas
§ Ambas são wrapers para construções SELECT
§ Tem as mais valias das vistas acrescido do facto de
suportar parâmetros de entrada.
51

51

UDF Inline Table-valued - Exemplo


-- Exemplos: Criação e Utilização de UDF Inline Table-valued
CREATE FUNCTION dbo.AveragePricebyItems (@price money = 0.0) RETURNS Table
AS
RETURN (SELECT Ite_Description, Ite_Price
FROM Items
WHERE Ite_Price > @price)

GO
SELECT * FROM dbo.AveragePricebyItems (15.00)

CREATE FUNCTION dbo.ftPriceList (@Code CHAR(10) = Null, @PriceDate DateTime)


RETURNS Table
AS
RETURN(SELECT Code, Price.Price
FROM dbo.Price JOIN dbo.Product AS P
ON Price.ProductID = P.ProductID
WHERE EffectiveDate = (SELECT MAX(EffectiveDate)
FROM dbo.Price
WHERE ProductID = P.ProductID
AND EffectiveDate <= @PriceDate)
AND (Code = @Code OR @Code IS NULL));

GO
SELECT * FROM dbo.ftPriceList(DEFAULT, ‘20020220’); 52

52

26
5/30/21

UDF Multi-statement Table-Valued

Sintaxe:
CREATE FUNCTION function_name
[ @param_name data_type] [= default] [ READONLY ][,...,n]
RETURNS @return_variable TABLE <table_type_definition>
AS
T-SQL_statement

• Combina a capacidade das funções escalares (conter


código complexo) com a capacidade das inline table-
valued (retornar um conjunto).
• Cria uma table variable, introduz-lhe tuplos e retorna-a.
§ Tabela retornada pode ser utilizada num SELECT

53

53

UDF Multi-statement Table-Valued - Exemplo


-- Exemplos: Criação e Utilização de UDF Multi-statement Table-Valued
CREATE FUNCTION dbo.AveragePricebyItems2 (@price money = 0.0) RETURNS @table TABLE
(Description varchar(50) null, Price money null)
AS
BEGIN
INSERT @table SELECT Ite_Description, Ite_Price
FROM Items WHERE Ite_Price > @price;
RETURN;
END;

GO
SELECT * FROM dbo.AveragePricebyItems2 (15.00);

CREATE FUNCTION dbo.ftPriceAvg() RETURNS @Price TABLE (Code char(10), EffectiveDate datetime,
Price money)
AS
BEGIN
INSERT @Price (Code, EffectiveDate, Price)
SELECT Code, EffectiveDate, Price
FROM Product JOIN Price ON Price.ProductID = Product.ProductID;

INSERT @Price (Code, EffectiveDate, Price)


SELECT Code, Null, Avg(Price)
FROM Product JOIN Price ON Price.ProductID = Product.ProductID
GROUP BY Code;
RETURN;
END;

GO 54
SELECT * FROM dbo.ftPriceAvg();

54

27
5/30/21

SP versus UDF

• return - zero, single or • return - single value (scalar


multiple values or table)

• input/output param • input param

• cannot use SELECT/ • can use SELECT/ WHERE/


WHERE/ HAVING statement HAVING statement

• call SP – OK • call SP - NOK

• exception handling - OK • exception handling - NOK

56
• transactions – OK • transaction - NOK
56

Trigger

57

57

28
5/30/21

Trigger - Definição

• Trigger: um tipo especial de stored procedure que é executado em


determinadas circunstâncias (eventos) associadas à manipulação de
dados.
• SQL Server suporta dois tipos de trigger: DML e DDL. Só vamos tratar de
triggers DML:
§ São criados em tabelas (ou vistas) e têm uma ou mais ações associadas
(INSERT, UPDATE, DELETE).

• Quando ocorre uma das ações previstas, os triggers são “disparados”


(executados).
• Exemplos de uso:
§ Maintenance of duplicate and derived data
§ Complex column constraints
§ Cascading referential integrity
§ Complex defaults
58
§ Inter-database referential integrity

58

Trigger - Conceitos Básicos

• SQL Server triggers são disparados uma vez por cada


operação de modificação de dados
§ Não por tuplo afectado – caso da Oracle.

• Ter em atenção que os triggers estendem a duração da


transação:
§ Pode criar problemas de locks/blocks em sistemas de elevado
desempenho.
§ Compromisso entre integridade dos dados e potencial impacto no
desempenho.

• Existem dois tipos de DML triggers que diferem quanto ao


propósito, timing e efeito.
§ instead of
59
§ after
59

29
5/30/21

SQL Server – Transaction Flow


É importante entender em que parte da transação ocorre cada um dos triggers...

1. IDENTITY INSERT check


2. Null ability constraint
3. Data-type check
4. INSTEAD OF trigger execution.
If an INSTEAD OF trigger exists, then execution of the DML stops here.
INSTEAD OF triggers are not recursive. Therefore, if the INSERT trigger
executes another DML command, then the INSTEAD OF trigger will be ignored
the second time around.
5. Primary-key constraint
6. Check constraints
7. Foreign-key constraint
8. DML execution and update to the transaction log
9. AFTER trigger execution
10. Commit transaction 60

60

Transaction Flow – Ideias a reter…

• AFTER trigger pode assumir que os dados passaram todos as


verificações de integridade de dados.

• AFTER trigger ocorre depois de todos os constraints


§ Não pode corrigir eventuais problemas dos dados.

• AFTER trigger ocorre antes do commit1 da transação DML. Assim


podemos fazer o rollback1 da transação se os dados forem inaceitáveis.

• INSTEAD OF trigger – a transação para no ponto 4 e nenhum dos


posteriores é executado, incluindo a instrução DML.
§ Excepção: Invocação recursiva do trigger

• INSTEAD OF trigger pode “contornar” problemas de integridade


referencial mas não de nulidade, tipo de dados e identidade das
colunas.
61
1 Vamos ver o que isto é mais à frente quando se falar de Transações

61

30
5/30/21

Trigger – Create, Enable/Disable, Drop

Sintaxe:
-- Criação
CREATE TRIGGER trigger_name ON <tablename>
AFTER | INSTEAD OF { [INSERT] [,] [UPDATE] [,] [DELETE]}
AS
SQL_Statement

-- Activar | Desactivar
ALTER TABLE <tablename> ENABLE | DISABLE TRIGGER trigger_name
ou
ENABLE | DISABLE TRIGGER trigger_name ON <tablename>

-- Eliminar
DROP TRIGGER trigger_name ON <tablename>
62

62

Trigger - After

• Podemos ter vários triggers after por tabela.

• Algumas das utilizações possíveis:


§ Processos complexos de validação de dados envolvendo, por
exemplo, várias tabelas
§ Assegurar regras de negócios complexas.
§ Efetuar auditorias aos dados.
§ Atualizar campos calculados.
§ Assegurar verificações de integridade referencial definidas pelo
utilizador e deletes em cascata
• Devemos evitar, i.e. privilegiar a integridade referencial declarativa,
a menos que não exista outra forma.
• Exemplo: Especialização – Subcategorias exclusivas. Uma Pessoa só
pode ser Aluno ou Professor.

63

63

31
5/30/21

Trigger - Exemplo de After


-- Exemplos: Criação e teste de um trigger After Insert ou Update.
GO
CREATE Trigger highsales ON dbo.[Order Details]
AFTER INSERT, UPDATE
AS

?
SET NOCOUNT ON;

DECLARE @total as real


SELECT @total = unitprice * (1-discount) * quantity FROM inserted;
IF @total < 0.99
BEGIN
RAISERROR ('Encomenda nao processada. Valor muito baixo', 16,1);
ROLLBACK TRAN; -- Anula a inserção
END
ELSE IF @total > 1000
PRINT 'Log: Encomenda de valor elevado'
GO

INSERT INTO dbo.[Order Details] values (10248, 14, 18.6, 20, 0.15);

INSERT INTO dbo.[Order Details] values (10248, 14, 18.6, 200, 0.15);

INSERT INTO dbo.[Order Details] values (10248, 14, 1.0, 1, 0.15);

64

64

Trigger – Instead of

• Apenas um por tabela (vista).

• NÃO É EXECUTADA a ação associada (Insert, Update,


Delete).
§ Fica à responsabilidade do trigger efetuar a operação pretendida
(ou não).

• Devemos utilizar este tipo de trigger quando sabemos que a


ação (instrução DML) tem um elevada probabilidade de ser
rolled back e pretendemos que outra lógica seja executada
em vez (instead of) dela.
§ Exemplos:
• Uma instrução tenta fazer update de uma view non-updatable
• Uma instrução tenta apagar um tuplo mas pretendemos que este
passe para uma tabela de arquivo.
65

65

32
5/30/21

Trigger – Exemplo 1 de Instead of


-- Exemplos: Criação, Teste e Eliminação de um trigger Intead of Insert
GO
CREATE TRIGGER dbo.TriggerTest ON dbo.dependent
INSTEAD OF INSERT
AS
PRINT ‘Insert Action Canceled’;
GO

INSERT INTO dependent VALUES('21312339', 'Catia Pereira', 'F', null, null);


GO

SELECT * FROM dependent WHERE essn= '21312339’;


GO

DROP Trigger dbo.TriggerTest;

66

66

Trigger – Exemplo 2 de Instead of


-- Exemplos: Intead of – Constraint: employee cannot work in projects associated to distinct PLocations
CREATE TRIGGER dbo.TriggerTest2 ON works_on
INSTEAD OF INSERT
AS
BEGIN
IF (SELECT count(*) FROM inserted) = 1
BEGIN
DECLARE @issn as char(9);
DECLARE @ipno as int;
DECLARE @iplocation as varchar(15);
SELECT @issn = essn, @ipno = pno FROM inserted;
SELECT @iplocation=plocation from project where pnumber=@ipno;

IF (@iplocation) is null
RAISERROR('Project Inexistent.', 16, 1);
ELSE
BEGIN -- You can have different Pno with same Plocation
IF (SELECT count(distinct Plocation) FROM Project join Works_on on Pno=Pnumber
WHERE essn=@issn AND plocation<>@iplocation) >= 1
RAISERROR('Not allowed to have employee working in Projects with different Plocations.', 16, 1);
ELSE
INSERT INTO works_on SELECT * FROM inserted; -- chamada recursiva
END
END
END
GO

insert into project values('Aveiro Digital', 1, 'Aveiro', 3);


insert into project values('BD Open Day', 2, 'Espinho', 2);
insert into project values('Dicoogle', 3, 'Aveiro', 3);

insert into works_on values('183623612', 1, 20);


insert into works_on values('183623612', 2, 20);
insert into works_on values('183623612', 3, 10); 67
SELECT * FROM works_on WHERE essn='183623612';

67

33
5/30/21

Inserted e Deleted – Logical Tables

• O SQL Server permite ter acesso a duas tabelas lógicas com


uma imagem read-only os dados afectados:
§ Inserted
§ Deleted

• Estas tabelas tem um scope muito limitado


§ Stored procedures invocados pelo trigger não as vêm

• A maioria dos triggers implementados não foram pensados


para eventos que afectam vários tuplos.
§ Na prática, estas situações acabam por estar associadas a situações
69
de mau desempenho dos triggers.

69

Trigger – Colunas Alteradas

• O SQL Server disponibiliza duas funções que nos permitem


saber quais as colunas (potencialmente) afectadas pela
instrução DML:
§ update(<columnname>)
• Retorna true se determinada coluna for alterada.

CREATE Trigger detectcontactupdate ON dbo.[Customers]


AFTER UPDATE
AS
IF update(ContactName)
PRINT ’Mudou a pessoa de contacto do cliente.’

§ columns_updated()
• Retorna um bitmapped varbinary representando as colunas
alteradas. O seu tamanho depende do número de colunas da tabela.
Se uma coluna foi alterada então o seu bit está a true. Temos de
utilizar bitwise operators para determinar quais as colunas
alteradas. 70

70

34
5/30/21

Triggers - Limitações

• Instruções não permitidas num trigger:


§ CREATE, ALTER, or DROP database
§ RECONFIGURE
§ RESTORE database or log
§ DISK RESIZE
§ DISK INIT

71

71

Trigger – Funcionalidades Úteis

• Ver conteúdo do trigger


§ sp_helptext <trigger name>

• Listar triggers de uma tabela


§ sp_helptrigger <table name>

72

72

35
5/30/21

Resumo

• Script e Batch
• Cursor

• Stored Procedure

• User Defined Function


• Trigger

73

73

36

Você também pode gostar