Stored procedure Khi cả 2 câu lệnh Create Procedure và Execute chứa mục chọn OUTPUT cho tên một tham số, thủ tục có thể sử dụng một biến để trả về trị của tham số đó đến người gọi CRE
Trang 1Chương III PROCEDURE, FUNCTION,
VIEW, TRIGGER & INDEX
Trang 3Trả về các thông báo cho biết thủ tục thực hiện thành
công hay thất bại
Trang 41 Stored procedure
4
Các lợi ích của stored procedure:
Cho phép module hóa các công việc và thực thi các câu lệnh dễ dàng hơn
Tối ưu hóa việc phân tích, biên dịch và thực thi câu lệnh
Thực hiện một yêu cầu bằng một câu lệnh đơn giản hơn thay vì phải sử dụng nhiều dòng lệnh SQL khi thực thi làm giảm thiểu sự lưu thông trên mạng
Tăng khả năng bảo mật khi cấp phát quyền thông qua thủ tục
Trang 51 Stored procedure
Tạo thủ tục tên danh sách có tham số truyền vào là tên nhân viên Liệt kê mã nhân viên, họ lót, tên
nhân viên, ngày vào làm, lương:
CREATE PROC sp_danhsach @ten nvarchar(20) AS
SELECT MaNV, HoLot, TenNV, NgayVaoLam, Luong
FROM NhanVien
Trang 6 Thực thi: sp_danhsach 'Linh‘ hoặc
exec sp_danhsach ‘Linh’
Trang 7SELECT * FROM NhanVien WHERE TenNV = @ten
Thực thi: sp_danhsach1 ‘Duy’
Trang 8Thực thi: asc_salary 100, 1
(chú ý thứ tự giá trị truyền vào theo đúng tham số)
Hoặc thực thi: asc_salary (@ascsalary=100, @idemp=1)
(Nếu thực thi câu lệnh tường minh có thể hoán đổi vị trí
các tham sô)
Trang 91 Stored procedure
Tạo thủ tục tăng lương nhân viên với tham số đầu vào là mã nhân viên Nếu lương nhân viên lớn hơn 1000$ thì tăng 150$, ngược lại tăng 100$
CREATE PROC asc_salary(@idemp int) AS
DECLARE @salary INT BEGIN
SELECT @salary=Luong FROM NhanVien
WHERE MaNV=@idemp
If @salary>1000 BEGIN
UPDATE NhanVien SET Luong=Luong+150 WHERE MaNV=@idemp
END
Trang 10UPDATE NhanVien SET Luong=Luong+50 WHERE MaNV=@idemp SET @count=@count+1 END
END
Trang 111 Stored procedure
Thông tin trả về các thủ tục:
Các thủ tục có thể trả về giá trị số nguyên để thông báo thủ tục thực hiện thành công hay thất bại SQL Server định nghĩa sẵn tập các giá trị trả về nằm
trong khoảng [-99;0] Giá trị 0 cho biết thủ tục thực hiện thành công, các giá trị còn lại cho biết nguyên nhân lỗi xảy ra.
Trang 121 Stored procedure
12
Ngoài ra, người dùng có thể định nghĩa giá trị trả
về bằng cách bổ sung một tham số vào câu lệnh RETURN Tất cả các số nguyên đều được chấp nhận ngoại trừ các số do hệ thống định nghĩa và sử dụng
CREATE PROC sp_vidu @ten nvarchar(20) AS
IF EXISTS (SELECT *
FROM NhanVien WHERE TenNV = @ten)
RETURN 1 ELSE
RETURN 2
Trang 141 Stored procedure
14
Tạo thủ tục với tham số mặc định
CREATE PROC sp_testdefault @MaNV int =3 AS
SELECT * FROM NhanVien WHERE MaNV=@MaNV
Thực thi thủ tục:
Exec sp_testdefault
Hoặc
Exec sp_testdefault 4
Trang 151 Stored procedure
Khi cả 2 câu lệnh Create Procedure và Execute
chứa mục chọn OUTPUT cho tên một tham số, thủ tục có thể sử dụng một biến để trả về trị của tham
số đó đến người gọi
CREATE PROC Chia @sobichia real,@sochia real,
@ketqua real OUTPUT
AS
IF (@sochia =0) Print ‘Loi chia cho 0’
Trang 161 Stored procedure
16
Thực thi thủ tục:
DECLARE @ketqua real
EXEC Chia 100, 2, @ketqua OUTPUT
SELECT @ketqua
Thực thi thủ tục
DECLARE @ketqua real EXEC Chia 100, 0, @ketqua OUTPUT SELECT @ketqua
Trang 171 Stored procedure
Tạo thủ tục với tham số đầu ra là lương nhân viên với tham
số đầu vào là mã nhân viên
CREATE PROCEDURE salary (@idemp int, @salary int
DECLARE @salary int
EXEC salary 5, @salary=@salary OUTPUT
Trang 18SELECT @sumsalary=SUM(Luong) FROM NhanVien
WHERE MaPB=@deptid
RETURN
If @sumsalary IS NULL SET @sumsalary=0 END
Trang 191 Stored procedure
Thự c thi thủ tục:
DECLARE @sumsalary, @result
EXEC @result=sum_salary 44,@sumsalary OUTPUT
Trang 201 Stored procedure
20
Tạo thủ tục gọi trực tiêp:
CREATE PROC count_rows (@name Nvarchar(50))
WITH EXECUTE AS CALLER
AS
EXECUTE(‘SELECT COUNT(*) FROM ‘ + @name)
Tạo thủ tục gọi bởi người tạo ra thủ tục:
CREATE PROC count_rows_as_me (@name
Trang 211 Stored procedure
Tạo thủ tục thực thi bởi người dùng:
CREATE PROC count_rows_as_user1 (@name
Trang 221 Stored procedure
22
Thực thi thủ tục:
DECLARE @sname VARCHAR(50)
SET @sname = ‘authors;drop table customers’ count_rows_as_me @sname
Trang 231 Stored procedure
Một thủ tục có thể sử dụng bất kỳ hoặc tất cả khả
năng sau để trả về giá trị:
Một hoặc nhiều giá trị
Một giá trị trả vê rõ ràng (lệnh RETURN)
Một tham sô OUTPUT
Bên trong câu lệnh Create Procedure có thể bao gồm bất kỳ câu lệnh nào trừ các câu lệnh sau: Create Procedure, Create View, Create Rule, Create
Default, Create Trigger
Trang 251 Stored procedure
Cú pháp sửa thủ tục:
Cú pháp đổi tên thủ tục:
SP_RENAME old_name, new_name
SP_RENAME sp_index, sp_index_user1
Cú pháp xóa thủ tục:
DROP PROCEDURE proc_name
DROP PROCEDURE sp_index_user1
Trang 262 Function
26
2.1 Hàm Scalar
2.2 Hàm Inline table valued
2.3 Hàm Multi statement table valued
Trang 272.1 Hàm Scalar
Hàm vô hướng trả về duy nhất một giá trị dựa trên tham số truyền vào Cú pháp như sau:
CREATE FUNCTION func_name
([parametername datatype, parameter2,…]) RETURNS (function datatype)
AS
BEGIN các_câu_lenh_của_hàm
Trang 282.1 Hàm Scalar
28
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 f_thu (@ngay datetime)
returns nvarchar(10) As
Begin declare @st nvarchar(10) select @st=case datepart(dw,@ngay)
when 1 then N'chủ nhật' when 2 then N'thứ hai’
when 3 then N 'thứ ba'
Trang 292.1 Hàm Scalar
CREATE FUNCTION f_thu(@ngay datetime)
Returns nvarchar(10) AS
Begin when 4 then N 'thứ tư' when 5 then N 'thứ năm' when 6 then N 'thứ sáu' else N 'thứ bảy'
Trang 312.2 Hàm Inline table valued
Hàm nội tuyến, trả về dạng bảng Cú pháp như sau:
CREATE FUNCTION func_name ([parameter
datatype])
RETURNS TABLE
AS
RETURN (câu_lenh_select)
Trang 322.2 Hàm Inline table valued
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
Trang 332.2 Hàm Inline table valued
Tạo hàm trả về các khách hàng tùy thuộc vào giá trị
mã khách hàng truyền vào cho tham số
CREATE FUNCTION f_KhachHang (@MaKH int) RETURNS TABLE
AS
RETURN (Select *
From KhachHang Where MaKH > @MaKH)
Trang 342.2 Hàm Inline table valued
34
Thực thi hàm:
SELECT tmp.TenKH, dh.NgayDatHang
FROM DonHang dh, dbo.f_KhachHang(3) as tmp
WHERE dh.MaKH = tmp.MaKH
Trang 352.3 Hàm Multi statement table valued
Hàm gồm nhiều câu lệnh SQL bên trong, trả vê dạng bảng.
Cú pháp như sau:
CREATE FUNCTION func_name (parameter datatype)
RETURNS @biên_bng TABLE dnh_nghia_bng
AS
BEGIN các_câu_lenh_trong_thân_hàm
RETURN END
Lưu ý: sau từ khóa RETURNS là một biến bảng được định nghĩa
và sau từ khóa RETURN cuối hàm không có tham sô
Trang 362.3 Hàm Multi statement table valued
36
returns @myKhachHang table (MaKH int, TenKH
nvarchar(50), NgayDatHang datetime) AS
Begin
If @MaKH = 0
Insert into @myKhachHang Select kh.MaKH, kh.TenKH, dh.NgayDatHang
From KhachHang kh, DonHang dh Where dh.MaKH = kh.MaKH
Trang 37
-2.3 Hàm Multi statement table valued
CREATE FUNCTION f_DSKhachHang (@MaKH int)
returns @myKhachHang table (MaKH int, TenKH
nvarchar(50), NgayDatHang datetime) AS
Begin
Else
-Insert into @myKhachHang Select kh.MaKH, kh.TenKH, dh.NgayDatHang From KhachHang kh, DonHang dh
Trang 382.3 Hàm Multi statement table valued
38
Thực thi hàm:
Select *
From f_DSKhachHang (0)
Trang 392.3 Hàm Multi statement table valued
Lệnh ALTER FUNCTION dùng để thay đổi hàm
ALTER FUNCTION f_KhachHang (@MaKH int)
Returns table
AS
Return (Select * From KhachHang
Trang 402.3 Hàm Multi statement table valued
40
Lệnh DROP FUNCTION dùng để xóa hàm
DROP FUNCTION f_KhachHang
Trang 413 View
View là một bảng logic hay ‘bảng ảo’ truy cập đến một hoặc nhiều bảng dữ liệu hoặc view khác View truy xuât dên các cột và dòng dữ liệu bên trong
bảng và hiển thị ra đúng các thông tin tối thiểu mà người sử dụng cần dùng.
Trang 423 View
42
Đối với một số view, người dùng có thể thực hiện các thao
tác thêm, xóa, sửa dữ lieu Việc thực hiện các thao tác này Phải thỏa các điều kiện sau:
- Trong câu lệnh SELECT định nghĩa view không được sử
Dụng các từ khóa DISTINCT, TOP, GROUP BY, UNION
- Các thành phần xuất hiện trong danh sách chọn của câu
Lệnh SELECT không xuất hiển các biểu thức tính toán, các
hàm gộp
- Các ràng buộc toàn vẹn trên các bảng cơ sở phải được
đảm bảo
Trang 433 View
Cú pháp tạo view:
CREATE VIEW [schema_name.] tên_view
[(column[, n])] [WITH ENCRYPTION]
AS câu_lenh_select [ ; ] [ WITH CHECK OPTION ]
Trang 443 View
44
Tạo view cho biết mã nhân viên, tên nhân viên và tên
chức vụ của nhân viên ( phòng ban có mã phòng ban là 45)
CREATE VIEW empvu45
AS
SELECT MaNV, TenNV, TenCV FROM NhanVien nv, ChucVu cv WHERE nv.MaCV=cv.MaCV and MaPB=45
Truy vấn đến view empvu45:
Select *
From empvu45
Trang 45SELECT MaNV, HoLot AS ‘FIRST NAME’, TenNV AS
‘LAST NAME’, Luong AS ‘MONTHLY_SALARY’
Trang 463 View
46
Cú pháp xóa view:
DROP VIEW [tên_schema.] tên_view
Xóa view salvu41:
DROP VIEW salvu41
Trang 474 Trigger
Trigger là một dạng đặc biệt của thủ tục lưu trữ và thực thi tự động khi người dùng áp dụng câu lệnh cập nhật dữ liệu lên một table chỉ định nhằm mục đích đảm bảo tính toàn vẹn dữ liệu Nếu trigger bị
vi phạm, câu lệnh sẽ không được thực thi
Trang 484 Trigger
48
Trigger được sử dụng trong các cách sau:
Có thể thay đổi đồng loạt các table có liên quan với nhau trong CSDL
Có thể không cho phép hoặc hủy bỏ những thay đổi vi phạm ràng buoc toàn vẹn tham chiêu và các giao dịch sửa đổi dữ liệu
Trang 494 Trigger
Có thể áp đặt các giới hạn phức tạp hơn những giới hạn được định nghĩa bằng ràng buộc CHECK và có thể tham chiếu đến các cột trong các bảng khác
Có thể tìm sự khác biệt giữa các trạng thái của một table trước và sau khi sửa đổi dữ liệu và lấy ra
những tác động dựa trên sự thay đổi đó
Trang 504 Trigger
50
Cơ chế hoạt động của trigger
3 biến cố kích hoạt 1 trigger
Trang 514 Trigger
Cú pháp:
CREATE TRIGGER Tên_trigger
ON tên_table| tên_view AFTER | INSTEAD OF biến_cố_kích_hoạt_trigger AS
Các câu lệnh T-SQL
Có thể thay bằng FOR After
là mặc định, chỉ định nghĩa
Trang 52VALUES(‘TV01’, ‘Tivi Sony’)
Trang 54Select * From Inserted
Select * From Deleted
Xóa dữ liệu
DELETE HANG_HOA
WHERE MaHH = ‘TV01’
Trang 554 Trigger
Các thao tác trigger phổ biến
Thêm mới mẩu tin
Xóa mẩu tin
Sửa mẩu tin
Trang 564 Trigger - Thêm mới mẩu tin
56
Kiểm tra ràng buộc dữ liệu
Khoá ngoại
Miền giá trị
Liên bộ trên một quan hệ
Liên thuộc tính trong cùng một bảng
Liên thuộc tính của nhiều bảng khác nhau
Trang 574 Trigger
Xây dựng trigger trong bảng PHIEU_XUAT để kiểm tra các ràng buộc toàn vẹn dữ liệu khi người dùng thêm mới thông tin của một phiếu xuất hàng cho một bảng hoá đơn đặt hàng trước đó Các ràng buộc toàn vẹn dữ liệu bao gồm.
Trang 58DECLARE @NgayHD datetime, @ErrMsg varchar(200)
Kiểm tra số hoá đơn đã có trong bảng DONDH không?
End
Trang 594 Trigger
Tính ra ngày đặt hàng
Select @NgayDH=NgayDH From HoaDon_DH D, Inserted I Where D.MaHD = I.MaHD
Kiểm tra ngày giao hàng phải sau ngày đặt hàng
IF @NgayDH < (Select ngayxuat From Inserted) Begin
Set @ErrMsg = ‘ngày giao hàng phải ở sau ngày:’
+ Convert(char(10), ngayDH, 103 )
Trang 604 Trigger
60
Kiểm tra ràng buộc khóa ngoại
HOADON_DH cần phải kiểm tra các RBTV dữ liệu sau:
Kiểm tra xem đơn đặt hàng bị xoá đã được xuất hàng chưa? Nếu đã được xuất rồi thì thông báo không thể xoá đơn đặt hàng được.
Ngược lại thì xoá dữ liệu liên quan bên bảng chi tiết đơn đặt hàng (CHITIET_HD)
Trang 61DECLARE @SoPX char(5), @ErrMsg char(200), @Delete_Err int
Kiểm tra xem đơn hàng đã được xuất chưa
IF EXISTS(Select MaPX From PHIEU_XUAT
Where MaHD IN(Select MaHD From Deleted))
Begin
Select @MaPX = MaPX From PHIEU_XUAT Where MaHD In(Select MaHD From Deleted) Set @ErrMsg = ‘Đơn đặt hàng đã được nhập theo ’+
Trang 624 Trigger
62
Else
Begin
Xoá tự động chi tiết các đơn đặt hàng liên quan
Delete FROM CHITIET_DH
Where MaHD In(Select MaHD From DELETED)
Set @Delete_Err = @@ERROR
End
End
Trang 634 Trigger - Sửa đổi mẩu tin
Kiểm tra ràng buộc dữ liệu
Khoá ngoại
Miền giá trị
Liên bộ trên một quan hệ
Liên thuộc tính trong cùng một bảng
Liên thuộc tính của nhiều bảng khác nhau
Trang 64 UPDATE (tên_cột) (biểu thức luận lý)
Tên_cột : tên cột mà chúng ta muốn kiểm tra xem dữ liệu tại đó có bị sửa đổi trong trigger không.
Biểu thức luận lý : trả về True khi giá trị dữ liệu của cột đã
bị sửa đổi, ngược lại trả về False khi giá trị dữ liệu của cột không bị sửa đổi
Trang 654 Trigger
Sửa đổi thông tin của một số đặt hàng bên trong bảng HOADON_DH cần phải kiểm tra các ràng buộc toàn vẹn dữ liệu sau:
Không cho phép sửa đổi dữ liệu tại cột MaDH hoặc MaKH
vì khi đó dữ liệu sẽ ảnh hưởng đến nhiều bảng.
Sửa đổi giá trị cột ngày đặt hàng thì phải đảm bảo luôn luôn trước ngày giao hàng đầu tiên của số đặt hàng đó (nếu đơn đặt hàng đã có giao hàng).
Trang 66AS Declare @MinNgayXH date, @ErrMsg varchar(200)
Khi sửa đổi các cột MaDH hoặc MaKH
IF Update(MaDH) OR Update(MaKH)
Begin
Rollback Tran Set @ErrMsg = ‘Không thể thay đổi số đặt hàng hoặc
mã khách hàng’
RaisError(@ErrMsg, 16, 1) Return
End
Trang 674 Trigger
Khi sửa đổi ngày đặt hàng
IF Update(NgayDH)
Begin
Kiểm tra đơn đặt hàng đã được xuất chưa
IF EXISTS (Select MaPX From PHIEU_XUAT PX, Deleted d
where px.madh=d.madh
Begin
Tính ra ngày nhập hàng đầu tiên
Trang 684 Trigger
68
kiểm tra giá trị ngày đăt hàng sau khi sửa đổi
phải luôn trước ngày giao hàng đầu tiên
IF @MinNgayXH < (Select NgayDH From Inserted) Begin
Rollback tran Set @ErrMsg = ‘Ngày đặt hàng phải ở trước ngày:’ + Convert(char(10), @MinNgayXH, 103)
RaisError(@ErrMsg, 16, 1) End
End
End
Trang 694 Trigger
Cài đặt trigger ngăn chặn tạo login ở cấp độ server
IF EXISTS (SELECT * FROM sys.server_triggers
WHERE name = ‘rtg_KhongTaoLoginMoi')
DROP TRIGGER rtg_KhongTaoLoginMoi
Trang 704 Trigger
70
Cho phép (enable) hoặc vô hiệu hóa (disable) trigger: ENABLE | DISABLE TRIGGER trigger_name
ON {OBJECT | DATABASE | SERVER}
Vô hieu hóa trigger rtg_KhongTaoLoginMoi:
disable trigger rtg_KhongTaoLoginMoi
Cho phép trigger rtg_KhongTaoLoginMoi hoạt động trở lại:
enable trigger rtg_KhongTaoLoginMoi
Trang 714 Trigger
Hiển thị thông tin vê các triggger:
Tất cả các đối tượng trong CSDL được liệt kê trong bảng hệ thống sysobjects Cột type trong sysobjects xác định các trigger với chữ viết tắt là TR
SELECT *
FROM sysobjects
WHERE type=‘TR’
Trang 74Biến kiểu dữ liệu cursor
CSDL quan hệ thường làm việc trên dữ liệu có
nhiều dòng mẫu tin – còn gọi là các bộ mẫu tin Ví
dụ lệnh SELECT kết quả luôn trả về nhiều dòng dữliệu hơn là một dòng dữ liệu Tuy nhiên có một sốngôn ngữ lập trình việc xử lý và tính toán dữ liệutrên từng dòng riêng lẻ Để đáp ứng được yêu cầunày SQL Server tạo ra một kiểu dữ liệu đó chính làkiểu cursor
Trang 75Biến kiểu dữ liệu cursor
Trang 76Biến kiểu dữ liệu cursor
Các bước sử dụng kiểu dữ liệu cursor
Định nghĩa biến kiểu cursor bằng lệnh DECLARE.
Trang 77Biến kiểu dữ liệu cursor
Cú pháp định nghĩa biến có kiểu cursor
DECLARE Tên_cursor CURSOR[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | DYNAMIC | KEYSET]
[READ_ONLY | SCROLL_LOCK]
Trang 78Biến kiểu dữ liệu cursor
Trong đó:
Tên cursor: tên của biến kiểu cursor
Từ khoá LOCAL | GLOBAL: dùng chỉ phạm vi
hoạt động của biến cursor hoặc là cục bộ (local)bên trong một thủ tục
FORWARD_ONLY: đọc dữ liệu trong cursor theo
chiều đi tới duyệt từ mẫu tin đầu tiên đến mẫu tincuối cùng
Trang 79Biến kiểu dữ liệu cursor
SCROLL: Đọc dữ liệu trong cursor được phép di
chuyển tới lui, qua lại các dòng mẫu tin bên trongcursor tùy thích
Trang 80Biến kiểu dữ liệu cursor
STATIC: Đọc dữ liệu bên trong cursor tĩnh Khi đó
nếu những người dùng khác có thay đổi bên dưới
dữ liệu gốc thì các thay đổi đó sẽ không được cậpnhật tự động trong dữ liệu của cursor Bởi vì khi đó
dữ liệu trong cursor chính là dữ liệu của bảng tạm
đã được hệ thống sao chép và lưu trữ trong CSDLtempdb của hệ thống khi định nghĩa cursor