Tham số với giỏ trị mặc định

Một phần của tài liệu baigiangsql (Trang 109 - 119)

Cỏc tham số được khai bỏo trong thủ tục cú thể nhận cỏc giỏ trị mặc định. Giỏ trị mặc định sẽđược gỏn cho tham số trong trường hợp khụng truyền đối số cho tham số khi cú lời gọi đến thủ tục.

Tham số với giỏ trị mặc định được khai bỏo theo cỳ phỏp như sau:

@tờn_tham_số kiểu_dữ_liệu = giỏ_trị_mặc_định

Vớ dụ 5.6: Trong cõu lệnh dưới đõy:

@tenlop NVARCHAR(30)=NULL, @noisinh NVARCHAR(100)='Huế') AS BEGIN IF @tenlop IS NULL SELECT hodem,ten

FROM sinhvien INNER JOIN lop

ON sinhvien.malop=lop.malop WHERE noisinh=@noisinh

ELSE

SELECT hodem,ten

FROM sinhvien INNER JOIN lop

ON sinhvien.malop=lop.malop WHERE noisinh=@noisinh AND

tenlop=@tenlop END

thủ tục sp_TestDefault được định nghĩa với tham số @tenlop cú giỏ trị mặc định là

NULL và tham s@noisinh cú giỏ trị mặc định là Huế. Với thủ tục được định nghĩa như trờn, ta cú thể thực hiện cỏc lời gọi với cỏc mục đớch khỏc nhau như sau:

• Cho biết họ tờn của cỏc sinh viờn sinh tại Huế:

sp_testdefault

• Cho biết họ tờn của cỏc sinh viờn lớp Tin K24 sinh tại Huế:

sp_testdefault @tenlop='Tin K24'

• Cho biết họ tờn của cỏc sinh viờn sinh tại Nghệ An:

sp_testDefault @noisinh=N'Nghệ An'

• Cho biết họ tờn của cỏc sinh viờn lớp Tin K26 sinh tại Đà Nẵng:

sp_testdefault @tenlop='Tin K26',@noisinh='Đà Nẵng'

5.1.7 Sửa đổi thủ tục

Khi một thủ tục đó được tạo ra, ta cú thể tiến hành định nghĩa lại thủ tục đú bằng cõu lệnh ALTER PROCEDURE cú cỳ phỏp như sau:

ALTER PROCEDURE tờn_thủ_tục [(danh_sỏch_tham_số)] [WITH RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION] AS

Cõu lệnh này sử dụng tương tự như cõu lệnh CREATE PROCEDURE. Việc sửa đổi lại một thủ tục đó cú khụng làm thay đổi đến cỏc quyền đó cấp phỏt trờn thủ tục cũng như khụng tỏc động đến cỏc thủ tục khỏc hay trigger phụ thuộc vào thủ tục này.

5.1.8 Xoỏ thủ tục

Để xoỏ một thủ tục đó cú, ta sử dụng cõu lệnh DROP PROCEDURE với cỳ phỏp như sau:

DROP PROCEDURE tờn_thủ_tục

Khi xoỏ một thủ tục, tất cả cỏc quyền đó cấp cho người sử dụng trờn thủ tục đú cũng đồng thời bị xoỏ bỏ. Do đú, nếu tạo lại thủ tục, ta phải tiến hành cấp phỏt lại cỏc quyền trờn thủ tục đú.

5.2 Hàm do người dựng định nghĩa (adsbygoogle = window.adsbygoogle || []).push({});

Hàm là đối tượng cơ sở dữ liệu tương tự như thủ tục. Điểm khỏc biệt giữa hàm và thủ tục là hàm trả về một giỏ trị thụng qua tờn hàm cũn thủ tục thỡ khụng. Điều này cho phộp ta sử dụng hàm như là một thành phần của một biờu thức (chẳng hạn trong danh sỏch chọn của cõu lệnh SELECT).

Ngoài những hàm do hệ quản trị cơ sở dữ liệu cung cấp sẵn, người sử dụng cú thểđịnh nghĩa thờm cỏc hàm nhằm phục vụ cho mục đớch riờng của mỡnh.

5.2.1 Định nghĩa và sử dụng hàm

Hàm được định nghĩa thụng qua cõu lệnh CREATE FUNCTION với cỳ phỏp như sau:

CREATE FUNCTION tờn_hàm ([danh_sỏch_tham_số]) RETURNS (kiểu_trả_về_của_hàm)

AS BEGIN

cỏc_cõu_lệnh_của_hàm END

Vớ dụ 5.7: Cõu lệnh dưới đõy định nghĩa hàm tớnh ngày trong tuần (thứ trong tuần) của một giỏ trị kiểu ngày

CREATE FUNCTION thu(@ngay DATETIME) RETURNS NVARCHAR(10)

AS

DECLARE @st NVARCHAR(10)

SELECT @st=CASE DATEPART(DW,@ngay) WHEN 1 THEN 'Chu nhật' WHEN 2 THEN 'Thứ hai' WHEN 3 THEN 'Thứ ba' WHEN 4 THEN 'Thứ tư' WHEN 5 THEN 'Thứ năm' WHEN 6 THEN 'Thứ sỏu' ELSE 'Thứ bảy'

END

RETURN (@st) /* Trị trả về của hàm */ END

Một hàm khi đó được định nghĩa cú thểđược sử dụng như cỏc hàm do hệ quản trị cơ sở dữ liệu cung cấp (thụng thường trước tờn hàm ta phải chỉ định thờm tờn của người sở hữu hàm)

Vớ dụ 5.8: Cõu lệnh SELECT dưới đõy sử dụng hàm đó được định nghĩa ở vớ dụ trước:

SELECT masv,hodem,ten,dbo.thu(ngaysinh),ngaysinh FROM sinhvien WHERE malop=’C24102’ cú kết quả là: 5.2.2 Hàm với giỏ trị trả về là “dữ liệu kiểu bảng” Ta đó biết được chức năng cũng như sự tiện lợi của việc sử dụng cỏc khung nhỡn trong cơ sở dữ liệu. Tuy nhiờn, nếu cần phải sử dụng cỏc tham số trong khung nhỡn (chẳng hạn cỏc tham số trong mệnh đề WHERE của cõu lệnh SELECT) thỡ ta lại khụng thể thực hiện được. Điều này phần nào đú làm giảm tớnh linh hoạt trong việc sử dụng khung nhỡn.

Vớ dụ 5.9: Xột khung nhỡn được định nghĩa như sau:

CREATE VIEW sinhvien_k25 AS

SELECT masv,hodem,ten,ngaysinh FROM sinhvien INNER JOIN lop ON sinhvien.malop=lop.malop WHERE khoa=25

với khung nhỡn trờn, thụng qua cõu lệnh:

SELECT * FROM sinhvien_K25

ta cú thể biết được danh sỏch cỏc sinh viờn khoỏ 25 một cỏch dễ dàng nhưng rừ ràng khụng thể thụng qua khung nhỡn này để biết được danh sỏch sinh viờn cỏc khoỏ khỏc do khụng thể sử dụng điều kiện cú dạng KHOA = @thamso trong mệnh đề WHERE của cõu lệnh SELECT được.

Nhược điểm trờn của khung nhỡn cú thể khắc phục bằng cỏch sử dụng hàm với giỏ trị trả về dưới dạng bảng và được gọi là hàm nội tuyến (inline function). Việc sử dụng hàm loại này cung cấp khả năng như khung nhỡn nhưng cho phộp chỳng ta sử dụng được cỏc tham số và nhờđú tớnh linh hoạt sẽ cao hơn.

Một hàm nội tuyến được định nghĩa bởi cõu lệnh CREATE TABLE với cỳ phỏp như sau:

CREATE FUNCTION tờn_hàm ([danh_sỏch_tham_số]) RETURNS TABLE

AS

RETURN (cõu_lệnh_select)

Cỳ phỏp của hàm nội tuyến phải tuõn theo cỏc qui tắc sau:

• Kiểu trả về của hàm phải được chỉđịnh bởi mệnh đề RETURNS TABLE. (adsbygoogle = window.adsbygoogle || []).push({});

• Trong phần thõn của hàm chỉ cú duy nhất một cõu lệnh RETURN xỏc định giỏ trị trả về của hàm thụng qua duy nhất một cõu lệnh SELECT. Ngoài ra, khụng sử dụng bất kỳ cõu lệnh nào khỏc trong phần thõn của hàm.

Vớ dụ 5.10: Ta định nghĩa hàm func_XemSV như sau:

CREATE FUNCTION func_XemSV(@khoa SMALLINT) RETURNS TABLE

RETURN(SELECT masv,hodem,ten,ngaysinh FROM sinhvien INNER JOIN lop ON sinhvien.malop=lop.malop

WHERE khoa=@khoa)

hàm trờn nhận tham sốđầu vào là khúa của sinh viờn cần xem và giỏ trị trả về của hàm là tập cỏc dũng dữ liệu cho biết thụng tin về cỏc sinh viờn của khoỏ đú. Cỏc hàm trả về giỏ trị dưới dạng bảng được sử dụng như là cỏc bảng hay khung nhỡn trong cỏc cõu lệnh SQL.

Với hàm được định nghĩa như trờn, để biết danh sỏch cỏc sinh viờn khoỏ 25, ta sử dụng cõu lệnh như sau:

SELECT * FROM dbo.func_XemSV(25)

cũn cõu lệnh dưới đõy cho ta biết được danh sỏch sinh viờn khoỏ 26

SELECT * FROM dbo.func_XemSV(26)

Đối với hàm nội tuyến, phần thõn của hàm chỉ cho phộp sự xuất hiện duy nhất của cõu lệnh RETURN. Trong trường hợp cần phải sử dụng đến nhiều cõu lệnh trong phần thõn của hàm, ta sử dụng cỳ phỏp như sau để định nghĩa hàm:

CREATE FUNCTION tờn_hàm([danh_sỏch_tham_số]) RETURNS @biến_bảng TABLE định_nghĩa_bảng

AS

BEGIN

cỏc_cõu_lệnh_trong_thõn_hàm RETURN

END

Khi định nghĩa hàm dạng này cần lưu ý một sốđiểm sau:

• Cấu trỳc của bảng trả về bởi hàm được xỏc định dựa vào định nghĩa của bảng trong mệnh đề RETURNS. Biến @biến_bảng trong mệnh đề RETURNS cú phạm vi sử dụng trong hàm và được sử dụng như là một tờn bảng.

• Cõu lệnh RETURN trong thõn hàm khụng chỉ định giỏ trị trả về. Giỏ trị trả về của hàm chớnh là cỏc dũng dữ liệu trong bảng cú tờn là @biếnbảng được định nghĩa trong mệnh đề RETURNS

Cũng tương tự như hàm nội tuyến, dạng hàm này cũng được sử dụng trong cỏc cõu lệnh SQL với vai trũ như bảng hay khung nhỡn. Vớ dụ dưới đõy minh hoạ cỏch sử dụng dạng hàm này trong SQL.

Vớ dụ 5.11: Ta định nghĩa hàm func_TongSV như sau:

CREATE FUNCTION Func_Tongsv(@khoa SMALLINT) RETURNS @bangthongke TABLE

( makhoa NVARCHAR(5), tenkhoa NVARCHAR(50), tongsosv INT ) AS BEGIN IF @khoa=0

INSERT INTO @bangthongke

SELECT khoa.makhoa,tenkhoa,COUNT(masv) FROM (khoa INNER JOIN lop

ON khoa.makhoa=lop.makhoa) INNER JOIN sinhvien

on lop.malop=sinhvien.malop GROUP BY khoa.makhoa,tenkhoa

ELSE

INSERT INTO @bangthongke

SELECT khoa.makhoa,tenkhoa,COUNT(masv) FROM (khoa INNER JOIN lop (adsbygoogle = window.adsbygoogle || []).push({});

ON khoa.makhoa=lop.makhoa) INNER JOIN sinhvien

ON lop.malop=sinhvien.malop WHERE khoa=@khoa

GROUP BY khoa.makhoa,tenkhoa RETURN /*Trả kết quả về cho hàm*/ END

Với hàm được định nghĩa như trờn, cõu lệnh:

SELECT * FROM dbo.func_TongSV(25)

Cũn cõu lệnh:

SELECT * FROM dbo.func_TongSV(0)

Cho ta biết tổng số sinh viờn hiện cú (tất cả cỏc khoỏ) của mỗi khoa:

5.3 Trigger

Trong chương 4, ta đó biết cỏc ràng buộc được sử dụng để đảm bảo tớnh toàn vẹn dữ liệu trong cơ sở dữ liệu. Một đối tượng khỏc cũng thường được sử dụng trong cỏc cơ sở dữ liệu cũng với mục đớch này là cỏc trigger. Cũng tương tự như thủ tục lưu trữ, một trigger là một đối tượng chứa một tập cỏc cõu lệnh SQL và tập cỏc cõu lệnh này sẽđược thực thi khi trigger được gọi. Điểm khỏc biệt giữa thủ tục lưu trữ và trigger là: cỏc thủ tục lưu trữ được thực thi khi người sử dụng cú lời gọi đến chỳng cũn cỏc trigger lại được “gọi” tựđộng khi xảy ra những giao tỏc làm thay đổi dữ liệu trong cỏc bảng.

Mỗi một trigger được tạo ra và gắn liền với một bảng nào đú trong cơ sở dữ liệu. Khi dữ liệu trong bảng bị thay đổi (tức là khi bảng chịu tỏc động của cỏc cõu lệnh INSERT, UPDATE hay DELETE) thỡ trigger sẽđược tựđụng kớch hoạt.

Sử dụng trigger một cỏch hợp lý trong cơ sở dữ liệu sẽ cú tỏc động rất lớn trong việc tăng hiệu năng của cơ sở dữ liệu. Cỏc trigger thực sự hữu dụng với những khả năng sau:

• Một trigger cú thể nhận biết, ngăn chặn và huỷ bỏ được những thao tỏc làm thay đổi trỏi phộp dữ liệu trong cơ sở dữ liệu.

• Cỏc thao tỏc trờn dữ liệu (xoỏ, cập nhật và bổ sung) cú thểđược trigger phỏt hiện ra và tự động thực hiện một loạt cỏc thao tỏc khỏc trờn cơ sở dữ liệu nhằm đảm bảo tớnh hợp lệ của dữ liệu.

• Thụng qua trigger, ta cú thể tạo và kiểm tra được những mối quan hệ phức tạp hơn giữa cỏc bảng trong cơ sở dữ liệu mà bản thõn cỏc ràng buộc khụng thể thực hiện được.

5.3.1 Định nghĩa trigger

Một trigger là một đối tượng gắn liền với một bảng và được tự động kớch hoạt khi xảy ra những giao tỏc làm thay đổi dữ liệu trong bảng. Định nghĩa một trigger bao gồm cỏc yếu tố sau:

• Trigger sẽđược ỏp dụng đối với bảng nào?

• Trigger được kớch hoạt khi cõu lệnh nào được thực thi trờn bảng: INSERT, UPDATE, DELETE?

• Trigger sẽ làm gỡ khi được kớch hoạt?

Cõu lệnh CREATE TRIGGER được sử dụng để đinh nghĩa trigger và cú cỳ phỏp như sau:

CREATE TRIGGER tờn_trigger

ON tờn_bảng

FOR {[INSERT][,][UPDATE][,][DELETE]} AS

[IF UPDATE(tờn_cột)

[AND UPDATE(tờn_cột)|OR UPDATE(tờn_cột)] ...]

cỏc_cõu_lệnh_của_trigger

Vớ dụ 5.12: Ta định nghĩa cỏc bảng như sau:

Bảng MATHANG lưu trữ dữ liệu về cỏc mặt hàng:

CREATE TABLE mathang ( (adsbygoogle = window.adsbygoogle || []).push({});

mahang NVARCHAR(5) PRIMARY KEY, /*mó hàng*/ tenhang NVARCHAR(50) NOT NULL, /*tờn hàng*/ soluong INT, /*số lượng hàng hiện cú*/

)

Bảng NHATKYBANHANG lưu trữ thụng tin về cỏc lần bỏn hàng

CREATE TABLE nhatkybanhang (

stt INT IDENTITY PRIMARY KEY, ngay DATETIME, /*ngày bỏn hàng*/

nguoimua NVARCHAR(30), /*tờn người mua hàng*/ mahang NVARCHAR(5) /*mó mặt hàng được bỏn*/ FOREIGN KEY REFERENCES mathang(mahang), soluong INT, /*giỏ bỏn hàng*/

giaban MONEY /*số lượng hàng được bỏn*/ )

Cõu lệnh dưới đõy định nghĩa trigger trg_nhatkybanhang_insert. Trigger này cú chức năng tự động giảm số lượng hàng hiện cú khi một mặt hàng nào đú được bỏn (tức là khi cõu lệnh INSERT được thực thi trờn bảng NHATKYBANHANG).

CREATE TRIGGER trg_nhatkybanhang_insert ON nhatkybanhang

FOR INSERT AS

UPDATE mathang

SET mathang.soluong=mathang.soluong-inserted.soluong FROM mathang INNER JOIN inserted

ON mathang.mahang=inserted.mahang

Với trigger vừa tạo ở trờn, nếu dữ liệu trong bảng MATHANG là: thỡ sau khi ta thực hiện cõu lờnh:

INSERT INTO nhatkybanhang

(ngay,nguoimua,mahang,soluong,giaban) VALUES('5/5/2004','Tran Ngoc Thanh','H1',10,5200)

dữ liệu trong bảng MATHANG sẽ như sau:

Trong cõu lệnh CREATE TRIGGER ở vớ dụ trờn, sau mệnh đề ON là tờn của bảng mà trigger cần tạo sẽ tỏc động đến. Mệnh đề tiếp theo chỉ định cõu lệnh sẽ kớch hoạt trigger (FOR INSERT). Ngoài INSERT, ta cũn cú thể chỉ định UPDATE hoặc DELETE cho mệnh đề này, hoặc cú thể kết hợp chỳng lại với nhau. Phần thõn của

trigger nằm sau từ khoỏ AS bao gồm cỏc cõu lệnh mà trigger sẽ thực thi khi được kớch hoạt.

Chuẩn SQL định nghĩa hai bảng logic INSERTED và DELETED để sử dụng trong cỏc trigger. Cấu trỳc của hai bảng này tương tự như cấu trỳc của bảng mà trigger tỏc động. Dữ liệu trong hai bảng này tuỳ thuộc vào cõu lệnh tỏc động lờn bảng làm kớch hoạt trigger; cụ thể trong cỏc trường hợp sau:

• Khi cõu lệnh DELETE được thực thi trờn bảng, cỏc dũng dữ liệu bị xoỏ sẽ được sao chộp vào trong bảng DELETED. Bảng INSERTED trong trường hợp này khụng cú dữ liệu.

• Dữ liệu trong bảng INSERTED sẽ là dũng dữ liệu được bổ sung vào bảng gõy nờn sự kớch hoạt đối với trigger bằng cõu lệnh INSERT. Bảng DELETED trong trường hợp này khụng cú dữ liệu.

• Khi cõu lệnh UPDATE được thực thi trờn bảng, cỏc dũng dữ liệu cũ chịu sự tỏc động của cõu lệnh sẽđược sao chộp vào bảng DELETED, cũn trong bảng INSERTED sẽ là cỏc dũng sau khi đó được cập nhật.

Một phần của tài liệu baigiangsql (Trang 109 - 119)