Lập trình cơ bản: Function, khái niệm hàm, phân loại hàm trong Java (có ví dụ...
Qtu.vn sql - chuong 7
1. Chương 7: Stored procedure
1. Giới thiệu Stored Procedure
A stored procedure là một tập các lệnh Transact-SQL được đặt tên và được lưu
trên server. Stored procedures trong SQL Server được thực hiện như các procedure
trong các ngôn ngữ lập trình khác, chúng cũng có các tham số input và output. Stored
procedure trả về giá trị trạng thái của lệnh gọi là thành công hay không thành công (và
lý do thành công).
SQL Server hỗ trợ 5 loại stored procedures:
System stored procedures được lưu trong master database, tên của các
procedure này có tiếp đầu ngữ là SP_. Các procedure này cho phép người quản trị
hệ thống thực hiện các chức năng của quản trị database. Các system procedure
này có thể được gọi thực hiện trong tất cả các database.
Local stored procedures được tạo bởi các user database.
Temporary stored procedures có thể là local, có tên được bắt đầu bởi ký tự
#, hoặc global, có tên bắt đầu bởi 2 ký tự ##. Local temporary stored procedures
có thể dùng trong một session của user đã tạo ra nó; global temporary stored
procedures có thể dùng cho tất cả các session của users.
Remote stored procedures là một điểm mới của SQL Server 2000. Chúng ta
có thể thực hiện một stored procedure trên remote server. Một instance của SQL
Server 2000 có thể gởi và nhận các lệnh gọi remote stored procedure đến một
instances của SQL Server 2000 hoặc 7.0
Extended stored procedures (XP_) được thi hành như một dynamic-link
libraries (DLLs) được thực hiện bên ngoài môi trường SQL Server.
2. Xử lý của stored procedure
Xử lý ban đầu (initial processing) của một stored procedure bao gồm việc tạo và thực
thi lần thứ nhất, đó là lúc mà SQL Server đặt sơ đồ thực thi (execution plans) của stored
procedure trong procedure cache. Procedure cache một vùng nhớ chứa execution plans
cho tất cả việc thực thi các lệnh Transact-SQL.
2. Creation: Các lệnh trong procedure sẽ được phân tích cú pháp theo cú pháp của
T-SQL. Nếu thành công, tên của stored procedure được lưu trong SysObjects
table, còn text, lệnh bên trong lệnh tạo procedure, lưu trong SysComments.
Delayed Name Resolution: cho phép stored procedure tham chiếu đến các đối
tượng chưa tồn tại trong lúc procedure được tạo. Delayed Name resolution được
thực hiện trong lúc procedure được thực hiện
Execution: Lần thứ nhất procedure được thực hiện hoặc khi mà procedure phải
recompile, query processor sẽ đọc procedure trong process được gọi là resolution.
Sau giai đoạn resolution, SQL Server sẽ tạo ra execution plans trong procedure cache
Optimization: Khi một stored procedure thành công trong giai đoạn resolution, SQL
Server query optimizer sẽ phân tích các lệnh Transact-SQL trong stored procedure và
tạo ra một sơ đồ chứa phương thức tối ưu để truy xuất data.
Compilation: Compilation liên quan đến quá trình phân tích và tạo execution plan của
procedure trong procedure cache.
Xử lý tiếp theo (Subsequent processing) của stored procedures nhanh hơn xử lý
ban đầu. vì SQL Server dùng optimized execution plan trong procedure cache.
Nếu các điều kiện sau đây thoả, SQL Server sử dụng in-memory plan để thực thi
query subsequently:
- Môi trường hiện hành giống với môi trường trong plan đã được dịch. Các sắp đặt
Server, database, và connection quyết định môi trường này.
- Các đối tượng mà procedure tham chiếu không đòi hỏi name resolution. Các đối tượng
đòi hỏi name resolution khi các đối tượng cùng tên được sở hửu bởi các users khác
nhau. Ví dụ user sales sở hửu table Product, và user development cũng sở hửu table
Product , SQL Server phải quyết định table nào được dùng.
SQL Server execution plans có 2 components chính
Execution Plan: Hầu hết các execution plan nằm trong vùng này. Đây là read-only
data structure mà tất cả các users có thể sử dụng.
3. Execution Context: Mỗi user có một reusable data structure chứa các dữ liệu riêng
của họ như các giá trị parameter. Khi một user thực thi một query, và một trong
các structures không được sử dụng, nó sẽ được khởi tạo lại cho user mới.
3. Ứng dụng Stored Procedure
Stored procedure có nhiều lợi ích.
Cho phép lập trình theo hướng modular (modular programming)
Thực thi nhanh hơn
Giảm được việc chiếm dụng đường truyền mạng
Bảo mật.
Xử lý các chức năng và chia sẽ với các ứng dụng khác
• Chia sẽ dữ liệu với các ứng dụng khác, do đó bảo đảm tính nhất quán dữ
liệu.
• Stored procedures có thể thực hiện một công việc, một nhiệm vụ. Các qui
tắc của công việc này được gói gọn trong các stored procedures có thể được thay
đổi tại một vị trí. Tất cả các clients có thể sử dụng cùng stored procedures để bảo
đảm tính nhất quán của dữ liệu.
• Nếu một tập hợp các stored procedures hỗ trợ tất cả các chức năng doanh
nghiệp mà user cần phải thực hiện, user không cần phải truy xuất trực tiếp vào
table
• Cung cấp cơ chế bảo mật. User có thể gán quyền thực thi một procedure
ngay khi họ không có quyền truy xuất các tables hoặc views được tham chiếu
trong procedure.
• Tăng tính năng thực hiện.
• Giảm tải đường truyền mạng. Thay vì gởi hàng trăm lệnh Transact-SQL
qua mạng, user có thể thực hiện một thao tác phức hợp bằng việc gởi một lệnh
đơn, giảm số lượng các yêu cầu được truyền giữa client và server.
4. Tạo stored procedure
Tạo stored procedure bằng lệnh Transact-SQL:
CREATE PROCEDURE procedure_name [ ; number ]
[{@parameter data_type}[VARYING][=default][OUTPUT] ][,...n]
[WITH {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION }]
AS sql_statement [ ...n ]
Trong đó
procedure_name: là tên của stored procedure. Tên này phải tuân theo qui tắc đặt
tên và là duy nhất trong một database.
number: là phần tuỳ chọn được dùng để nhóm các procedure có cùng tên với nhau
để có thể được xoá một lần với nhau bởi lệnh DROP PROCEDURE. Ví dụ chúng
ta có thể có các procedure orderproc;1, orderproc;2 .... và khi đó lệnh DROP
PROCEDURE ORDERPROC sẽ xoá tất cả các procedure trong nhóm đó.
@parameter: là tham số của procedure. Khi procedure có tham số, giá trị các tham
số phải được cung cấp khi procedure được thực thi trừ khi tham số có khai báo
4. giá trị default. Mỗi procedure có tối đa là 2,100 tham số. Chúng ta phải dùng @
để làm ký tự đầu tiên trong tên cho tham số hình thức của procedure.
data_type: là kiểu dữ liệu của tham số bao gồm tất cảc các kiểu dữ liệu. Tuy nhiên
kiểu cursor chỉ được dùng cho OUTPUT parameters. Khi chúng ta chỉ định data
type là cursor, thì tham số VARYING và OUTPUT phải đước dùng.
VARYING: chỉ định rằng result set được hỗ trợ như một output parameter. Tham
số này chỉ áp dụng cho tham số có kiểu cursor.
default: giá trị mặc nhiên của tham số nếu user không truyền giá trị cho tham số
khi procedure được thực thi. Giá trị mặc nhiên này có thể là một giá trị hằng, hoặc
NULL, nó có thế các ký tự đại diện (%, _, [], và [^]) nếu procedure sử dụng tham
số với từ khoá LIKE.
OUTPUT: chỉ định tham có trả giá trị về. Giá trị của tham số output sẽ được trả về
khi procedure này thực thi và từ khoá OUTPUT được dùng để truyền tham số.
RECOMPILE: chỉ định rằng SQL Server sẽ recompiled procedure mỗi khi được
gọi thực hiện.
ENCRYPTION: chỉ định rằng SQL Server mã hoá lệnh tạo procedure khi lưu và
table syscomments
sql_statement: là tập lệnh Transact-SQL để thực hiện nhiệm vụ của procedure.
Thực thi stored procedure:
EXECUTE procedure_name[;number]
[ [ @parameter = ] { value | @variable [ OUTPUT ] | [ DEFAULT ] ] [ ,...n ]
[ WITH RECOMPILE ]
Sau đây là các lưu ý khi tạo proedure:
• Procedure có thể tham chiếu đến các tables, view, procedure khác cũng
như các temporary table
• Để tạo một procedure, user phải có quyền CREATE PROCEDURE
(sysadmin, hoặc database owner)
• Kích thước của một procedure tối đa là 128 MB
• Các procedure có gọi các procedure khác (nesting stored procedure).
Chúng ta có thể gọi lồng 32 cấp procedure
• Để xem lại nội dung lệnh tạo stored procedure, chúng ta thực thi system
procedure sp_helptext trong database của procedure đó với tham số là tên của
procedure.
• Không thể kết hợp lệnh create procedure với các lệnh SQL khác để tạo
thành một bó lệnh (batch)
• Chúng ta chỉ có thể tạo procedure trong database hiện hành
• Sau khi procedure được tạo thành công, tên của procedure được lưu trong
table sysobjects
5. 5. Một số ví dụ lệnh tạo stored procedure:
Ví dụ 1: Tạo procedure với tên UpdatePrice dùng để tăng 10% giá cho tất cả các mặt
hàng.
Create procedure UpdatePrice
As
update VatTu set GiaMua = GiaMua *1.1
go
Sau khi thực hiện thành công việc tạo procedure UpdatePrice, ta có thể thực thi
procedure này bằng lệnh như sau:
EXECUTE UpdatePrice
Hoặc
EXEC UpdatePrice
Ví dụ 2: Sau đây là một ví dụ về procedure có tham số. Tạo procedure sẽ xoá các
khách hàng có địa chỉ bằng với giá trị của tham số nhận.
Create procedure deletingKhachHang @diachi nvarchar(50)
As
delete KhachHang where diachi= @diachi
Chúng ta có thể thực thi procedure trên với giá trị ‘Binh Dinh’ truyền vào cho
@diachi bằng nhiều cách như sau:
EXECUTE deletingKhachHang ‘Binh Dinh’
hoặc
EXECUTE deletingKhachHang @diachi=‘ Binh Dinh’
Ví dụ 3: Sử dụng procedure có tham số có giá trị default. Tạo một procedure có
lấy ra danh sách các khách hàng có giá trị địa chỉ là tham số truyền vào.
create procedure DanhsachKhachHang @diachi nvarchar(50) = '%'
as
select * from KhachHang where diachi like @diachi
go
Chúng thực thi procedure trên với tham số truyền vào như sau:
exec DanhsachKhachHang ‘Binh Dinh’
Kết quả cho ra là danh sách các records trong table KhachHang có giá trị là ‘Binh
Dinh’. Nhưng khi thực thi procedure trên mà không truyền tham số vào, kết quả sẽ trả
về là toàn bộ các records có trong table KhachHang.
Ví dụ 4: Tạo procedure có tham số trả về (Output parameter). Xét ví dụ sau:
create proc SoluongKhachHang
@diachi varchar(50) = '%',
@total integer OUTPUT
AS
SELECT @total = count(*) FROM KhachHang
WHERE diachi LIKE @diachi
Go
6. Procedure trên dùng để đếm có bao nhiêu khách hàng có địa chỉ là tham số truyền
vào và số lượng đếm được sẽ trả về cho output parameter. Để gọi thực hiện procedure
trên, ta thực hiện đoạn mã lệnh như sau:
declare @sluong integer
exec SoluongKhachHang 'Binh Dinh', @sluong output
SELECT 'Tong so luong khach hang la:' +str(@sluong,4)
6. Cursor output parameter
Phần này chúng ta sẽ tìm hiều về cursor output parameter.
Stored procedures chỉ có thể dùng kiểu cursor cho OUTPUT parameters. Nếu kiểu
cursor được dùng cho parameter, thì cả hai tham số VARYING và OUTPUT phải được
chỉ định. Hoặc nếu từ khoá VARYING được dùng cho parameter, thì kiểu dữ liệu của
parameter đó phải là cursor và phải là OUTPUT parameter.
Chú ý rằng kiểu cursor không thể gắn với biến của các ứng dụng khác thông qua
database APIs như OLE DB, ODBC, ADO, và DB-Library. Do vậy, các stored
procedures với cursor OUTPUT parameters không thể được gọi từ database APIs. Các
procedures này có thể được gọi từ bó lệnh Transact-SQL, stored procedures, hoặc
triggers chỉ khi biến cursor OUTPUT được gán cho một biến Transact-SQL local
cursor.
Trước khi xét một vài ví dụ về cursor output parameter, chúng ta hãy tìm hiểu về
kiểu dữ liệu cursor.
Cú pháp khai báo biến kiểu cursor
DECLARE cursor_name CURSOR [LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]
Các tham số trong cú pháp trên có ý nghĩa như sau:
cursor_name: là tên của biến cursor.
LOCAL: chỉ định rằng đây là biến cục bộ trong phạm vi của bó lệnh, của
procedure hoặc trigger mà cursor được khai báo.
GLOBAL: chỉ định rằng đây là biến toàn cục trong phạm vi connection. Cursor
này có thể được tham chiếu trong bất kỳ procedure hoặc bó lệnh được thực hiện
trong một connection. Khi chúng ta không chỉ định biến cursor là local hay
global, thì mặc nhiên phạm vi này sẽ được qui định bởi thông số default to local
cursor. Mặc nhiên, thông số này là FALSE, có nghĩa là tất cả các biến cursors
mặc nhiên là global.
FORWARD_ONLY: Tham số này chỉ định rằng cursor là forward only, nghĩa là con
trỏ chỉ di chuyển từ dòng đầu đến dòng cuối mà không thể di chuyển ngược lại.
Nếu tham số này được chỉ định mà không có tham số STATIC, KEYSET, hay
7. DYNAMIC, thì cursor sẽ là DYNAMIC cursor. Khi không dùng
FORWARD_ONLY hay SCROLL, thì mặc nhiên là FORWARD_ONLY trừ khi
tham số STATIC, KEYSET, or DYNAMIC được dùng. STATIC, KEYSET, và
DYNAMIC cursors mặc nhiên là SCROLL.
STATIC: dùng tham số này để định nghĩa một cursor, dữ liệu trả về sẽ tạo ra một
bản sao chép tạm để dùng cho cursor. Tất cả các yêu cầu đến cursor sẽ được thực
hiện từ table tạm trong database tempdb; Do vậy mà việc thay đổi xãy ra trên
table cơ sở không ảnh hưởng gì đến cursor này, và cursor này không cho phép cập
nhật.
KEYSET: Chỉ định rằng các thành phần cũng như thứ tự các dòng trong cursor là
cố định khi cursor được open.
DYNAMIC: tham số này dùng để định nghĩa cursor cho phép thay đổi giá trị dữ liệu, các
thành phần cũng như thứ tự các dòng.
FAST_FORWARD: tham số này bao gồm FORWARD_ONLY, READ_ONLY. Tham
số này không thể dùng chung với SCROLL hoặc FOR_UPDATE. READ_ONLY:
không cho phép cập nhật thông qua cursor này.
SCROLL_LOCKS: khi dùng tham số này, thì tại những dòng được cập nhật hoặc xoá
thông qua cursor sẽ được khoá lại. SQL Server sẽ khoá các dòng được đọc vào cursor.
SCROLL_LOCKS không thể dùng chung với FAST_FORWARD.
OPTIMISTIC: SQL Server không khoá các dòng được đọc vào cursor. Tham số
này không được dùng chung với FAST_FORWARD
select_statement: là câu lệnh select để định nghĩa kết quả của cursor. Các từ khoá
COMPUTE, COMPUTE BY, FOR BROWSE, và INTO không được cho phép trong
lệnh select để định nghĩa cursor.
UPDATE [OF column_name [,...n]]: Chỉ định các dòng có thể được cập nhật trong
cursor. Nếu không chỉ định các cột thì mặc nhiên tất cả các cột đều có thể được cập
nhật.
Ví dụ tạo ra một cursor chứa các record trả về bởi lệnh select sau:
DECLARE KhachHang_cursor CURSOR
FOR SELECT * FROM KhachHang
OPEN KhachHang_cursor
Sau khi cursor được khai báo, chúng ta phải dùng lệnh OPEN Cursor_Name để mở
cursor. Để lấy một dòng trong cursor, chúng ta phải dùng lệnh FETCH. Cú pháp lệnh
FETCH như sau:
FETCH
[ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n } | RELATIVE { n } ]
FROM
]
{ { cursor_name } | @cursor_variable_name }
[ INTO @variable_name [ ,...n ] ]
trong đó,
8. NEXT: di chuyển đến dòng kế tiếp của dòng hiện hành. Đây là tham số default của lệnh
fetch.
PRIOR: di chuyển đến dòng trước của dòng hiện hành
FIRST: di chuyển đến record đầu.
LAST: di chuyển đến record cuối
ABSOLUTE {n}: nếu n là số dương, thì di chuyển đến dòng thứ n tính từ dòng thứ nhất.
Nếu n là số âm, thì di chuyển đến dòng n tính từ dòng cuối.
RELATIVE {n }: nếu n là số dương, thì di chuyển đến n dòng kế tiếp tính từ dòng hiện
hành . Nếu n là số âm, thì di chuyển đến n dòng trước tính từ dòng hiện hành.
cursor_name: tên của cursor
@cursor_variable_name: tên biến cursor
Is the name of a cursor variable referencing the open cursor from which the fetch should
be made.
INTO @variable_name[,...n]: cho phép dữ liệu từ các dòng vào các biến cục bộ. Danh
sách các biến phải có kiểu tương ứng với kiểu của các cột trong record set.
Sau khi lệnh FETCH thực hiện, giá trị của hàm @@FETCH_STATUS sẽ cho
chúng ta biết lệnh FETCH hợp lệ (có giá trị bằng 0) hay đã đến EOF (khác 0). Chúng ta
có thể sử dụng giá trị trả về của @@FETCH_STATUS để kiểm tra điều kiện vòng lập
khi duyệt tòan bộ các record của cursor.
Ví dụ sau đây khai báo cursor cho các record trong table KhachHang và
sử dụng FETCH NEXT để duyệt qua các record.
DECLARE KhachHang_cursor CURSOR FOR
SELECT TenKH FROM KhachHang WHERE TenKH LIKE "B%"
ORDER BY TenKH
OPEN KhachHang_cursor
-- di chuyển đến record đầu.
FETCH NEXT FROM KhachHang_cursor
--Kiểm tra @@FETCH_STATUS --để xem có còn dòng nào nữa hay không
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM KhachHang_cursor
END
CLOSE KhachHang_cursor
DEALLOCATE KhachHang_cursor
GO
Một ví dụ khác dùng để tạo một cursor và đổ dữ liệu trong các dòng của cursor ra
các biến rồi in ra màn hình.
-- Khai báo các biến để lưu các giá trị trả về bởi lệnh FETCH
DECLARE @TenKH varchar(40)
DECLARE KhachHang_cursor CURSOR FOR
SELECT TenKH FROM KhachHang WHERE TenKH LIKE "B%"
9. ORDER BY TenKH
OPEN KhachHang_cursor
-- Đọc dòng thứ nhất và lưu giá trị các cột vào các biến.
FETCH NEXT FROM KhachHang_cursor INTO @TenKH
-- Kiểm tra @@FETCH_STATUS để duyệt hết các dòng.
WHILE @@FETCH_STATUS = 0
BEGIN
-- Hiển thị các giá trị trong các biến.
PRINT "Khach hang: " + @TenKH
-- di chuyển đến dòng kế tiếp.
FETCH NEXT FROM KhachHang_cursor INTO @TenKH
END
CLOSE KhachHang_cursor
DEALLOCATE KhachHang_cursor
GO
Và bây giờ chúng ta xét một ví dụ tạo procedure có cursor output
parameter.
Lệnh đầu tiên là tạo một stored procedure mà trong đó có khai báo và mở cursor cho
table KhachHang:
CREATE PROCEDURE KhachHang_cursor
@KhachHang_cursor CURSOR VARYING OUTPUT
AS
SET @KhachHang_cursor = CURSOR FORWARD_ONLY STATIC FOR
SELECT * FROM KhachHang
OPEN @KhachHang_cursor
GO
Kế tiếp, chúng ta khai một biến local cursor, để truyền vào lệnh thực thi procedure
trên và sau đó duyệt các dòng trong cursor.
DECLARE @MyCursor CURSOR
EXEC KhachHang_cursor @KhachHang_cursor = @MyCursor OUTPUT
WHILE (@@FETCH_STATUS = 0)
BEGIN
FETCH NEXT FROM @MyCursor
END
CLOSE @MyCursor
DEALLOCATE @MyCursor
GO
7. Quản trị Stored Procedure
Cũng giống như các đối tượng khác trong database, để xoá procedure, chúng ta
dùng lệnh DROP PROCEDURE và để sửa định nghĩa procedure, chúng ta dùng lệnh
ALTER PROCEDURE. Cú pháp lệnh ALTER PROCEDURE như sau:
ALTER PROCEDURE procedure_name [ ; number ]
[ { @parameter data_type } [ VARYING ] [ = default ] [ OUTPUT ] ] [ ,...n ]
10. [ WITH { RECOMPILE | ENCRYPTION | RECOMPILE ,
ENCRYPTION } ]
AS
sql_statement [ ...n ]
Cú pháp này giống lệnh create procedure.
8. Xử lý lỗi trong stored procedure
i) Dùng lệnh RETURN CODE
Để tăng tính hiệu quả của stored procedures, chúng ta nên xử lý các thông báo về
trạng thành công hay không thành công cho user. Khi có lổi xãy ra, chúng ta cũng nên
cung cấp cho user biết thông tin về lỗi theo cách dễ hiểu nhất. Chúng ta có thể dùng lệnh
return code để thực hiện công việc này. Giá trị code trả về là 0 để chỉ sự thành công.
Hiện nay, chúng ta chỉ nên dùng giá trị từ 0 đến -14 để trả giá trị trả về.
Ví dụ sau đây dùng để tạo procedure DanhSachKhachHang để lấy các record trong
table HoaDon và KhachHang, lệnh RETURN dùng để trả về tổng số dòng được trả
về từ kết quả lệnh select.
CREATE PROCEDURE DanhSachKhachHang
@MaKH nvarchar (10)
AS
SELECT MaHD, KhachHang.MaKH
FROM HoaDon, KhachHang
WHERE HoaDon.MaKH = KhachHang.MaKH
And KhachHang.MaKH = @MaKH
RETURN (@@ROWCOUNT)
Stored procedure cũng cho phép developers tạo các thông báo lổi bằng cách thực
thi procedure hệ thống sp_addmessage. SQL Server xem các thông báo lổi hệ thống
giống như các thông báo lổi do người dùng đặt ra. Các thông báo lổi sẽ được lưu trong
table sysmessages trong database master.
Ví dụ sau đây sẽ tạo ra một user-defined error message, và khi có lỗi xãy ra, nó sẽ
được tự động lưu vào Windows aplication log.
EXEC sp_addmessage @msgnum = 50010, @severity = 10,
@msgtext = 'Customer cannot be deleted.', @with_log = 'true'
b) Hàm @@error
Ngoài ra, SQL Server cũng cung cấp cho chúng ta một hàm hệ thống chứa các
error number cho hầu hết các lệnh Transact-SQL là @@error. Giá trị trả về của
hàm này là không nếu lệnh thực hiện thành công. Chúng ta cũng có thể dùng hàm
này để quyết định xem stored procedure có lỗi hay không. Ví dụ sau đây dùng để
tạo ra procedure InsertKhachHang. Stored procedure này dùng giá trị trả về của
hàm @@error để quyết định xem có lỗi xảy ra hay không khi lệnh INSERT được
thực hiện. Nếu lỗi xảy ra, transaction sẽ roll back.
CREATE PROCEDURE InsertKhachHang
11. @MaKH nvarchar (10) = NULL,
@TenKH nvarchar (30) = NULL,
@Diachi nvarchar (50) = NULL,
@DT nvarchar (15) = NULL,
@Email nvarchar (30) = NULL
AS
BEGIN TRANSACTION
INSERT KhachHang (MaKH, TenKH, DiaChi, DT, Email)
VALUES ( @MaKH, @TenKH, @Diachi, @DT, @Email)
IF @@error <> 0
BEGIN
ROLLBACK TRAN
RETURN
END
ELSE
COMMIT TRANSACTION
c) Lệnh RAISERROR
Lệnh RAISERROR để trả về một thông báo lổi do người dùng định nghĩa, user-
defined error message.
Cú pháp lệnh RAISERROR như sau:
RAISERROR ( { msg_id | msg_str } { , severity , state } )
Trong đó, các tham số có ý nghĩa như sau:
msg_id: là một mã lỗi được lưu trong table sysmessages.
msg_str: Chuỗi thông báo lỗi. Chuỗi này tối đa dài 400 ký tự, được hỗ trợ theo
định dạng sau:
severity: là số nguyên chỉ mức độ nghiêm trọng của thông báo lỗi. Chúng ta có thể
gán giá trị này nằm trong khoảng từ 0-18, còn phạm vi 19-25 chỉ nên dùng cho
các thành viên sysadmin.
state: là số nguyên tuỳ ý từ 1 đến 127 để mô tả thông tin về trạng thái khẩn cấp của
thông báo lỗi.
Chúng ta xét ví dụ sau đây dùng lệnh RAISERROR để điều khiển lỗi như thế nào.
CREATE PROCEDURE UpdateCustomerPhone
@MaKH nvarchar (5) = NULL,
@DT nvarchar (15) = NULL
AS
IF @ MaKH IS NULL
BEGIN
PRINT 'Kiem tra lai MaKH.'
RETURN
END
/* Xem khach hang nay co ton tai hay chua? */
12. IF NOT EXISTS
(SELECT * FROM KhachHang WHERE MaKH = @MaKH)
BEGIN
RAISERROR (50010, 16, 1) --Customer not found.
RETURN
END
BEGIN TRANSACTION
UPDATE KhachHang SET DT = @DT
WHERE MaKH = @MaKH
/* Hien thi thong tin moi*/
SELECT 'Dien thoai cua ' + @MaKH + ' da thay doi thanh: ' +@DT
COMMIT TRANSACTION
GO