KHOA CÔNG NGHỆ THÔNG TIN
Chương 4
T-SQL PROGRAMING
LOGO
I. KHAI BÁO VÀ SỬ DỤNG BIẾN
Có 2 loại biến: Cục bộ và toàn cục
1. Biến cục bộ:
Định nghĩa: là biến chỉ sử dụng trong đoạn chương
trình khai báo nó như Query Batch, stored procedure/
function , chứa giá trị thuộc một kiểu nhất định.
Biến cục bộ được bắt đầu bằng 1 ký hiệu @
Khai báo:
Declare <@tên_biến> <Kiểu_dữ_liệu >, …
Ví dụ:
Declare @MaSinhVien char(10)
Declare @Gioitinh bit, @Ngaysinh SmallDateTime
Gán giá trị cho biến
Cú pháp
Set @tên_biến = {giá_trị | biến |
biểu_thức | Cấu trúc Select }
Ví dụ
Set @MaLop = ‘TH2001’
Set @SoSV = (select count (*) from SinhVien)
Set @MaLop = ‘TH’+Year(@NgayTuyenSinh)
Chú ý: Kết quả lệnh Select chỉ cho một giá trị
(không thể nhiều bộ giá trị)
Gán giá trị của cột tại dòng hiện tại hoặc dòng chỉ định
trong Table cho biến.
Cú pháp:
Select <@tên biến1>=<Tên cột 1>,
<@tên biến2>=<Tên cột 2>,
…
[Where <Điều kiện>]
Nếu kết quả của Select cho nhiều dịng thì sẽ gán giá trị của
dịng có STT vật lý đầu tiên cho biến.
Hiển thị kết quả của biến:
Print <@tên biến>
Ví dụ: Hiển thị dịng ‘Xin chào’ họ tên của sinh viên đầu tiên
trong bảng SINHVIEN
Declare @ht nVarchar(30)
Select @ht=HotenFrom SINHVIEN
Print 'Xin chào'+ @ht
2. Biến toàn cục:
Định nghĩa: là biến được sử dụng bất kỳ đâu trong hệ thống.
Trong SQL biến toàn cục Là các biến hệ thống do SQL
Server cung cấp
SQL tự cập nhật giá trị cho các biến này, Người sử dụng
không thể gán giá trị trực tiếp cho biến này
Bản chất là 1 hàm (function) và bắt đầu bằng ký tự @@
Một số biến toàn cục trong SQL
Tên biến
Ý nghĩa
@@ERROR
Mã số lỗi của câu lệnh T-SQL cuối cùng bị lỗi
@@FETCH_STATUS
Trạng thái truy nhập con trỏ:
0 nếu trạng thái truy nhật cuối cùng thành cơng
-1 nếu có lỗi
@@IDENTITY
Giá trị xác định (identity) cuối cùng được thêm
vào
@@ROWCOUNT
Số lượng dòng của kết quả câu lệnh SQL gần
đây nhất.
@@SERVERNAME
Tên của Server địa phương
@@TRANSCOUNT
Số lượng những giao dịch đang được mở
@@VERSION
Thông tin về phiên bản SQL Server đang dùng
@@CURSOR_ROWS
Số lượng các dòng dữ liệu của con trỏ mới được
mở gần đây nhất
II. CẤU TRÚC LỆNH
1. Cấu trúc IF…
Cú pháp:
If <điều kiện>
Lệnh| Khối_lệnh
[Else Lệnh| Khối_lệnh]
Khối lệnh là một hoặc nhiều lệnh nằm trong cặp từ khóa
begin…end
Giải thích cấu trúc
Ví dụ:
Viết lệnh để thêm dữ liệu mới (001,Hồ Thị ,Lan, CT11) vào bảng
SINHVIEN. Qui định rằng mỗi lớp chỉ được tối đa 50 sinh viên.
Declare @SiSo int
Select @SiSo = Count(MaSV) From SINHVIEN
Where MaLop= ‘CT11’
If @SiSo < 50
Begin
Insert into SINHVIEN(MaSV, Ho, Ten, Malop)
Values(‘001’,N’Hồ Thị’ ,N’Lan’, ‘CT11’)
Print N’Thêm thành công’
End
Else Print N’Lớp đã đủ số sinh viên’
2. Cấu trúc Case
Cú pháp: Có hai dạng
–Dạng 1 (simple case):
Dạng 2: (searched case):
Case Biểu_thức
When Giá_trị 1 Then kết_quả 1
[When Giá_trị 2 Then Kết_quả 2
[...n]
[ Else kết_quả_khác]
End
Case
When <điều kiện 1> then kết_quả 1
When <điều kiện 2> then kết_quả 2
[...n]
[ Else kết_quả_khác]
End
2. Cấu trúc WHILE
Cú pháp
While <điều_kiện>
Lệnh| Khối lệnh
[Break]
[Continue]
Có thể thêm Break và Continue trong khối lệnh của while
Break: thoát khỏi vòng While hiện hành
Continue : trở lại đầu vòng While, bỏ qua các lệnh sau đó
Giải thích:
Ví dụ: Viết đoạn chương trình tách tên của sinh viên có mã ‘0001’
trong bảng SINHVIEN
Declare @ht varchar(30),@ten varchar(10), @L int, @i int,@j int,@kt
varchar(10)
set @ht=(select hoten from SINHVIEN Where MaSV='0001')
Set @L=LEN(@ht)
Set @i=1
While @i<=@L
Begin
Set @kt=Substring(@ht,@i,1)
if @kt='' set @j=@i
set @i=@i+1
end
set @ten=substring(@ht,@j+1,10)
print @ht+' có tên là: '+@ten
III- CURSOR (CON TRỎ)
1. Khái niệm:
Là một cấu trúc dữ liệu ánh xạ đến một tập các dòng dữ
liệu là kết quả của một câu truy vấn (select), cho phép duyệt
tuần tự các dòng dữ liệu và đọc giá trị từng dịng trong tập kết
quả
Sử dụng con trỏ có thể đến vị trí một dịng nhất định trong
tập kết quả.
Truy cập đến 1 dòng hoặc 1 tập hợp những dòng từ vị trí
hiện tại của con trỏ trong tập kết quả.
Hỗ trợ sửa chữa dữ liệu ở 1 dòng nào đó.
Ví dụ: Chúng ta có một danh sách sinh viên (Select), trong
lập trình ta muốn có một con trỏ đến vị trí từng dịng để có
những truy cập cần thiết.
1.
Tạo con trỏ
Câu lệnh DECLARE để khai báo con trỏ. Nó chứa đựng câu
lệnh Select để đưa ra tập những bản ghi từ bảng.
Declare Cursor_name Cursor
[ Local | Global ]
[ Forward_only| Scroll]
[ Static| Dynamic]
[ Read_only]
For select_statement
Những tham số gạch chân là mặc định
Giải thích
Local: cursor cục bộ, chỉ có thể sử dụng trong phạm vi một
khối (query batch) hoặc một thủ tục/ hàm
Global: cursor toàn cục (tồn tại trong suốt connection hoặc
đến khi bị hủy tường minh)
-Forward_only: cursor chỉ có thể duyệt một chiều từ đầu đến
cuối
Scroll: có thể duyệt lên xuống cursor tùy ý
-Static: nội dung của cursor không thay đổi trong suốt thời
gian tồn tại, trong trường hợp này cursor chỉ là read only
Dynamic: trong thời gian tồn tại, nội dung của cursor có thể
thay đổi nếu dữ liệu trong các bảng liên quan có thay đổi.
-Read only: chỉ có thể đọc từ cursor, không thể sử dụng
cursor để update dữ liệu trong các bảng liên quan (ngược lại với
“for update…” )
2. Duyệt tuần tự mẫu tin trong kết quả
Cú pháp lệnh
Fetch [ [Next| Prior| First| Last| Absolute n| Relative n]
From Tên_cursor
[Into Tên_biến [,…n] ]
FETCH FIRST: Truy cập đến dòng đầu tiên.
FETCH NEXT: Truy cập đến dòng tiếp theo. Mặc định
FETCH PRIOR: Truy cập đến dòng trước dòng hiện tại của con trỏ.
FETCH LAST: Truy cập đến dòng cuối cùng.
FETCH ABSOLUTE n: Nếu n là số nguyên dương, nó truy cập đến
dịng thứ n. Nếu n là số ngun âm, nó truy cập đến dòng thứ n
trước dòng cuối cùng của con trỏ. Nếu n=0 nó truy cập tới chính
dịng hiện tại.
FETCH RELATIVE n: Nếu n là số dương, truy cập đến dòng thứ n sau
dòng hiện tại của con trỏ. Nếu n là số âm, truy cập đến dòng thứ n,
truy cập đến dịng thứ n trước vị trí hiện tại của con trỏ. Nếu bằng 0,
truy nhập đến dòng hiện tại một lần nữa.
Biến hệ thống @@fetch_status:
Cho biết lệnh fetch vừa thực hiện có thành cơng hay khơng.
Là cơ sở để biết đã duyệt đến cuối cursor hay chưa
Nếu @@fetch_status =0 thì thành cơng con trỏ đang ở vị trí
mẫu thỏa mãn điều kiện
Nếu @@fetch_status <>0 thì KHƠNG thành cơng con trỏ
đang ở vị trí vượt qua mẫu tin cuối cùng của bảng kết quả
Ví du: Cập nhật lại giá trị MaSV = MaLop + MaSV hiện tại cho
tất cả sinh viên
Declare cur_Masv cursor
For Select MaSV, Malop From SINHVIEN
Open cur_Masv
declare @Masv varchar(5), @Malop varchar(5)
Fetch Next From cur_Masv into @MaSV,@Malop
While @@fetch_status = 0
Begin
Update SINHVIEN Set MaSV = @Malop+@MaSV
Where MaSV = @MaSV
Fetch Next From cur_Masv into @MaSV,@Malop
End
Close cur_Masv
Deallocate cur_Masv
Ví dụ: Cập nhật lại Masv thứ n là aaa
Declare cur_DSSV cursor scroll
For select MaSV From SINHVIEN
Open cur_DSSV
Declare @masv varchar(10)
Fetch Absolute 5 From cur_DSSV into @Masv
If (@@fetch_status = 0)
update SINHVIEN set masv ='aaa' where current of cur_DSSV
Deallocate cur_DSSV
Tóm lại các bước sử dụng biến con trỏ trong lập trình
B1. Định nghĩa Cursor từ một kết quả Select
Declare Cursor_name Cursor For select_statement
B2. Mở Cursor:
OPEN <Cursor_name> , con trỏ ở vị trị dòng 0
B3. Truy cập đến các bản ghi
FETCH NEXT| Absolute 5
FROM <Cursor_name> INTO <ds biến>
B4. Kểm tra có thành cơng khơng:
Nếu @fetch_status = 0 thì xử lý lệnh, quay lại B3
Nếu @fetch_status <> 0 thì sang B5
B5. Đóng Cursor:
CLOSE <Cursor_name>
B6. Xố tham chiếu của Cursor:
DEALLOCATE <Cursor_name>
Bài tập
1. Thêm cột SBD trong bảng SV: Hãy điền SBD cho các
sinh viên theo từng lớp
2. Thêm cột Docdiem trong bảng DIEMTBC, Viết đoạn
chương trình cập nhật cho cột Docdiem để đọc điểm TBC ra
thành chữ tương ứng.
3. Viết đoạn chương trình phân lớp ‘CT11’ ra thành 2 lớp
CT11A, CT11B có số lượng nam nữ như nhau.
Declare cur_SBD cursor
For Select MaSV From SINHVIEN order by Malop
Open cur_SBD
Declare @i int
Fetch Next From cur_SBD
Set @i=1
While @@fetch_status = 0
Begin
Update SINHVIEN Set MaSV = right('1000000'+
+ltrim(STR(@i)),4)
Where Current Of cur_SBD
Fetch Next From cur_SBD
set @i=@i+1
End
Close cur_SBD
Deallocate cur_SDB
Declare cur_phanlop cursor for
select masv,Gioitinh,Malop from SINHVIEN where malop='ct11‘ order by
gioitinh
open cur_phanlop
declare @malop varchar(10),@masv varchar(10),@i int
fetch next from cur_phanlop
set @i=1
While @@FETCH_STATUS=0
Begin
If @i% 2=0
update SINHVIEN set MaLop='CT11A' where current of cur_phanlop
Else
update SINHVIEN set MaLop='CT11B' where current of cur_phanlop
set @i=@i+1
fetch next from cur_phanlop
end
close cur_phanlop
Deallocate cur_phanlop
IV. Stored procedure (Thủ tục)
1. Khái niệm:
Thủ tục lưu trữ là một đối tượng trong CSDL, bao gồm nhiều
câu lệnh T-SQL , sẽ được thực thi khi thủ tục lưu trữ được goi.
2. Ý nghĩa:
–Tính tái sử dụng.
–Các lệnh trong stored procedure được tối ưu hóa một lần sau
khi biên dịch tiết kiệm thời gian khi thực thi.
–Giảm khối lượng thông tin trao đổi khi ứng dụng gửi yêu cầu
thực hiện công việc về database server
–Hỗ trợ tốt hơn cho việc đảm bảo an toàn (security) cho CSDL
3. Tạo thủ tục:
Create procedure <Tên thủ tục> Danh sách tham số vào ra
As
<Đoạn chương trình xử lý>
[return [giá trị trả về] ]
Go
Lưu ý:
Danh sách tham số vào (ra)
<Tên tham số> <kiểu> [=default] [output]
Output: Chỉ định tham số ra (muốn biết giá trị của nó)
- Tên tham số đặt theo qui tắc như tên biến cục bộ
- Lệnh RETURN được sử dụng để kết thức stored procedure và
trả về giá trị là một số, có thể là một biến. Giá trị mặc định là
Return 0
- Mỗi lệnh SELECT đặt trong stored procedure sẽ trả về 1 bảng.
CREATE PROCEDURE usp_Sinhvien
@Masv varchar(10),@Ho nvarchar(30),@Ten varchar(10),
@Malop varchar(10),@Siso int =NULL Output
AS
Declare @SiSo int
Select @SiSo = Count(MaSV) From SINHVIEN
Where MaLop= ‘CT11’
@Malop
If @SiSo < 50
Begin
Insert into SINHVIEN(MaSV, Ho, Ten, Malop)
Values(‘001’,N’Hồ
Thị’ ,N’Lan’, ‘CT11’)
(@Masv,@Ho,@Ten,@Malop)
Print N’Thêm thành công’
End
Else Print N’Lớp đã đủ số sinh viên’
Go