Công việc lập trình luôn đòi hỏi khả năng tái sử dụng mã lệnh Không những vậy, các đoạn mã lệnh được tái sử dụng còn phải có tính uyển chuyển, xử lý linh động theo từng tình huống sử dụng. Từ đó xuất hiện khái niệm lập trình hướng thủ tục (functional). Các thủ tục được gọi lại và điều khiển thông qua hệ thống tham số
Trang 25.7 Phát biểu điều khiển
5.8 Tham số với giá trị mặc định
5.9 Sửa đổi thủ tục
5.10 Xoá thủ tục
Trang 35.1 Giới thiệu thủ tục
• Công việc lập trình luôn đòi hỏi khả năng tái
sử dụng mã lệnh
• Không những vậy, các đoạn mã lệnh được
tái sử dụng còn phải có tính uyển chuyển, xử
lý linh động theo từng tình huống sử dụng
• Từ đó xuất hiện khái niệm lập trình hướng
thủ tục (functional) Các thủ tục được gọi lại
và điều khiển thông qua hệ thống tham số
Trang 45.1 Giới thiệu thủ tục
•Việc lập trình trên CSDL cũng không ngoại lệ Trong môi trường SQL Server, các thủ tục được gọi là thủ tục thường trú (stored procedure – SP)
•Thường trú: Chỉ dịch 1 lần, từ đó lưu trũ bền vững trong CSDL, bền vững tựa như các table Bất cứ khi nào cần, ta chỉ việc gọi thực hiện
Trang 55.1 Giới thiệu thủ tục
•Tính tái sử dụng, uyển chuyển nhờ hệ thống tham số
•Khi biên dịch SP, SQL Server tối ưu hóa
nó sao cho thực thi hiệu quả nhất Kết quả tối ưu hóa được lưu bền vững Khi gọi thực thi không cần tối ưu hóa lại lời gọi thủ tục tiết kiệm thời gian và tài nguyên hơn khối lệnh tương đương thân thủ tục
•Ứng dụng triển khai theo môi trường client-server Client gửi lời gọi SP lên server thì chiếm dụng đường truyền ít hơn rất nhiều so với việc gửi khối lệnh tương đương thân hàm tránh nghẽn đường truyền, giảm trì trệ
Trang 65.2 Phân loại thủ tục
Trong SQL Server 2005 có 3 nhóm thủ tục nội tại sau:
•Nhóm thứ nhất là do người dùng tạo ra
Nó bao gồm hai loại:
- Loại thủ tục nội tại được
người dùng tạo ra và lưu vào CSDL Chúng chứa các phát biểu T-SQL.
- Loại thứ hai được khai báo và
tạo ra bằng ngôn ngữ lập trình NET.
Trang 7- Danh sách các thủ tục nội tại
hệ thống hiển thị trong ngăn System Stored Procedure
- Thủ tục nội tại trong CSDL
Resource luôn có tên với tiền
tố là sp_ Do đó bạn không nên đặt tên thủ tục nội tại do mình tạo ra bằng tiền tố này.
Trang 85.2 Phân loại thủ tục
•Nhóm thứ hai là thủ tục nội tại hệ thống
thực hiện các chức năng quản trị CSDL thường dùng Các thủ tục này chứa trong CSDL
Resource.
- Danh sách các thủ tục nội tại hệ
thống hiển thị trong ngăn System Stored Procedure
- Thủ tục nội tại trong CSDL Resource
luôn có tên với tiền tố là sp_ Do đó bạn không nên đặt tên thủ tục nội tại do mình tạo ra bằng tiền tố này.
•Nhóm thứ ba là thủ tục nội tại hệ thống mở rộng Loại này cũng được lưu trong CSDL
Resouce nhưng có tên bắt đầu với xp_.
Trang 95.3 Tạo thủ tục
•Trong khung Object Explorer, chọn
Database chứa thủ tục nội tại cần tạo, chọn Programmability Kích nút phải chuột lên
mục Stored Procedures chọn New Stored
Procedure, cửa sổ Query xuất hiện cho phép bạn soạn thảo câu lệnh T-SQL để tạo thủ
tục Cú pháp tạo thủ tục nội tại như sau:
CREATE PROCEDURE tên_thủ_tục
[(danh_sách_tham_số)]
[WITH RECOMPILE |ENCRYPTION ]
AS
Các_câu_lệnh_của_thủ_tục
Trang 105.3 Tạo thủ tục
Ví dụ 1: Viết thủ tục cho biết danh sách
sinh viên của một lớp có mã cho trước
Creste proc DS_Lop @MaLop Varchar (10)
AS
Select Sinhvien.MaSV, SinhVien.HoDem, SinhVien.Ten,
SinhVien.NgaySinh
From SinhVien Where SinhVien.MaLop= @MaLop Go
Trang 11•Lên danh sách nhập điểm thi môn công nghệ
phần mềm cho các sinh viên học lớp có mã dl01
(tức là chèn thêm vào bảng DIEMTHI các bản ghi
với cột MAHOCPHAN nhận giá trị cnpm, cột
MASV nhận giá trị lần lượt là mã các sinh viên
học lớp có mã dl01 và các cột điểm là NULL).
Trang 12cú pháp :
•EXECUTE|EXEC tên_thủ_tục
[danh_sách_các_đối_số]
Trang 135.3 Lời gọi thủ tục
Thứ tự của các đối số được truyền cho
thủ tục có thể không cần phải tuân theo thứ
tự của các tham số như khi định nghĩa thủ tục nếu tất cả các đối số được viết dưới
dạng:
@tên_tham_số = giá_trị
Trang 145.4 Lời gọi thủ tục
Ví dụ:
•Cách 1:
spLenDanhSachDiem 'cnpm','Công nghệ phầm mềm',3,'dl01'
Trang 155.5 Khai báo và sử dụng biến5.5.1 Khai báo biến
DECLARE @tên_biến kiểu_dữ_liệu
•Tên biến phải bắt đầu bởi ký tự @ và tuân theo qui tắc về định danh
•Tất cả các biến sau khi khai báo sẽ có giá trị khởi tạo là Null
•Ví dụ:
DECLARE @hodem NVARCHAR(30)
Trang 165.5.2 Phát biểu Set
•Phát biểu Set dùng để gán giá trị cho
các biến Cú pháp của phát biểu Set như
Set @Tong=0; Set @dem=0
Set @max=(Select max(diemlan1) from DIEMTHI where mahocphan='sql')
Trang 175.5.2 Phát biểu SetChú ý:
Nếu sử dụng phát biểu SET với phát biểu SELECT, bạn bảo đảm phát biểu SELECT
này trả về giá trị đơn Nếu phát biểu SELECT trả về nhiều giá trị thì lỗi sẽ phát sinh
Trang 185.5.3 Phát biểu Select để gán
giá trị
Một trong những điểm mạnh của phát
biểu Select khi sử dụng để gán giá trị cho biến là cùng một lúc có thể lấy giá trị từ
CSDL và gán vào nhiều biến
Ví dụ:
•Select @max=10, @min=0, @tong=0
•Select @max= max(diemlan1),
@min=min(diemlan1) from DIEMTHI where mahocphan='sql'
Trang 195.6 Giá trị trả về của tham số trong
thủ tục
•Xét câu lệnh sau đây
CREATE PROCEDURE sp_Conghaiso(@a
INT,@b INT, @c INT)
Trang 205.6 Giá trị trả về của tham số trong
thủ tục
•Nếu muốn giữ lại giá trị của đối số
sau khi kết thúc thủ tục, bạn phải khai
báo tham số theo cú pháp như sau:
@tên_tham_số kiểu_dữ_liệu OUTPUT
hoặc:
@tên_tham_số kiểu_dữ_liệu OUT
•Và trong lời gọi thủ tục, sau đối số
được truyền cho thủ tục, bạn cũng phải
chỉ định thêm từ khoá OUTPUT (hoặc
OUT)
Trang 215.6 Giá trị trả về của tham số trong
thủ tục
Định nghĩa lại thủ tục ở ví dụ trên như
sau:
CREATE PROCEDURE sp_Conghaiso(
@a INT, @b INT, @c INT OUTPUT)
AS
SELECT @c=@a+@b
Trang 225.6 Giá trị trả về của tham số trong
thủ tục
Thực hiện lời gọi thủ tục trong một
tập các câu lệnh như sau:
DECLARE @tong INT
Trang 235.7 Cấu trúc điều khiển
Trang 245.7.1 Cấu trúc If Else
Cấu trúc như sau :
IF <Biểu thức điều kiện>
Trang 255.7.1 Cấu trúc If Else
Ví dụ 1: Viết thủ tục đưa vào một masv Nếu sinh viên đó là Nam thì hiện ra câu
thông báo “Chúc anh sức khỏe” ngược lại
nếu sinh viên đó là Nữ hiện ra câu thông
báo “Chúc chị sức khỏe”
Ví dụ 2: Viết thủ tục yêu cầu đưa vào hai
mã sinh viên và in ra câu ai sinh trước hơn ai
Trang 265.7.2 Cấu trúc While
•Cấu trúc điều khiển While cho phép
chúng ta lặp lại thực thi tập lệnh cho đến khi biểu thức điều kiện là False Cấu trúc Cấu trúc điều khiển While như sau:
WHILE <Biểu thức điều kiện>
<Các câu lệnh SQL>
Trang 27Ví dụ: Viết thủ tục in ra tổng của các số từ 1 n.
CREATE PROCEDURE Tinhtong(@n int)
Trang 285.7.3 Phát biểu Continue
•Phát biểu Continue cho phép bạn bỏ
qua các khai báo ngay sau nó trong vòng lặp While
•Phát biểu này thường được sử dụng với Cấu trúc điều khiển While
Trang 29Viết thủ tục thực hiện in ra tổng các số lẻ từ 1 n.
CREATE PROCEDURE Tong_so_le(@n int)
Print @tong
END
Trang 305.7.4 Phát biểu Break
Phát biểu Break cho phép bạn thoát khỏi vòng lặp hay rẽ nhánh
Ví dụ 1: Viết thủ tục kiểm tra một số
nguyên đưa vào có phải là số nguyên tố
không
Trang 31CREATE PROCEDURE (@n int)
Trang 325.7.5 Phát biểu Return
•Khi cần trả về một giá trị nào đó Chúng
ta sử dụng phát biểu Return Nếu gặp phát biểu Return, quá trình xử lý sẽ kết thúc
•Trong thủ tục đôi khi chúng ta sử dụng phát biểu Reture để Strored Procedure trả
về giá trị tương tự như hàm Cú pháp phát biểu này như sau:
RETURN [Giá trị nguyên]
Trang 33Ví dụ: Viết thủ tục đưa vào một mã sinh viên, thủ tục xuất ra số môn thi
lần một không đạt của sinh viên đó.
CREATE PROCEDURE THILAI(@MASV
masv=@masv)
Return @countEND
Trang 345.7.5 Phát biểu Return
•Sau khi đã tạo thủ tục THILAI, bạn thực
thi một tập các câu lệnh như sau:
Declare @dem int
Exec @dem=thilai 'dl01-002'
Print N'Số môn thi lại '+ Str(@dem)
Trang 355.7.6 Cấu trúc Try Catch
Cấu trúc Try Catch trong SQL
Server 2005 được dùng để bắt lỗi
tương tự như trong C# và C++.
Một nhóm các lệnh được đặt trong khối Try, nếu có một lỗi xuất hiện bên trong khối Try thì điều khiển được gởi đến một nhóm lệnh khác được đặt
trong một khối Catch
Trang 375.7.6 Cấu trúc Try Catch
Một số thông tin về lỗi:
•ERROR_NUMBER(): Trả về mã số lỗi.
•ERROR_SEVERITY(): Trả về mức độ của lỗi.
•ERROR_STATE(): Mã trạng thái của lỗi.
•ERROR_PROCEDURE(): Trả về tên của thủ tục hay trigger xuất hiện lỗi.
•ERROR_LINE(): Trả về số dòng bên trong thủ tục xuất hiện lỗi.
•ERROR_MESSAGE(): Trả về dòng văn bản thông báo lỗi một cách đầy đủ.
Các hàm này trả về Null nếu nó được gọi bên ngoài của khối Catch.
Trang 38Ví dụ: Điều khiển lỗi trong thủ tục chia hai số
CREATE PROCEDURE phepchia(@sobichia float, @sochia float)
end try begin catch SELECT
ERROR_NUMBER() AS ErrorNumber, ERROR_SEVERITY() AS ErrorSeverity, ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure, ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
Print N'Số chia bằng không' end catch
Trang 425.7.7 Phát biểu Case
Ví dụ 1: Để hiển thị mã, họ tên và giới
tính (nam hoặc nữ) của các sinh viên, bạn
Trang 435.7.7 Cấu trúc CaseHoặc:
Trang 44•Nếu 9>Điểm >=8 hiển thị giỏi
•Nếu 8>Điểm >=7 hiển thị khá
•Nếu 7>Điểm >=5 hiển thị trung bình
•Điểm<5 hiển thị yếu
Trang 455.8 Tham số với 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
Trang 46CREATE PROC sp_TestDefault(
@tenlop NVARCHAR(30)=NULL,
@noisinh NVARCHAR(100)='Huế' AS
Trang 475.8 Tham số với giá trị mặc định
Thực hiện các lời gọi thủ tục 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 dữ
liệu 2 sinh tại Huế:
sp_testdefault @tenlop=N'dữ liệu 2'
Trang 485.8 Tham số với giá trị mặc định
•Cho biết họ tên của các sinh viên sinh
tại Quảng nam
sp_testDefault @noisinh=N'Quảng
nam'
•Cho biết họ tên của các sinh viên lớp đồ
họa 3 sinh tại Đà Nẵng:
sp_testdefault @tenlop=N'Đồ họa
3',@noisinh=N'Đà Nẵng'
Trang 495.9 Sửa đổi thủ tục
•Kích nút phải chuột lên thủ tục cần sửa,
chọn Modify, cửa sổ Query xuất hiện cho
phép bạn hiệu chỉnh lại câu lệnh T-SQL để sửa đổi thủ tục Cú pháp sửa đổi thủ tục nội tại như sau:
ALTER PROCEDURE tên_thủ_tục
Trang 505.10 Xoá thủ tục
•Kích nút phải chuột lên thủ tục cần xóa, chọn Delete Hoặc có thể sử dụng câu lệnh DROP PROCEDURE với cú pháp như sau:
DROP PROCEDURE tên_thủ_tục
Trang 515.11 KIỂU DỮ LIỆU CURSOR (CON
TRỎ)
5.11.1 Giới thiệu Cursor
5.11.2 Quá trình xử lý của Cursor 5.11.3 Khai báo Cursor trong thủ
tục
Trang 525.11.1 Giới thiệu Cursor
Kiểu dữ liệu Cursor được sử dụng trong
trường hợp tính toán trên tập bản ghi, nên
nó cho phép bạn định vị được bản ghi cần xử
lý trong tập dữ liệu Bạn cũng có thể lấy ra một hoặc nhiều bản ghi từ vị trí hiện hành
trong tập dữ liệu kết quả
•Cursor cũng cho phép cập nhật bản ghi trong tập dữ liệu tại vị trí Cursor hiện hành Bên cạnh đó, bạn cũng có thể cho phép che dấu hay hiển thị bản ghi trong tập dữ liệu
Trang 535.11.1 Giới thiệu Cursor
•SQL Server 2005 cung cấp hai phương thức để gọi Cursor là T-SQL và hàm
Database API (Application Programming
Interface) Trong đó, loại phương thức T-SQL dùng ngôn ngữ T-SQL có cú pháp hỗ trợ sử dụng Cursor theo các chuẩn sau SQL-92
Loại phương thức Database API bao gồm
hàm trong đối tượng ADO, OLE DB, ODBC
•Chú ý: Một ứng dụng không nên lẫn lộn giữa hai phương thức gọi Cursor
Trang 545.11.2 Quá trình xử lý của CursorMặc dù Cursor loại T-SQL và API có cú pháp khác nhau nhưng quá trình xử lý đều theo quy trình tổng quát sau:
•Kết hợp một Cursor với tập bản ghi từ phát biểu T-SQL và định nghĩa đặc tính của Cursor ứng với tập bản ghi cần cập nhật.
•Thực thi phát biểu T-SQL để trỏ đến Cursor.
•Lấy ra những bản ghi trong Cursor bạn
muốn, hành động này được gọi là fetch Sau
đó, di chuyển đến những bản ghi kế tiếp.
•Thực hiện các thao tác xóa, sửa dữ liệu
(nếu cần) tại dòng hiện thời trong Cursor.
•Đóng Cursor
Trang 555.11.2.1 Khai báo Cursor
•Khai báo Cursor sử dụng T-SQL có cú
pháp như sau:
DECLARE Tên_Cursor [INSENSITIVE] [SCROLL]
CURSOR FOR Câu_lệnh_Select
[FOR {READ ONLY| UPDATE [ OF
tên_cột [,…n]]} ]
Trang 565.11.2.1 Khai báo Cursor
•INSENSITIVE: Cho phép bạn định nghĩa
Cursor ứng với bản sao tập dữ liệu tạm thời
dùng cho Cursor Mọi đòi hỏi của Cursor đều
được lấy từ tập dữ liệu này trong CSDL tempdb.
•SCROLL: Chỉ định tùy chọn lấy bản ghi theo
hình thức NEXT, PRIOR, FIRST, LAST, ABSOLUTE, RELATIVE Đối với trường hợp không khai báo
tùy chọn này trong khai báo Cursor thì NEXT là tùy chọn mặc định.
•READ ONLY cho phép bạn ngăn ngừa cập
nhật hay xóa dữ liệu trên Cursor.
•UPDATE [ OF tên_cột [,…n]: Cột cho phép
cập nhật Nếu chỉ định trong tùy chọn này thì
bạn chỉ có thể cập nhật dữ liệu trong những cột này
Trang 575.11.2.1 Khai báo Cursor
•Khai báo biến Cursor_Hocphan như
sau
DECLARE Cursor_Hocphan CURSOR
FOR Select * from hocphan
Trang 585.11.2.2 Mở Cursor
Sau khi khai báo biến Cursor, bạn có thể
mở Curosr theo cú pháp sau:
•OPEN Tên_Cursor
•Ví dụ: OPEN Cursor_Hocphan
Trang 595.11.2.3 Lấy dữ liệu
Tùy thuộc vào cột dữ liệu mà phát biểu
SELECT trả về, bạn có thể sử dụng phát biểu FETCH với cú pháp như sau:
Trang 605.11.2.3 Lấy dữ liệu
•NEXT: Cho phép lấy bản ghi ngay sau
bản ghi hiện hành và chỉ định bản ghi vừa lấy ra là bản ghi hiện hành
•PRIOR: Cho phép lấy bản ghi trước bản ghi hiện hành và chỉ định bản ghi này là bản ghi hiện hành
•FIRST: Cho phép lấy bản ghi đầu tiên và chỉ định bản ghi này là bản ghi hiện hành
•LAST: Cho phép lấy bản ghi cuối cùng và chỉ định bản ghi này là bản ghi hiện hành
Trang 615.11.2.3 Lấy dữ liệu
•ABSOLUTE {n| @nvar}:
thì cho phép lấy ra bản ghi thứ
n so với bản ghi đầu tiên rồi
chỉ định bản ghi này là bản ghi hiện hành tính từ trên xuống.
cho phép lấy ra bản ghi thứ n
so với bản ghi cuối cùng rồi
chỉ định bản ghi này là bản ghi hiện hành tính từ dưới lên.
Trang 625.11.2.3 Lấy dữ liệu
•RELATIVE {n| @nvar}:
thì cho phép lấy ra bản ghi thứ
n so với bản ghi hiện hành rồi chỉ định bản ghi này là bản ghi hiện hành tính từ trên xuống.
cho phép lấy ra bản ghi thứ n
so với bản ghi hiện hành rồi
chỉ định bản ghi này là bản ghi hiện hành tính từ dưới lên
Trang 635.11.2.3 Lấy dữ liệu
•Ví dụ: Để lấy dữ liệu của các cột khai báo trong phát biểu SQL vào các biến cục bộ thì bạn khai báo như sau
DECLARE @Mahocphan nvarchar(10)
DECLARE @Tenhocphan nvarchar(50)
DECLARE @Sotinchi smallint
FETCH NEXT FROM Cursor_Hocphan
INTO @Mahocphan, @Tenhocphan,
@Sotinchi
Trang 645.11.2.4 Duyệt bản ghi
Để duyệt qua từng bản ghi trong Cursor,
bạn có thể sử dụng hàm @@FETCH_STATUS và phát biểu WHILE Hàm @@FETCH_STATUS trả
về giá trị 0 ứng với bản ghi lấy ra hợp lệ.
Phát biểu sau sẽ in toàn bộ dữ liệu trong
FETCH NEXT FROM Cursor_Hocphan
INTO @Mahocphan, @Tenhocphan, @Sotinchi END
Trang 655.11.2.5 Đóng và giải phóng bộ
nhớ cho biến Cursor
Sau khi kết thúc làm việc với Cursor, bạn cần khai báo để đóng Cursor và giải phóng bộ nhớ đã cấp cho nó với cú pháp như sau:
Trang 665.11.2.4 Duyệt bản ghi
Để duyệt qua từng bản ghi trong Cursor,
bạn có thể sử dụng hàm @@FETCH_STATUS và phát biểu WHILE Hàm @@FETCH_STATUS trả
về giá trị 0 ứng với bản ghi lấy ra hợp lệ.
Phát biểu sau sẽ in toàn bộ dữ liệu trong
FETCH NEXT FROM Cursor_Hocphan
INTO @Mahocphan, @Tenhocphan, @Sotinchi END
Trang 675.11.2.4 Khai báo Cursor trong thủ tục và
hàm
Phần này sẽ trình bày các khai báo Cursor trong thủ tục và hàm cũng như sử dụng các
từ khóa NEXT| PRIOR | FIRST| LAST|
ABSOLUTE| RELATIVE để lấy ra bản ghi theo yêu cầu
Trang 688.3 Bảo trì cơ sở dữ liệu
8.3.1 Sao lưu dự phòng
8.3.2 Khôi phục cơ sở dữ liệu