Stored Procedures, Function, Trigger,
Dynamic SQL, Cursor
Introduction
Apa Itu
Smart Database ??
Database yang menyimpan “bisnis logic”Database
yang “smart”
Database yang bukan hanya sekedar menyimpan data, tetapi dapat menjalankan bisnis logic dan dapat menjaga konsistensi data, sehingga dapat bekerja sebagai database yang smart
Database yang “konsisten”
3-Tier
Architecture
Object-Object
Smart Database
Stored
Procedures
Function
Trigger
Dynamic
STORED PROCEDURES
Apakah STORED PROCEDURES itu?
a. Eksekusi yang sudah dikompilasi.
b. Mengurangi trafik client/server.
c. Efisiensi penggunaan code dan
abtraksi pemrograman.
d. Meningkatkan control
keamanan pengguna.
St
or
ed
P
ro
ce
du
re
s S
yn
ta
x
CREATE PROC[EDURE]
procedure
[
schema
[ { @
parameter
.]
[
schema
.]
data_type
} [VARYING ] [ =
default
]
[ OUT[PUT] ] ] [ ,...
n
] [WITH
Option
[,...
n
]]
AS {
sql_statement
[;][ ...
n
] | EXTERNAL NAME
assembly.class.method
}
[;]
ALTER PROCEDURE
EXEC
– Execute Procedure
EXEC
GetProducts
CREATE
PROCEDURE
[dbo].[GetProducts] AS
SELECT
ProductID, ProductName
FROM
Products
STORED PROCEDURES
Samples (2)
CREATE
PROCEDURE
OrderSummary @MaxQuantity INT
OUTPUT AS
SELECT
Ord.EmployeeID,
SummSales =
SUM
(OrDet.UnitPrice * OrDet.Quantity)
FROM
Orders AS Ord
JOIN
[Order Details] AS OrDet
ON (Ord.OrderID = OrDet.OrderID)
GROUP
BY
Ord.EmployeeID
ORDER
BY
Ord.EmployeeID
SELECT
@MaxQuantity =
MAX(Quantity
)
FROM
[Order Details]
STORED PROCEDURES
Samples (2)
DECLARE
@OrderSum INT
DECLARE
@LargestOrder INT
EXEC
@OrderSum = OrderSummary
@MaxQuantity = @LargestOrder OUTPUT
'The size of the largest single order was: '
+ CONVERT(CHAR(6), @LargestOrder)
'The sum of the quantities ordered was: '
+ CONVERT(CHAR(6), @OrderSum)
EXEC
CustomerOrder @CustID=
'WILMK'
CREATE PROCEDURE
CustomerOrder
@CustID nvarchar(5)
AS
SELECT
orderID,CustomerId,OrderDate
FROM
Orders
WHERE
CustomerID=@CustID
FUNCTION
Apakah FUNCTION itu?
Keuntungan Menggunakan FUNCTION
a. Penggunaan kembali code,
sehingga mengurangi waktu
pembuatan.
b. Menyembunyikan detail SQL.
c. Tersentralisasi, sehingga
memudahkan jika bisnis logic
mengalami perubahan.
Perbedaan STORED PROCEDURES dan FUNCTION
Function adalah
subprogram yang harus
mengembalikan nilai (menggunakan keyword
RETURN)
Function digunakan pada
perintah SELECT, tetapi stored procedures tidak dapat
digunakan didalam perintah
SELECT.
Function hanya mempunyai parameter IN, sedangkan stored procedures dapat terdiri atas parameter OUT
atau INOUT
Stored Procedure dapat
mengembalikan banyak nilai menggunakan parameter
OUT, atau tidak
mengembalikan nilai sama sekali.
Fu
nct
io
n S
yn
ta
x
CREATE FUNCTION
[schema.] function
( [@parameter [ AS ][type_schema.]
parameter_data_type [= default ]
[ ,...n ]
])
RETURNS
return_clause...
[;]
ALTER FUNCTION
DROP
FUNCTION
Ada 3 tipe User-Defined Functions :
Tipe Function
1. Scalar
2. Inline
Table-Valued
FUNCTION
Samples (1) - Scalar
CREATE FUNCTION WhichContinent (@Country nvarchar(15))
RETURNS varchar(30)
AS
BEGIN
declare @Return varchar(30)
select @Return = case @Country
when 'Argentina' then 'South America'
when 'Belgium' then 'Europe'
when 'Brazil' then 'South America'
when 'Canada' then 'North America'
when 'Denmark' then 'Europe'
when 'Finland' then 'Europe'
when 'France' then 'Europe'
else 'Unknown'
end
return @Return
FUNCTION
Samples (1) - Scalar
PRINT dbo.WhichContinent('USA')
SELECT dbo.WhichContinent(Customers.Country), customers.* FROM
FUNCTION
Samples (2) – Inline Table Valued
CREATE FUNCTION CustomersByContinent (@Continent varchar(30)) RETURNS TABLE AS RETURN SELECT dbo.WhichContinent(Customers.Country) as continent, customers.* FROM customers WHERE dbo.WhichContinent(Customers.Country) = @Continent
FUNCTION
Samples (2) – Inline Table Valued
SELECT * FROM CustomersbyContinent('North America')SELECT * FROM CustomersByContinent('South America')
FUNCTION
Samples (3) – Multi Statement Table Valued
CREATE FUNCTION dbo.customersbycountry( @Country varchar(15) )
RETURNS @CustomersbyCountryTab table ( [CustomerID] [nchar] (5), [CompanyName] [nvarchar] (40), [ContactName] [nvarchar] (30), [ContactTitle] [nvarchar] (30), [Address] [nvarchar] (60), [City] [nvarchar] (15), [PostalCode] [nvarchar] (10), [Country] [nvarchar] (15), [Phone] [nvarchar] (24), [Fax] [nvarchar] (24) ) AS BEGIN
FUNCTION
Samples (3) – Multi Statement Table Valued
INSERT INTO @CustomersByCountryTabSELECT [CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address], [City], [PostalCode], [Country], [Phone], [Fax] FROM [Northwind].[dbo].[Customers]
FUNCTION
Samples (3) – Multi Statement Table Valued
DECLARE @cnt INT
SELECT @cnt = COUNT(*) FROM @customersbyCountryTab
IF @cnt = 0
INSERT INTO @CustomersByCountryTab ( [CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address], [City], [PostalCode], [Country], [Phone], [Fax] )
VALUES ('','No Companies Found','','','','','','','','')
RETURN END
FUNCTION
Samples (3) – Multi Statement Table Valued
SELECT * FROM dbo.customersbycountry('USA')SELECT * FROM dbo.customersbycountry('CANADA')
TRIGGER
Apakah TRIGGER itu?
“Sekumpulan perintah yang secara otomatis dijalankan apabila data didalam tabel berubah
Keuntungan Menggunakan TRIGGER
a. Melakukan update data
otomatis ketika terjadi
perubahan
b. Mengimplementasikan
sistem log.
c. Validasi dan verifikasi data
sebelum data tersebut
FOR / AFTER, trigger dijalankan setelah DML Event pada tabel.
INSTEAD OF, trigger dijalankan sebelum DML Event pada tabel. INSTEAD OF dapat
dijalankan pada sebuah view.
Timing Trigger
Event Trigger
INSERT, trigger dijalankan pada saat melakukan penambahan data.
UPDATE, trigger dijalankan pada saat melakukan update data.
DELETE, trigger dijalankan pada saat data dihapus.
TRIGGER
Samples (1)
CREATE TABLE dbo.AuditTrail( AuditTrailID Int IDENTITY (1, 1) NOT NULL, TableName VarChar (50) NOT NULL,
ActionTaken Char (1) NOT NULL, ActionUser VarChar (50) NOT NULL, ActionDate DateTime NOT NULL )
ON [PRIMARY]
Column Datatype NULL
AuditTrailID Identity Not allowed TableName VarChar(50) Not allowed ActionTaken Char(1) Not allowed ActionUser VarChar(50) Not Allowed ActionDate DateTime Not Allowed
TRIGGER
Samples (1)
CREATE TRIGGER [AuditInsertUpdate] ON dbo.Products FOR INSERT, UPDATE
AS
INSERT INTO AuditTrail (TableName, ActionTaken, ActionUser, ActionDate)
VALUES ('Products', 'I', User_Name(), GetDate())
CREATE TRIGGER [AuditDelete] ON dbo.Products FOR DELETE
AS
INSERT INTO AuditTrail (TableName, ActionTaken, ActionUser, ActionDate)
TRIGGER
Samples (1)
UPDATE dbo.Products SET UnitPrice = 1
WHERE ProductID = 1
TRIGGER
Samples (2)
CREATE TABLE [dbo].[TriggerTest] ([au_id] [int] NULL,
[au_name] [varchar] (50))
CREATE TRIGGER tr_InsertConcatName ON employees
FOR INSERT AS
DECLARE @EmpID INT
DECLARE @ConcatName VARCHAR(50)
SELECT @EmpID = (SELECT EmployeeID FROM Inserted)
SELECT @ConcatName = (SELECT LastName + ', ' + FirstName FROM Inserted)
INSERT TriggerTest VALUES (@EmpID,@ConcatName)
INSERT employees (employeeid, lastname, firstname, title)
TRIGGER
Samples (2)
CREATE TRIGGER tr_UpdateConcatName ON employees
FOR UPDATE AS
DECLARE @EmpID INT
DECLARE @NewConcatName VARCHAR(50)
SELECT @EmpID = (SELECT EmployeeID FROM Inserted)
SELECT @NewConcatName = (SELECT Lastname + ', ' + Firstname FROM Inserted)
UPDATE TriggerTest SET au_name = @NewConcatName WHERE au_id = @EmpID
UPDATE employees SET firstname = 'Greg' WHERE EmployeeID = 10
TRIGGER
Samples (2)
CREATE TRIGGER tr_DeleteConcatName
ON employees FOR DELETE AS
DECLARE @EmpID INT
SELECT @EmpID =(SELECT EmployeeID FROM Deleted)
DELETE FROM TriggerTest WHERE au_id = @EmpID
DYNAMIC SQL
Apakah DYNAMIC SQL Itu?
“Suatu teknik pemrograman SQL Code yang memungkinkan menuliskan perintah SQL secara
4
Keuntungan Menggunakan DINAMIC SQL
a. Isi perintah SQL ditentukan
pada saat sebelum dieksekusi.
b. Fleksibilitas karena perintah SQL
dianggap sebagai
S
T
R
I
N
G
.
c. Tidak perlu compile ulang jika
terjadi perubahan perintah SQL.
Static SQL
Dinamic SQL
STATIC SQL
DYNAMIC SQL
Isi perintah tidak dapat dirubah pada saat eksekusi (runtime).
Isi perintah belum dapat diketahui sebelum eksekusi (runtime) shg harus ditentukan pada saat runtime.
Perintah SQL dianggap sebagai bagian dari
program. Perintah SQL dianggap sebagai string biasa sebelum proses eksekusi. Fleksibilitas rendah karena perintah SQL
dianggap sudah fix/tetap. Fleksibilitas tinggi karena perintah SQL dapat diubah-ubah pada saat eksekusi. Sebagian proses dilakukan pada saat
kompilasi sehingga secara umum performansi lebih baik dibanding Dynamic SQL.
Semua proses dilakukan pada saat
eksekusi sehingga secara umum
?
Bagaimana menjalankan
Dinamic SQL…
Membuat Query dengan
Parameter
Menggunakan
EXEC
Dynamic SQL
Samples (1)
DECLARE @City nvarchar(15)
SET @city='Paris'
SELECT * FROM customers WHERE city=@city
DECLARE @sqlCommand varchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city nvarchar(15)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = '''London'''
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = ' + @city
EXEC (@sqlCommand)
DECLARE @sqlCommand nvarchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city nvarchar(15)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = '''London'''
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = @city'
Dynamic SQL
Samples (2)
Dinamic SQL pada STORED PROCEDURE
CREATE PROCEDURE GenericTableSelect @TableName VarChar(100)
AS
DECLARE @SQL VarChar(1000)
SET @SQL = 'SELECT * FROM '
SET @SQL = @SQL + @TableName
CURSOR
Apakah CURSOR itu?
“Object database yang dapat menampung banyak data untuk dimanipulasi baris per baris.”
5
Keuntungan Menggunakan CURSOR
a. Menghasilkan data-data
spesifik sesuai kebutuhan.
b. Membantu penggunaan
stored procedure yang
berhubungan dengan
manipulasi data.
» DECLARE, mendeklarasikan cursor sehingga terbentuk di memory
Server Database.
» OPEN, mengaktifkan cursor sehingga cursor dapat
menampung data.
» FETCH, mengambil data dari cursor untuk ditampung kedalam
variabel.
» WHILE, melakukan perulangan pada cursor jika operasi FETCH berhasil.
» CLOSE, menonaktifkan cursor, tetapi bisa dibuka kembali.
» DEALLOCATE, menghapus cursor, sehingga tidak bisa dibuka
kembali.
CU
RSO
R S
yn
ta
x
DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]
OPEN { { [GLOBAL] cursor_name } | cursor_variable_name}
FETCH
[[ NEXT | PRIOR | FIRST | LAST | ABSOLUTE {n | @nvar} | RELATIVE {n | @nvar} ] FROM ] { { [GLOBAL] cursor_name } | @cursor_variable_name} [INTO @variable_name[,...n] ]
CLOSE { {[GLOBAL] cursor_name } | cursor_variable_name }
DEALLOCATE { { [GLOBAL] cursor_name } |
CURSOR
Samples
DECLARE @ProductName nvarchar(40)
DECLARE @idx int
SET @idx=1
DECLARE @getProductName CURSOR
SET @getProductName = CURSORFOR SELECT ProductName FROM Products
OPEN @getProductName
FETCH NEXT FROM @getProductName INTO @ProductName
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Product #' + CAST(@idx AS char(3)) + @ProductName
SET @idx= @idx+1
FETCH NEXT FROM @getProductName INTO @ProductName
END
CLOSE @getProductName