0% found this document useful (0 votes)
7 views35 pages

Sqldev320a Week6-2

Uploaded by

adams.radiy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views35 pages

Sqldev320a Week6-2

Uploaded by

adams.radiy
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 35

Instructor:

SQL Server boB Taylor


Developme [email protected]
nt m
SQLDEV
320 A
Spring
2021 MCA, MCM, MCSM,
Week 6 MCSE, MCSD, MCT,
Data Scientist
REVIEW
• RECAP WEEK 5
• ASSIGNMENT 5 REVIEW
TODAY
ERROR HANDLING

TRIGGERS

• WHAT ARE TRIGGERS


• TYPES
• VIRTUAL TABLES

CURSORS
• WHAT ARE CURSORS
• SYSTEM CURSOR FUNCTIONS
• COMMON CURSOR ARGUMENTS
Error Error Handling
Handling
Functions
Accessing the @@ERROR object
Creating customer errors with
RAISERROR()
Capturing error info with TRY…
CATCH…
THROW…
Error Object: @@ERROR

SQL Server Engine

RuntimeError Access info in @@ERROR


ERROR
Object
Can only access
once!
SQL SQL
Statement Statement
Error Object:
@@ERROR
USE
[AdventureWorks2019]
GO
DECLARE @Oops
int; PRINT 1/0;
SET @Oops = @@ERROR; --Capture error number from objec
@@ERROR t
IF @Oops >
0
SELEC 'An error has
BEGIN
T occurred.'
UNION 'Error Number: ' + CAST(@Oops AS
varchar(4))
SELEC [TEXT
T
FROM ]
SYS.messages
UNION [message_id] =
WHERE
@Oops AND
SELEC
[language_id] = (
T SELECT MSGLANGID
FROM sys.syslanguages
END WHERE LANGID =
; @@LANGID)
Creating
custom USE [AdventureWorks2019] GO
errors with
IF NOT EXISTS(
RAISERROR SELECT LoginID
() FROM HumanResources.Employee
WHERE BusinessEntityID = 0)
BEGIN
RAISERROR( '[SQLDEV200] Employee not found.’,
16,1)
END
You can add
custom error
messages to
sys.messages
Creating custom errors with
THROW()
USE
[AdventureWorks2019]
GO

IF NOT EXISTS(
SELECT LoginID
FROM HumanResources.Employee
WHERE BusinessEntityID = 0)
THROW 76543, '[SQLDEV320A] Employee not
found.', 1;
RAISERROR THROW statement
Differences statement

Between If a msg_id is passed


to RAISERROR, the
The error_number
parameter does not
RAISERROR ID must be defined in
sys.messages.
have to be defined
in sys.messages.
and The msg_str The message
THROW parameter parameter
can contain does not
printf accept printf
formatting style
styles. formatting.
The severity There is no
parameter severity
specifies the parameter. The
severity of the exception
Handling Errors with TRY CATCH
USE [AdventureWorks2019]
GO
BEGIN TRY
PRINT 1/0;
-- Generate divide-by-zero error
END TRY
BEGIN CATCH
PRINT 'Inside the Catch block'; TRY
PRINT ERROR_NUMBER();
PRINT ERROR_SEVERITY();
PRINT ERROR_STATE();
Runtime
PRINT ERROR_PROCEDURE(); Error
PRINT ERROR_LINE();
PRINT ERROR_MESSAGE();
END CATCH
PRINT 'Outside the catch block'; ERROR
CATCH
PRINT ERROR_NUMBER(); Object
GO
Handling Errors with TRY CATCH THROW11
USE
[AdventureWorks2019]
GO Runtime
TRY
BEGIN TRY Error
SELECT 1/0 AS
[DivideByZero] END TRY
BEGIN CATCH ERROR
THROW CATCH
Object
51000,
'[SQLDEV200] Divide by
zero', 101;
END ERROR
THROW
CATCH Object
GO
What are Triggers

Trigger Types
• FOR | AFTER trigger

Database
• INSTEAD OF trigger

DMLTriggers
Triggers INSERT, UPDATE or DELETE statement to a table or
view
DDL Triggers
CREATE, ALTER, DROP, GRANT DENY, REVOKE,
UPDATE
What are
triggers
•A trigger is a special
kind of stored
procedure that
automatically
executes when a
table event occurs in
the database server.
Enforce Enforce business logic

Enforce Enforce referential data integrity

Why do we Apply Apply changes automatically without user


use Triggers? action

Apply transaction commit and rollback


Apply actions

Track Track changes in thedatabase


What are the cons of using
Triggers?

Why do • Additional logic to monitor and maintain


• Synchronous actions within the scope of

we use the transaction


• Hidden from application logic
• Have global scope
Triggers? • Recursive triggers can easily cause errors
• Could have unintended consequences
•FOR | AFTER Trigger:

•DMLtrigger

Trigger •Fired only when all operations specified in the


triggering SQL statement have executed
Types successfully

•Cannot be defined on views

•FOR was a pre-2000 syntax.


•INSTEAD OF Trigger:

Trigger •DML trigger


Types •Overrides the standard action of the
triggering statement: an INSERT,
UPDATE or DELETE
•Can be used in either tables or views
•It can be used to bypass the statement
and execute a whole different
statement, or just help us check and
examine the data before the action is
done.
DML Trigger
Command Syntax

CREATE TRIGGER [ schema_name . ]trigger_name


ON
{ table }
[ WITH <dml_trigger_option> [ ,...n ] ]
{ FOR | AFTER } { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ]}
AS { sql_statement [ ; ] [ ,...n ] }
DML •CREATE TRIGGER
Trigger [ schema_name . ]trigger_name
Command •ON { table | view } [ WITH
<dml_trigger_option> [ ,...n ] ]
Syntax for • { FOR | AFTER | INSTEAD OF } {
Views [ INSERT ] [ , ] [ UPDATE ] [ , ]
[ DELETE ] } [ WITH APPEND ]
[ NOT FOR REPLICATION ]
•AS { sql_statement [ ; ] [ ,...n ] |
EXTERNAL NAME <method specifier [ ; ]
>}
Simple Trigger Example:
USE [test]
GO

IF OBJECT_ID('[dbo].[Table1]', 'U') IS NOT NULL


DROP TABLE
[dbo].Table1 GO

-- 1 Create table
object
CREATE TABLE Table1
(SRC_ID int IDENTITY,
[Description]
NVARCHAR(100));
GO

-- 2 Create Insert
trigger
CREATE TRIGGER
i_trgTable1

ON Table1
FOR INSERT AS
PRINT
GETDATE();
GO
AFTER Trigger Example:
USE
[AdventureWorks2019]
GO

CREATE TRIGGER
trg_OrderDetailNotDisc
AS
ontinued
-- Prevent
ON [Sales]. for discontinued
orders IF items AFTER
[SalesOrderDetail]
EXISTS (
INSERT, UPDATE
SELECT 1
FROM Production.Product p
JOIN
INSERTED
ON i
i.productid = p.productid
WHERE p.DiscontinuedDate < GETDATE()
)
BEGI
N
R
A
I
INSERTED • Inserted and Deleted virtual tables are
and created for the trigger
• Each trigger has its own Inserted and
DELETED Deleted tables
• For every new set of values in a row,
virtual there's a row in the
tables • Inserted virtual table
• For every old set of values in a row,
there's a row in the Deleted virtual
table
• An update generates an Inserted and
Deleted row for every single update.
More on virt
ual tables
Using INSERTED and DELETED virtual
tables
USE
[test]
GO

IF
OBJECT_ID
('[dbo].
[Table2]'
, 'U') IS
NOT NULL
--DROP
Create Insert trigger
TABLE TRIGGER
CREATE ON
[dbo].T FOR UPDATE, Table2
u_trgTest
able2 DELETE AS
INSERT,
GO SELECT 'inserted', * FROM INSERTED -- Virtual table containing
INSERTED rows
SELECT
CREATE 'deleted',*
TABLE FROM
Table2(Col1 intDELETED--
IDENTITY,Virtual table containing DELETED
Col2 varchar(100),
Col3rows
int) GO
GO
-- Test trigger
INSERT INTO Table2 VALUES ('Inserted value',
1); UPDATE Table2 SET Col2 = 'Updated
value'; DELETE FROM Table2 WHERE Col1 = 1;
Using DDL triggers:
Triggered by:
CREATE
ALTER
DROP

CREATE TRIGGER tr_ddlProtectTable ON DATABASE


AFTER DROP_TABLE AS
PRINT 'Tables cannot be dropped'
ROLLBACK TRANSACTION
GO
INSTEAD OF Trigger Example
CREATE TABLE BaseTable (
PrimaryKey int PRIMARY KEY IDENTITY(1,1)
,Color varchar(10) NOT NULL
,Material varchar(10) NOT NULL
,ComputedCol AS (Color + Material)
); GO

--Create a view that contains all columns from the basetable.


CREATE VIEW InsteadView
AS
SELECT PrimaryKey, Color, Material, ComputedCol FROM BaseTable;
GO
--Create an INSTEAD OF INSERT trigger on the view.
CREATE TRIGGER InsteadTrigger ON InsteadView INSTEAD OF INSERT
AS
BEGIN
--Build an INSERT statement ignoring inserted.PrimaryKey and ComputedCol. INSERT INTO
BaseTable
SELECT Color, Material FROM inserted;
END
GO
DELETE a Trigger:
DMLTrigger:

DROP TRIGGER [schema_name.]trigger_name [ ,...n ] [ ; ]

DDLTrigger:

DROP TRIGGER trigger_name [ ,...n ] ON { DATABASE | ALL SERVER } [


; ]

Logon Trigger:

DROP TRIGGER trigger_name [ ,...n ] ON ALL SERVER

1
Writing
• What are Cursors
• Examples

Cursors •

Discussions
Pros and Cons
What is a cursor?
A cursor is a database object used by
applications to manipulate data in a set on a
row-by-row basis, instead of the typical SQL
commands that operate on all the rows in
the--set at one time.
Cursor Syntax
DECLARE cursor_name
CURSOR [LOCAL | GLOBAL] [FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE [OF column_name [,...n]]]
Steps to use a Cursor:
--Declare the cursor and associate it with a query
DECLARE <cursorname> CURSOR FOR <query>

--Open the cursor


OPEN <cursorname>;

--Fetch the first data row


FETCH NEXT FROM <cursorname> INTO <@variable>;

--Loop until the end of the cursor is reached WHILE @@FETCH_STATUS = 0 BEGIN
<SQL statements>

--Get the next row


FETCH NEXT FROM CustList INTO @customerid; END -- End the while loop

--Close the cursor


CLOSE <cursorname>;

--Release resources
DEALLOCATE <cursorname>;
• @@FETCH_STATUS
• 0 Successful
• -1 Failed
• -2 Row missing

System • @@CURSOR_ROWS
• -m The number of rows in the
Cursor keyset
• -1 Dynamic cursor

Functions:
• 0 No cursor has been
opened
• n Total number of rows
in the cursor

•3) CURSOR_STATUS
• 'local' | 'global' | 'variable'
Common Cursor Arguments
Argument Purpose
UPDATE [OF column_name] for update columns within the cursor

READ ONLY Prevents updates made through this cursor

FORWARD_ONLY Cursor can only be scrolled from first to the last row

STATIC Cursor makes a temporary copy of the data in


tempdb Data changes to base tables are not visible
KEYSET Cursor makes a keyset table in tempdb Data
changes to base tables are visible
DYNAMIC Cursor reflect all data changes as you scroll

OPTIMISTIC Update through the cursor will not succeed if the


row has been updated since it was read into the
cursor. Timestamp is used.

FAST_FORWARD FORWARD_ONLY, READ_ONLY with performance


optimizations enabled
Sample Cursor
DECLARE @customerid int; DECLARE CustList CURSOR FOR
SELECT CustomerID from Sales.Customer WHERE CustomerID IN (1,2,3,4,5,6,7,8,9,10);

OPEN CustList;

FETCH NEXT FROM CustList INTO @customerid;

WHILE @@FETCH_STATUS = 0
BEGIN
IF (SELECT COUNT(CustomerID) FROM Sales.Customer) > 0
SELECT AccountNumber FROM Sales.Customer
WHERE CustomerID = @customerid;
PRINT @customerid;

-- Loop to next record


FETCH NEXT FROM CustList INTO @customerid;
END

CLOSE CustList;
DEALLOCATE CustList; -- Required to DEALLOCATE
GO
What does this code do?
DECLARE @SPID int

DECLARE c_idleSessions CURSOR FAST_FORWARD


FOR SELECT s.spid FROM master..sysprocesses s
WHERE spid > 50
AND DATEDIFF(ss,s.last_batch,GETDATE()) > (60*30)

OPEN c_idleSessions
FETCH NEXT FROM c_idleSessions INTO @SPID;

WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'killing process: ' + CAST(@spid as NVARCHAR(5)) EXEC('kill ' + @spid)
FETCH NEXT FROM c_idleSessions INTO @spid
END

CLOSE c_idleSessions;
DEALLOCATE c_idleSessions;
GO
It depends on:
Size of the result set.
Percentage of the data likely tobe needed.
Performance of the cursor open.
Need for cursor operations, such as scrolling or
positioned updates.
Level of visibility to data modifications made by other

Choosing a users.

Simple rules:
Cursor Type Use default settings when possible.
Dynamic cursors open faster than static or keyset-driven
cursors.
In joins, keyset-driven and static cursors can be faster
than dynamic cursors.
Keyset-driven or static cursors must be used if you want
to do absolute fetches.
Keyset-driven or static cursors increase the usage of
tempdb.
Cursor Pros and Cons
Pros
They are necessary for some dynamic operations that can't be accomplished with set-based
operations.
They are simple to understand, which makes them ideal for quick-and-dirty programming
A tool of choice for beginner SQL developers or developers who are used to procedural
programming
They outperform while loops when you need row-by-row processing.
They are ideal for scrolling a portion of a large resultsset.
By default, they provide a window into your tables or results set, which maximizes concurrency
Confor
s all applications.
They are procedural iterative functions that are not like database set operations
They are resource intensive and generally slower than other application approaches
They may not scale to support processing and better options are available
They may lock table inserts or updates causing excessiveblocking
There are better alternatives for FOREACH operations
Week 6 Assignment

QUIZ 6 NO CODING THIS


WEEK

You might also like