Giao Trinh SQL
Transcript of Giao Trinh SQL
1
SQL SERVER 2008
Tác giả: Ks Hoàng Anh Quang
2
Mục lục
Bài 1 – Ngôn ngữ T-SQL ................................................ 5
1. Truy vấn dữ liệu đơn giản với SELECT ......................... 5
2. Tìm hiểu các trường tính toán ....................................... 11
3. Lọc dữ liệu với mệnh đề WHERE ................................. 14
4. Sắp xếp dữ liệu với ORDER BY .................................... 20
5. Nhóm dữ liệu với mệnh đề GROUP BY ........................ 23
6. Query con ....................................................................... 28
7. Các phép nối ................................................................... 32
7.1. Tạo phép nối với mệnh đề WHERE ................................ 32
7.2. INNER JOIN (nội kết) ..................................................... 35
7.3. Sử dụng bí danh của bảng ............................................... 35
7.4. OUTER JOIN (Ngoại kết) ............................................... 37
8. Kết hợp các query .......................................................... 40
9. Chèn dữ liệu ................................................................... 41
9.1. Chèn dữ liệu trực tiếp ...................................................... 41
9.2. Chèn dữ liệu truy vấn ...................................................... 43
9.3. Sao chép dữ liệu từ bảng khác ......................................... 43
10. Cập nhật, xóa dữ liệu ................................................... 43
10.1. Cập nhật chỉnh sửa dữ liệu ............................................ 43
10.2. Xóa dữ liệu ..................................................................... 44
11. Bài tập thực hành ......................................................... 45
Bài 2 – Giới thiệu về phiên bản SQL Server 2008 47
1. Hệ quản trị cơ sở dữ liệu ................................................ 47
2. Cài đặt SQL Server 2008 ............................................... 48
3
2.1. Cài đặt .Net FrameWork 3.5 ........................................... 49
2.2. Cài đặt bản nâng cấp Windows ....................................... 52
2.3. Cài đặt SQL Server 2008 ................................................. 54
2.4. Khởi động SQL server 2008 ............................................ 59
3. Một số thao tác cơ bản với SQL Server 2008 ................ 60
3.1. Kết nối tới Sever .............................................................. 61
3.2. Tìm hiểu cửa sổ New Query ............................................ 63
4. Quản lý Database đơn giản ............................................ 65
4.1. Tạo mới một DataBase .................................................... 65
4.2. Cất dữ DataBase (Backup) .............................................. 70
4.3. Xóa DataBase (Delete) ..................................................... 77
4.4. Phục hồi DataBase (Restore) ........................................... 79
4.5. Gở bỏ DataBase (Detach) ................................................ 85
4.6. Đính kèm DataBase (Attach) ........................................... 87
Bài 3 – Các đối tượng và một số xử lý trong SQL Server 2008 ..................................................................... 91
1. Câu lệnh SQL ................................................................. 91
1.1. Đối tượng ......................................................................... 91
1.2. Biến .................................................................................. 91
1.3. Kiểu dữ liệu ...................................................................... 93
1.4. Hàm .................................................................................. 95
1.5. Câu lệnh có cấu trúc ...................................................... 108
1.6. Viết câu lệnh T-SQL trên New Query của SQL Server 2008 ....................................................................................... 109
1.7. Bài tập thực hành........................................................... 114
2. Bảng .............................................................................. 115
2.1. Tạo bảng ........................................................................ 115
4
2.2. Cập nhật dữ liệu vào bảng ............................................. 123
2.3. Bài tập thực hành........................................................... 130
3. View .............................................................................. 135
3.1. Định nghĩa ...................................................................... 135
3.2. Thêm và chỉnh sửa View ................................................ 136
3.3. Bài tập thực hành........................................................... 145
4. Stored Procedures (Thủ tục lưu) ................................. 145
4.1. Khái niệm ....................................................................... 145
4.2. Viết Stored Procedure ................................................... 147
4.3. Sử dụng bảng tạm .......................................................... 155
4.4. Tìm hiểu Cursors ........................................................... 159
4.5. Bài tập thực hành........................................................... 162
5. Trigger .......................................................................... 162
5.1. Định nghĩa ...................................................................... 162
5.2. Tạo mới và sửa đổi Trigger ........................................... 164
5.3. Bài tập thực hành........................................................... 169
5
Phần 1 – Hệ quản trị cơ sở dữ liệu SQL Server
Bài 1 – Ngôn ngữ T-SQL
Giới thiệu sơ lược về ngôn ngữ Transact-SQL (T-SQL)
- Structured Query Language (SQL) là ngôn ngữ do IBM phát triển từ năm 1970, dùng để giao tiếp với cơ sở dữ liệu. Các hệ thống cơ sở dữ liệu có cách viết và thi hành vâu lệnh SQL riêng như: ANSI SQL (SQL chuẩn), T-SQL (SQL Server, Sybase), PL/SQL (Oracle), Access SQL.
- Transact-SQL là ngôn ngữ SQL mở rộng dựa trên SQL chuẩn của ISO (International Organization for Standardization) và ANSI (American National Standards Institute) được sử dụng trong SQL Server khác với P-SQL (Procedural-SQL) dùng trong Oracle.
Các lệnh T-SQL được chia làm 3 nhóm:
+ Data Definition Language (DDL): Ðây là những lệnh dùng để quản lý các thuộc tính của một Database như định nghĩa các hàng hoặc cột của một table, hay vị trí data file của một database... như Create, Alter, Drop.
+ Data Control Language (DCL): Ðây là những lệnh quản lý các quyền truy cập lên từng object (table, view, stored procedure...) như Grant, Revoke, Deny.
+ Data Manipulation Language (DML): Ðây là những lệnh phổ biến dùng để xử lý data như Select, Update, Insert, Delete.
Trong bài này chúng ta chủ yếu nghiên cứu nhóm lệnh Data Manipulation Language (DML).
1. Truy vấn dữ liệu đơn giản với SELECT
Trong thực tế chúng ta thường xuyên phải thực hiện các công việc như lập danh sách sinh viên trong lớp hay lập danh sách các nhà cung cấp hàng hóa cho công ty,… Để thực hiện các công việc đó trong hệ quản trị CSDL với ngôn ngữ T-SQL chúng ta sử dụng câu truy vấn SELECT.
6
Cú pháp:
SELECT [DISTINCT] [TOP So_Ban_Ghi]
<Danh_Sach_Truong>
FROM <Ten_Bang>
Giải thích:
- Distinct: Chỉ định không trùng lặp thông tin giữa các bản ghi của kết quả truy vấn tương ứng với danh sách trường hiển thị.
- So_Ban_Ghi: Số bản ghi trả về trong kết quả truy vấn
Lưu ý: Nếu danh sách kết quả không được sắp xếp, kết quả sẽ hiển thị theo thứ tự dữ liệu được thêm vào bảng.
- Danh_Sach_Truong: Trường hiển thị trong danh sách kết quả truy vấn, danh sách trường có thể là tên các trường hoặc các biểu thức được ngăn cách với nhau bằng dấu phẩy dưới “,”. Số lượng tối đa các trường, biểu thức trong danh sách này là 4096.
Lưu ý: Sử dụng ký tự “*” khi cần lấy tất cả các trường trong bảng gốc vào danh sách kết quả truy vấn.
- Ten_Bang: Tên bảng cần truy vấn dữ liệu
Ví dụ:
Cho các bảng cơ sở dữ liệu sau:
- Bảng danh sách nhà cung cấp, khách hàng (DMDT) bao gồm các trường: Id, Ma_Dt, Ten_Dt, Dia_Chi, So_Dt, Fax, Email, Ghi_Chu.
7
Dữ liệu mẫu
Id Ma_Dt
Ten_Dt Dia_Chi So_Dt Fax Email
1 N001 Cty TNHH ABC Hà Nội 04 3640 0119
3 N002 Cty Cổ phần CB thực phẩm miền bắc Hà Nội 046 3423 3438
4 N003 Cty liên doanh Việt Pháp Hải Phòng
033 6534 391
5 N004 Cty TNHH một thành viên cấp nước Yên Bái
Yên Bái 02183 543 443
6 N005 Cty Cổ phần Lạc Hồng Bắc Ninh
0240 362 552
7 N006 Cty XNK Á Châu Hải Dương
0320 3111 411
- Bảng danh sách vật tư, hàng hóa (DMVT) bao gồm các trường: Id, Ma_Vt, Ten_Vt, Dvt, Quy_Cach, Ghi_Chu.
Id Ma_Vt Ten_Vt Dvt Quy_Cach
1 TP001 Bánh trứng Custas Hộp Hộp 20 cái
2 TP002 Bánh kem xốp Gói Gói 200 gram
8
3 VT001 Bột mì loại 1 Kg
4 VT002 Hương liệu Kg
5 VT003 Bột nở Kg
6 TP003 Bánh kem bơ Gói Gói 150 gram
7 TP004 Bánh Socola Vinasun Hộp Hộp 6 cái
8 VT004 Socola nguyên liệu Kg
9 VT005 Sửa ông thọ Thùng
- Bảng chứng từ (CT) bao gồm các trường: Id, Ma_Ct, Nhom_Ct, So_Ct, Ngay_Ct, Ma_Dt, Ong_Ba, Dia_Chi, Dien_Giai.
SttCt Ma_Ct Nhom_Ct So_Ct Ngay_Ct Ma_Dt Ong_Ba Dia_Chi Dien_Gi
ai
1 PX 1 PX001 31/05/11 N001 Lê Văn Khương
Hà Nội Xuất hàng hóa bán đại lý
2 PX 1 PX002 01/06/11 N001 Đào Thị Hạnh
Hà Nội Xuất hàng hóa bán đại lý
9
3 PN 2 PN001 01/06/11 N002 Tạ Thu Loan
Công ty Nhập vật tư phục vụ sản xuất
4 PX 1 PX003 01/06/11 N004 Phan Thế Anh
Hà Nội Xuất bán hàng hóa
5 PN 2 PN002 02/06/11 N005 Tạ Thị Minh
Hà Tây Nhập nguyên liệu
6 PX 1 PX004 05/06/11 N004 Phan Thế Anh
Hà Nội Xuất bán hàng hóa
- Bảng chi tiết chứng từ (CTCT) bao gồm các trường: Id, Id_Ct, Ma_Vt, Ma_Kho, So_Luong, Don_Gia.
Stt_Dong Stt_Ct Ma_Vt Ma_Kho So_Luong Don_Gia
1 1 TP001 KTP 120.000 120,00
2 1 TP002 KTP 23.500 45,00
1 2 TP001 KTP 11.500 35,00
1 3 VT001 KVT 30.000 120,00
2 3 VT002 KVT 120.000 15,00
1 4 TP001 KTP 110.000 75,00
10
2 4 TP004 KTP 34.000 44,00
1 5 VT004 KVT 75.000 30,00
2 5 VT001 KVT 31.000 32,00
3 5 VT003 KVT 120.000 56,00
1 6 TP001 KVT 13.000 78,00
11
Yêu cầu truy vấn:
- Lập danh sách nhà cung cấp, khách hàng bao gồm các thông tin: Tên, Địa chỉ, Số điện thoại, Email.
Câu lệnh SQL
SELECT Ten_Dt, Dia_Chi, So_Dt, Email
FROM DmDt
- Lập danh sách vật tư hàng hóa bao gồm toàn bộ thông tin có trong bảng DMVT
SELECT * FROM DmVt
- Lập danh sách 5 vật tư xuất hiện đầu tiên trong bảng DMVT
SELECT TOP 5 Id, Ma_Vt, Ten_Vt, Quy_Cach, Ghi_Chu
FROM DmVt
- Lập bảng kê chứng từ nhập xuất bao gồm các thông tin Ngày chứng từ, số chứng từ, Diễn giải, mã đối tượng, người nhập xuất (học viên tự viết).
2. Tìm hiểu các trường tính toán
Các trường tính toán không tồn tại trong cơ sở dữ liệu đã được chuẩn hóa, nó chỉ được xác định trong quá trình xử lý, tính toán. Ví dụ trong bảng DMDT (như giới thiệu phần trước) bạn muốn lấy danh sách nhà cung cấp với tên nhà cung cấp kèm theo sổ điện thoại để tiện liên lạc như minh họa dưới đây:
Mã số Tên nhà cung cấp Địa chỉ
N001 Cty TNHH ABC (04 3640 0119) Hà Nội
N002 Cty Cổ phần CB thực phẩm miền bắc (046 3423 3438)
Hà Nội
… … …
Trong ví dụ này cột “Tên nhà cung cấp” được tạo ra từ trường Ten_Dt và trường So_Dt trong bảng DMDT.
12
Câu lệnh SQL tương ứng:
SELECT Ma_Dt, Ten_Dt + ‘ (’ + So_Dt + ‘)’, Dia_Chi
FROM DmDt
Hoặc trong bảng CTCT (như giới thiệu phần trước) bạn muốn lấy danh sách chứng từ bao gồm các trường Ma_Vt, Ma_Kho, So_Luong, Don_Gia, Thanh_Tien.
Mã vật tư Mã kho Số lượng Đơn giá Thành tiền
TP001 KTP 120.000 120,00 14.400.000
TP002 KTP 23.500 45,00 1.075.500
… … …
- Mô hình quan hệ giữa các bảng trong hệ thống
Trong ví dụ này cột “Thành tiền” được tạo ra từ phép nhân giữa hai trường Don_Gia và So_Luong.
Câu lệnh SQL tương ứng:
SELECT Ma_Vt, Ma_Kho, So_Luong, Don_Gia, Don_Gia * So_Luong
13
FROM DmDt
Như vậy trong hai ví dụ trên trường “Tên nhà cung cấp” mới và trường “Thành tiền” là các trường tính toán.
Lưu ý:
- Tên bí danh: Câu lệnh SQL ở hai ví dụ trên khi thực thi đều cho kết quả đúng, tuy nhiên hai trường tính toán chưa có tên (thường trả về tên mặc định theo hệ quản trị cơ sở dữ liệu ví dụ như “(no column name)”), để gán tên cho hai trường này chúng ta sử dụng cú pháp <Bieu_Thuc> AS Ten_Bi_Danh.
Có thể viết lại hai câu truy vấn trên như sau:
SELECT Ma_Dt, Ten_Dt + ‘ (’ + So_Dt + ‘)’ AS Ten_Dt_Moi,
Dia_Chi
FROM DmDt
Và
SELECT Ma_Vt, Ma_Kho, So_Luong,
Don_Gia, Don_Gia * So_Luong AS Thanh_Tien
FROM DmDt
Trong hai câu lệnh mới tên trường “Thanh_Tien” và “Ten_Dt_Moi” gọi là tên bí danh.
- Các toán tử trong biểu thức trường tính toán: Có thể sử dụng các toán tử +, -, *, / trong biểu thức của trường tính toán.
- Chúng ta cũng có thể sử dụng các hàm xử lý chuỗi, ngày tháng, số trong biểu thức của trường tính toán.
Danh sách một số hàm thường dùng
Hàm Giải thích
GetDate() Lấy thời gian hiện thời tại Client
GetUtcDate() Lấy thời gian hiện thời tại Server
14
Day() Trả về giá trị ngày của đối số
Month() Trả về giá trị tháng của đối số
Year() Trả về giá trị năm của đối số
ABS() Trả về giá trị tuyệt đối của đối số
LEFT() Lấy các ký tự bên trái của đối số
RIGHT() Lấy các ký tự bên phải đối số
SUBSTRING() Lấy ký tự bất kỳ của đối số
LEN() Trả về độ dài của đối số
LTRIM(), RTRIM(), ALLTRIM()
Cắt khoảng trắng bên trái, phải và cả trái và phải của đối số
UPPER(), LOWER() Chuyển đối số thành chữ viết hoa, viết thường
… …
3. Lọc dữ liệu với mệnh đề WHERE
Trong thực tế bảng thường chứa một lượng lớn dữ liệu và ít khi chúng ta lấy toàn bộ các bản ghi trong bảng dữ liệu đó. Chúng ta thường truy xuất một tập con dữ liệu của bảng ứng với các hoạt động cụ thể. Việc truy vấn như vậy đòi hỏi phải chỉ định một vùng điều kiện tìm kiếm hay còn gọi là điều kiện lọc. Ví dụ lấy danh sách các nhà cung cấp tại Hà Nội hoặc lấy bảng kê các mặt hàng nhập xuất trong năm 2011,…
Cú pháp:
SELECT [DISTINCT] [TOP So_Ban_Ghi]
<Danh_Sach_Truong>
FROM <Ten_Bang>
WHERE <Dieu_Kien_Loc>
Giải thích:
- Dieu_Kien_Loc: Biểu thức điều kiện lọc dữ liệu
Một số toán tử cơ bản trong biểu thức điều kiện lọc dữ liệu:
15
Toán tử Giải thích
= Bằng
<> Khác
!= Khác
< Nhỏ hơn
<= Nhỏ hơn hoặc bằng
!< Không nhỏ hơn
> Lớn hơn
>= Lớn hơn hoặc bằng
!> Không lớn hơn
BETWEEN Nằm giữa hai giá trị cụ thể
ISNULL Là một giá trị NULL
Ví dụ: (Sử dụng các bảng dữ liệu ở phần trước)
- Lập danh sách khách hàng, nhà cung cấp tại Hà Nội
SELECT Ma_Dt, Ten_Dt, So_Dt, Fax, Email
FROM DmDt
WHERE Dia_Chi = N'Hà Nội'
Kết quả
Ma_Dt Ten_Dt So_Dt Fax Email
N001 Cty TNHH ABC 04 3640 0119
N002 Cty Cổ phần CB thực phẩm miền bắc
046 3423 3438
- Lập bảng kê chứng từ nhập xuất trong tháng 06
SELECT Ma_Ct, Ngay_Ct, So_Ct, Ma_Dt, Dien_Giai
FROM Ct
WHERE MONTH(Ngay_Ct) = 6
Kết quả
16
Ma_Ct Ngay_Ct So_Ct Ma_Dt Dien_Giai
PX 01/06/2011 PX002 N001 Xuất hàng hóa bán đại lý
PN 01/06/2011 PN001 N002 Nhập vật tư phục vụ sản xuất
PX 01/06/2011 PX003 N004 Xuất bán hàng hóa
PN 02/06/2011 PN002 N005 Nhập nguyên liệu
PX 05/06/2011 PX004 N004 Xuất bán hàng hóa
Tìm hiểu một số toán tử cao cấp:
- Toán tử AND và OR: Sử dụng các toán tử này để kết hợp nhiều điều kiện lọc
+ Lập danh sách chứng từ xuất hàng cho công ty Cty TNHH một thành viên cấp nước Yên Bái vào ngày 01/06/2011.
SELECT Ngay_Ct, So_Ct, Dien_Giai, Ong_Ba
FROM Ct
WHERE Ma_Dt = ‘N004‘ AND Ngay_Ct = ‘01/06/2011‘
Kết quả:
Ngay_Ct So_Ct Dien_Giai Ong_Ba
01/06/2011 PX003 Xuất bán hàng hóa Phan Thế Anh
Lưu ý: Cty TNHH một thành viên cấp nước Yên Bái có mã là “N004”
+ Lập bảng kê xuất hàng chi tiết mặt hàng “Bánh trứng Custas (TP001)” hoặc “Bánh kem bơ (TP003)”.
SELECT Ma_Vt, So_Luong, Don_Gia,
So_Luong * Don_Gia AS Thanh_Tien
FROM CtCt
WHERE Ma_Vt = ‘TP001‘ OR Ma_Vt = ‘TP003’
17
Kết quả:
Ma_Vt So_Luong Don_Gia Thanh_Tien
TP001 120 120,000 14,400,000
TP002 45 23,500 1,057,500
TP001 35 11,500 402,500
TP001 75 110,000 8,250,000
TP001 78 13,000 1,014,000
+ Lập bảng kê chứng từ xuất hàng cho Cty TNHH ABC (N001) hoặc các chứng từ không phải cho công ty này nhưng được thực hiện vào ngày 05/06/2011.
SELECT Ngay_Ct, So_Ct, Dien_Giai, Ma_Dt
FROM CT
WHERE Ma_Dt = ‘N001’
OR (Ma_Dt <> ‘N001’ AND Ngay_Ct = ‘05/06/2011’)
Kết quả
Ngay_Ct So_Ct Dien_Giai Ma_Dt
2011-05-31 PX001 Xuất hàng hóa bán đại lý
N001
2011-06-01 PX002 Xuất hàng hóa bán đại lý
N001
2011-06-05 PX004 Xuất bán hàng hóa N004
- Toán tử IN: Sử dụng toán tử này để chỉ định một dãy điều kiện với bất kỳ giá trị nào trong dãy thỏa mãn. IN sử dụng một danh sách các giá trị được tách bởi dấu phẩy dưới “,”, tất cả được đặt trong dấu ngoặc đơn.
Ví dụ:
Lập bảng kê xuất hàng chi tiết mặt hàng “Bánh trứng Custas (TP001)” hoặc “Bánh kem bơ (TP003)” sử dụng từ khóa IN.
18
SELECT Ma_Vt, So_Luong, Don_Gia,
So_Luong * Don_Gia AS Thanh_Tien
FROM CtCt
WHERE Ma_Vt IN(‘TP001‘, ‘TP003’)
- Toán tử NOT: Phủ định biểu thức đứng ngay sau nó
Ví dụ:
+ Lập bảng kê chứng từ xuất hàng cho Cty TNHH ABC (N001) hoặc các chứng từ không phải cho công ty này nhưng được thực hiện vào ngày 05/06/2011 sử dụng từ khóa NOT.
SELECT Ngay_Ct, So_Ct, Dien_Giai, Ma_Dt
FROM CT
WHERE Ma_Dt = ‘N001’
OR (NOT(Ma_Dt = ‘N001’) AND Ngay_Ct = ‘05/06/2011’)
- Toán tử LIKE và các ký tự đại diện: Sử dụng toán tử này để tìm dữ liệu gần đúng với giá trị tìm kiếm bằng cách kết hợp với các ký tự đại diện. Chỉ có thể áp dụng toán tử LIKE và các ký tự đại diện cho dữ liệu kiểu chuỗi.
+ Ví dụ về ký tự đại diện “%”: Ký tự đại diện này đại diện cho phần còn lại của chuỗi.
Lập danh sách các khách hàng là loại hình doanh nghiệp “Cổ phần” trên địa bàn Hà Nội
SELECT RTRIM(Ten_Dt) + ' (' + RTRIM(Ma_Dt) + ')' AS Ten_Dt,
So_Dt, Email
FROM DmDt
WHERE Ten_Dt LIKE N'%Cổ phần%' AND Dia_Chi = N'Hà Nội'
Kết quả:
19
Ten_Dt So_Dt Email
Cty Cổ phần CB thực phẩm miền bắc (N002)
046 3423 3438
+ Ví dụ về ký tự đại diện “_”: Ký tự đại diện này tương tự như ký tự “%” tuy nhiên nó chỉ đại diện cho một ký tự đơn.
Tìm những thành phẩm với mã có phần mở rộng là các số chạy nhỏ hơn 10.
SELECT Ma_Vt, Ten_Vt, Dvt, Quy_Cach
FROM DmVt
WHERE RTRIM(Ma_Vt) LIKE N'TP00_'
Kết quả:
Ma_Vt Ten_Vt Dvt Quy_Cach
TP001 Bánh trứng Custas Hộp Hộp 20 cái
TP002 Bánh kem xốp Gói Gói 200 gram
TP003 Bánh kem bơ Gói Gói 150 gram
TP004 Bánh Socola Vinasun
Hộp Hộp 6 cái
+ Ví dụ về ký tự đại diện “[ ]”: Sử dụng để chỉ định một tập hợp các ký tự, một ký tự trong tập hợp phải thỏa mãn một ký tự tại một vị trí xác định trước (vị trí của ký tự đại diện).
Lập danh sách các công ty “TNHH” hoặc “Cổ phần” đóng trên địa bàn “Hà Nội”
SELECT RTRIM(Ten_Dt) + ' (' + RTRIM(Ma_Dt) + ')' AS Ten_Dt,
So_Dt, Email
FROM DmDt
WHERE Ten_Dt LIKE N'%[Cổ phần, TNHH]%'
AND Dia_Chi = N'Hà Nội'
20
Kết quả:
Ten_Dt So_Dt Email
Cty TNHH ABC (N001) 04 3640 0119
Cty Cổ phần CB thực phẩm miền bắc (N002)
046 3423 3438
Lưu ý: Không thể phủ nhận khả năng linh hoạt khi tìm kiếm với các ký tự đại diện, tuy nhiên việc tìm kiếm với chúng mất nhiều thời gian hơn cả so với những cách tìm kiếm đã giới thiệu.. sau đây là một số thủ thuật cần ghi nhớ khi sử dụng tìm kiếm bằng các ký tự đại diện:
- Không lạm dụng các ký tự đại diện nếu như có thể tìm kiếm bằng các toán tử khác.
- Nếu không thực sự cần thiết không nên sử dụng ký tự đại diện ở phần đầu của các mẩu tìm kiếm vì đây là cách tìm kiếm chậm nhất.
- Đặc biệt chú ý đến vị trí của ký tự đại diện vì nếu đặt sai vị trí bạn sẽ không có được kết quả như mong muốn.
4. Sắp xếp dữ liệu với ORDER BY
Trong những ví dụ ở các phần đã học kết quả truy vấn chưa được sắp xếp, chúng thường được hiển thị theo thứ tự trong bảng, đây có thể là trật tự dữ liệu được thêm vào bảng ban đầu. Tuy nhiên trật tự này có thể thay đổi nếu như bảng thường xuyên được cập nhật hoặc xóa, chúng ta có thể sử dụng câu truy vấn với ORDER BY để sắp xếp lại dữ liệu.
Cú pháp:
SELECT [DISTINCT] [TOP So_Ban_Ghi]
<Danh_Sach_Truong>
FROM <Ten_Bang>
WHERE <Dieu_Kien_Loc>
ORDER BY <Chi_Tieu_Sap_Xep> [ASC|DESC]
21
Giải thích:
- Chi_Tieu_Sap_Xep: Là danh sách tên cột hoặc thứ tự cột cần sắp xếp
- ASC: Chỉ định sắp xếp tăng dần
- DESC: Chỉ định sắp xếp giảm dần
Ví dụ:
- Lập danh sách thành phẩm mà công ty sản xuất, kết quả được sắp xếp theo thứ tự trong bảng chữ cái của tên thành phẩm.
SELECT Ma_Vt, Ten_Vt, Dvt, Quy_Cach
FROM DmVt
WHERE Ma_Vt LIKE ‘TP%’
ORDER BY Ten_Vt
Kết quả:
Ma_Vt Ten_Vt Dvt Quy_Cach
TP003 Bánh kem bơ Gói Gói 150 gram
TP002 Bánh kem xốp Gói Gói 200 gram
TP004 Bánh Socola Vinasun Hộp Hộp 6 cái
TP001 Bánh trứng Custas Hộp Hộp 20 cái
Xem lại kết quả khi không sử dụng ORDER BY
Ma_Vt Ten_Vt Dvt Quy_Cach
TP001 Bánh trứng Custas Hộp Hộp 20 cái
TP002 Bánh kem xốp Gói Gói 200 gram
TP003 Bánh kem bơ Gói Gói 150 gram
TP004 Bánh Socola Vinasun Hộp Hộp 6 cái
- Lập bảng kê chứng từ nhập xuất trong tháng 06 năm 2011, sắp xếp theo Ma_Dt và Ngay_Ct tăng dần.
SELECT Ngay_Ct, So_Ct, Ma_Dt, Dien_Giai
22
FROM Ct
WHERE MONTH(Ngay_Ct) = 6 AND YEAR(Ngay_Ct) = 2011
ORDER BY Ma_Dt, Ngay_Ct
Kết quả:
Ngay_Ct So_Ct Ma_Dt Dien_Giai
01/06/2011 PX002 N001 Xuất hàng hóa bán đại lý
01/06/2011 PN001 N002 Nhập vật tư phục vụ sản xuất
01/06/2011 PX003 N004 Xuất bán hàng hóa
05/06/2011 PX004 N004 Xuất bán hàng hóa
02/06/2011 PN002 N005 Nhập nguyên liệu
- Lập bảng kê chứng từ xuất bán thành phẩm, sắp xếp theo Ma_Vt và So_Luong giảm dần.
SELECT Ma_Vt, So_Luong, Don_Gia,
So_Luong * Don_Gia AS Thanh_Tien
FROM CtCt
WHERE Ma_Vt LIKE 'TP%'
ORDER BY Ma_Vt, So_Luong DESC
Kết quả:
Ma_Vt So_Luong Don_Gia Thanh_Tien
TP001 120 120.000 14.400.000
TP001 78 13.000 1.014.000
TP001 75 110.000 8.250.000
TP001 35 11.500 402.500
TP002 45 23.500 1.057.500
TP004 44 34.000 1.496.000
23
5. Nhóm dữ liệu với mệnh đề GROUP BY
Với mệnh đề WHERE ở phần trước đã học chúng ta có thể thống kê xem có bao nhiêu lần vật tư có mã là ‘VT001’ được nhập xuất với câu lệnh như sau:
SELECT COUNT(*) AS So_Lan_Nx
FROM CTCT
WHERE Ma_Vt = ‘VT001’
Tuy nhiên để thống kê xem mỗi vật tư được nhập xuất bao nhiêu lần chúng ta phải sử dụng mệnh đề GROUP BY.
Cú pháp:
SELECT <Danh_Sach_Truong>
FROM <Ten_Bang>
WHERE <Dieu_Kien_Loc>
GROUP BY <Danh_Sach_Nhom>
HAVING <Bieu_Thuc_Dieu_Kien>
ORDER BY <Chi_Tieu_Sap_Xep>
Giải thích:
- <Danh_Sach_Nhom>: Danh sách cột, thứ tự cột cần nhóm dữ liệu
- <Bieu_Thuc_Dieu_Kien>: Biểu thức điều kiện lọc nhóm dữ liệu
Ví dụ:
- Thống kê xem mỗi nhà cung cấp, khách hàng đã phát sinh bao nhiêu chứng từ nhập xuất với công ty trong tháng 6 năm 2011.
SELECT Ma_Dt, COUNT(Ma_Dt) AS So_Ct_Nx
FROM Ct
WHERE MONTH(Ngay_Ct) = 6 AND YEAR(Ngay_Ct) = 2011
GROUP BY Ma_Dt
24
Kết quả:
Ma_Dt So_Ct_Nx
N001 1
N002 1
N004 2
N005 1
- Thống kê tổng số lượng nhập xuất kho của từng mặt hàng, kết quả sắp xếp tăng dần theo số lượng.
SELECT Ma_Vt, SUM(So_Luong) AS So_Luong
FROM CtCt
GROUP BY Ma_Vt
ORDER BY So_Luong
Kết quả:
Ma_Vt So_Luong
VT002 15
VT004 30
TP004 44
TP002 45
VT003 56
VT001 152
TP001 308
- Thống kê lượng nhập xuất hàng hóa theo từng kho và từng mặt hàng, kết quả sắp xếp theo mã kho và giảm dần theo số lượng.
SELECT Ma_Kho, Ma_Vt, SUM(So_Luong) AS So_Luong
FROM CtCt
GROUP BY Ma_Kho, Ma_Vt
ORDER BY Ma_Kho, So_Luong DESC
25
Kết quả:
Ma_Kho Ma_Vt So_Luong
KTP TP001 230
KTP TP002 45
KTP TP004 44
KVT VT001 152
KVT TP001 78
KVT VT003 56
KVT VT004 30
KVT VT002 15
- Thống kê doanh số bán hàng theo từng mặt hàng, kết quả sắp xếp theo Ma_Vt và giảm dần theo doanh thu.
SELECT Ma_Vt, SUM(So_Luong * Don_Gia) AS Doanh_Thu
FROM CtCt
WHERE Ma_Vt LIKE 'TP%'
GROUP BY Ma_Vt
ORDER BY Doanh_Thu DESC
Kết quả:
Ma_Vt Doanh_Thu
TP001 24.066.500
TP004 1.496.000
TP002 1.057.500
- Thống kê những mặt hàng có doanh số bán hàng lớn hơn 2 triệu, kết quả sắp xếp danh sách theo Ma_Vt.
SELECT Ma_Vt, SUM(So_Luong * Don_Gia) AS Doanh_Thu
FROM CtCt
26
WHERE Ma_Vt LIKE 'TP%'
GROUP BY Ma_Vt
HAVING SUM(So_Luong * Don_Gia) > 2000000
ORDER BY Ma_Vt
Kết quả:
Ma_Vt Doanh_Thu
TP001 24.066.500
- Lập danh sách những nhà cung cấp, khách hàng đã từng phát sinh từ 2 chứng từ nhập xuất trở lên với công ty. Kết quả sắp xếp giảm dần theo số chứng từ phát sinh.
SELECT Ma_Dt, COUNT(Ma_Dt) AS So_Ct_Nx
FROM Ct
GROUP BY Ma_Dt
HAVING COUNT(Ma_Dt) >= 2
ORDER BY So_Ct_Nx DESC
Kết quả
Ma_Dt So_Ct_Nx
N001 2
N004 2
- Thống kê mặt hàng bán chạy nhất
SELECT TOP 1 Ma_Vt, SUM(So_Luong * Don_Gia) AS Doanh_Thu
FROM CtCt
WHERE Ma_Vt LIKE 'TP%'
GROUP BY Ma_Vt
ORDER BY Doanh_Thu DESC
Kết quả
27
Ma_Vt Doanh_So TP001 24.066.500
- Thống kê 2 mặt hàng bán chậm nhất
SELECT TOP 2 Ma_Vt, SUM(So_Luong * Don_Gia) AS Doanh_Thu
FROM CtCt
WHERE Ma_Vt LIKE 'TP%'
GROUP BY Ma_Vt
ORDER BY Doanh_Thu ASC
Kết quả:
Ma_Vt Doanh_So
TP002 1.057.500
TP004 1.496.000
Lưu ý:
- Các trường trong danh sách nhóm sau mệnh đề GROUP BY có thể không xuất hiện trong danh sách trường sau SELECT.
- Các trường không xuất hiện trong danh sách nhóm sau mệnh đề GROUP BY, nhưng xuất hiện trong danh sách trường sau SELECT thì phải được chỉ định bởi một hàm thống kê (phải là một trường tính toán). Một số hàm thống kế thường sử dụng.
Hàm Giải thích
AVG() Trả về giá trị trung bình của cột
COUNT() Đếm số dòng trong cột
MAX() Trả về giá trị lớn nhất của cột
MIN() Trả về giá trị nhỏ nhất của cột
SUM() Tính tổng giá trị của cột
- Sử dụng HAVING trong mệnh đề GROUP BY vì WHERE chỉ lọc dòng dữ liệu cụ thể không phải là nhóm dữ liệu.
28
- Biểu thức sau HAVING hỗ trợ tất cả các toán tử như biểu thức sau WHERE
- Khác biệt giữa HAVING và WHERE là WHERE lọc dữ liệu khi chưa nhóm còn HAVING lọc dữ liệu sau khi đã được nhóm.
- Chúng ta cũng có thể sử dụng ORDER BY cùng GROUP BY để sắp xếp nhóm dữ liệu
6. Query con
Tất cả các câu lệnh truy vấn (Query) mà chúng ta đã nghiên cứu qua các bài trước đều là các câu truy vấn đơn giản (các câu truy vấn từ các bảng cơ sở dữ liệu riêng lẻ). T-SQL còn cho phép bạn tạo ra các query con (SubQuery: Các Queries được nhúng và Query khác), để hiểu sâu về vấn đề này chúng ta nghiên cứu một ví dụ sau đây:
Từ bảng danh mục vật tư (DMVT) và bảng chi tiết chứng từ nhập xuất (CTCT) đã tạo lập ở các phần trước chúng ta cần lập danh sách những vật tư đã từng được nhập xuất. Đầu tiên hãy thực hiện ví dụ này bằng các Query đơn giản chúng ta làm như sau:
Bước 1: Lấy mã những vật tư đã từng nhập xuất trong bảng CTCT
SELECT DISTINCT Ma_Vt FROM CTCT
Kết quả:
Ma_Vt
TP001
TP002
VT001
VT002
Bước 2: Lấy danh sách vật tư có mã tương ứng trong danh sách vừa lọc
SELECT * FROM DMVT
WHERE Ma_Vt IN('TP001', 'TP002', 'VT001', 'VT002')
29
Kết quả:
ID Ma_Vt Ten_Vt Dvt Quy_Cach Ghi_Chu
1 TP001 Bánh trứng Custas
Hộp Hộp 20 cái NULL
2 TP002 Bánh kem xốp
Gói Gói 200 gram
NULL
3 VT001 Bột mì loại 1 Kg NULL NULL
4 VT002 Hương liệu Kg NULL NULL
Bây giờ có thể viết lại với Query con bằng cách kết hợp hai Query vừa thực hiện:
SELECT * FROM DMVT
WHERE Ma_Vt IN(SELECT Ma_Vt FROM CTCT)
Kết quả cuối cùng cho tương tự như thực hiện bước 2
Với ví dụ trên chúng ta đã tìm hiểu cách lọc dữ liệu theo các Query con, ví dụ sau đây sẽ mô tả cách sử dụng Query con làm trường tính toán.
Với bảng danh mục khách hàng, nhà cung cấp (DMDT) và bảng chứng từ nhập xuất (CT) hãy xem mỗi khách hàng, nhà cung cấp đã nhập xuất bao nhiêu chứng từ với công ty. Với Query đơn giản chúng ta có thể viết như sau:
SELECT Ma_Dt, COUNT(*) AS So_Ct_Nx
FROM CT
GROUP BY Ma_Dt
Kết quả
Ma_Dt So_Ct_Nx
N001 2
N002 1
30
Tuy nhiên với câu lệnh này bạn không có được các thông tin chi tiết về khách hàng, nhà cung cấp đó. Bây giờ hãy thử thực hiện với một Query phức tạp hơn.
SELECT Ma_Dt, Ten_Dt, Dia_Chi,
(
SELECT COUNT(*)
FROM CT
WHERE DmDt.Ma_Dt = Ct.Ma_Dt
) AS So_Ct_Nx
FROM DmDt
Kết quả
Ma_Dt Ten_Dt Dia_Chi So_Ct_Nx
N001 Công ty TNHH ABC Hà Nội 2
N002 Công ty Cổ phần CB thực phẩm miền bắc
Hà Nội 1
Một số ví dụ khác
- Thống kê tổng số lượng nhập xuất kho của từng mặt hàng, kết quả hiển thị bao gồm các thông tin: Ma_Vt, Ten_Vt, Dvt, So_Luong và sắp xếp tăng dần theo số lượng.
SELECT Ma_Vt, Ten_Vt, Dvt,
(
SELECT ISNULL(SUM(So_Luong), 0) AS So_Luong
FROM CtCt WHERE CtCt.Ma_Vt = DmVt.Ma_Vt
) AS So_Luong
FROM DmVt
ORDER BY So_Luong
31
Kết quả:
Ma_Vt Ten_Vt Dvt So_Luong
TP003 Bánh kem bơ Gói 0
VT005 Sửa ông thọ Thùng 0
VT002 Hương liệu Kg 15
VT004 Socola nguyên liệu Kg 30
TP004 Bánh Socola Vinasun Hộp 44
TP002 Bánh kem xốp Gói 45
VT003 Bột nở Kg 56
VT001 Bột mì loại 1 Kg 152
TP001 Bánh trứng Custas Hộp 308
- Thống kê doanh số bán hàng theo từng mặt hàng, kết quả hiển thị bao gồm các trường Ma_Vt, Ten_Vt, Dvt, Doanh_Thu được sắp xếp theo Ma_Vt và giảm dần theo doanh thu.
SELECT Ma_Vt, Ten_Vt, Dvt,
(
SELECT ISNULL(SUM(So_Luong * Don_Gia), 0) AS Doanh_Thu
FROM CtCt WHERE CtCt.Ma_Vt = DmVt.Ma_Vt
) AS Doanh_Thu
FROM DmVt
WHERE Ma_Vt LIKE ‘TP%’
ORDER BY Doanh_Thu DESC
Kết quả:
Ma_Vt Ten_Vt Dvt Doanh_Thu
TP001 Bánh trứng Custas Hộp 24.066.500
TP004 Bánh Socola Vinasun Hộp 1.496.000
32
TP002 Bánh kem xốp Gói 1.057.500
TP003 Bánh kem bơ Gói 0
7. Các phép nối
- Một trong những tính năng mạnh mẽ nhất của SQL là khả năng kết các bảng nhanh chóng trong các Query. Phép nối được thực hiện đơn giản bằng cách sử dụng câu lệnh SELECT của SQL, việc tìm hiểu kỹ và thực hành tốt các phép nối là phần vô cùng quan trọng trong quá trình học SQL.
- Để đảm bảo toàn vẹn, tránh dư thừa cơ sở dữ liệu luôn được chuẩn hóa vì vậy trong quá trình truy vấn dữ liệu thường xuyên phải lấy dữ liệu từ nhiều bảng khác nhau, với việc sử dụng các phép nối sẽ giúp người lập trình dễ dàng trích rút đầy đủ dữ liệu mà mình cần khai thác.
7.1. Tạo phép nối với mệnh đề WHERE
Với mệnh đề WHERE khi tạo kết nối bạn phải chỉ định tất cả các bảng chứa dữ liệu cần truy vấn và cách chúng tạo ra quan hệ với nhau. Chúng ta tìm hiểu ví dụ sau:
Lập bảng kê chứng từ gồm các thông tin: Ngay_Ct, So_Ct, Dien_Giai, Ten_Dt, Ong_Ba, Dia_Chi.
Phân tích ví dụ trên chúng ta thấy thông tin Ten_Dt được lấy từ bảng danh mục khách hàng, nhà cung cấp (DMDT), các thông tin còn lại lấy từ bảng chứng từ (CT), hai bảng này liên kết với nhau bằng trường Ma_Dt. Câu lệnh truy vấn như sau:
SELECT CT.Ngay_Ct, CT.So_Ct,
CT.Dien_Giai, DMDT.Ten_Dt,
CT.Ong_Ba, CT.Dia_Chi
FROM DMDT, CT
WHERE DMDT.Ma_Dt = CT.Ma_Dt
Kết quả:
33
Ngay_Ct So_Ct Dien_Giai Ten_Dt Ong_Ba Dia_Chi
2011-01-06
PX001 Xuất hàng hóa bán đại lý
Công ty TNHH ABC
Lê Văn Khương
Hà N
2011-01-07
PX002 Xuất hàng hóa bán đại lý
Công ty TNHH ABC
Đào Thị Hạnh
Hà N
2011-01-06 PN001 Nhập vật tư phục vụ sản xuất
Công ty Cổ phần CB thực phẩm miền bắc
Tạ Thu Loan
Công ty
Như vậy kết quả truy vấn là phần dữ liệu có mối quan hệ giữa hai bảng cơ sở dữ liệu.
Một số ví dụ
- Lập bảng kê chứng từ nhập hàng chi tiết theo vật tư gồm có các thông tin Ma_Ct, Ngay_Ct, So_Ct, Dien_Giai, Ma_Dt, Ma_Vt, So_Luong, Don_Gia, Thanh_Tien.
SELECT Ct.Ma_Ct, Ct.Ngay_Ct,Ct.So_Ct,
Ct.Dien_Giai, Ct.Ma_Dt,
CtCt.Ma_Vt, CtCt.So_Luong,
34
CtCt.Don_Gia,
ISNULL(CtCt.Don_Gia * CtCt.So_Luong, 0) AS Thanh_Tien
FROM Ct, CtCt
WHERE Ct.Stt_Ct = CtCt.Stt_Ct AND Ct.Ma_Ct = ‘PN’
ORDER BY Ct.Ngay_Ct
Kết quả:
Ma_Ct Ngay_Ct So_Ct Dien_Giai Ma_Dt Ma_Vt So_Luong
PN 01/06/11 PN001 Nhập vật tư phục vụ sản xuất
N002 VT001 120
PN 01/06/11 PN001 Nhập vật tư phục vụ sản xuất
N002 VT002
PN 02/06/11 PN002 Nhập nguyên liệu
N005 VT004
PN 02/06/11 PN002 Nhập nguyên liệu
N005 VT001
PN 02/06/11 PN002 Nhập nguyên liệu
N005 VT003
- Lập bảng kê chứng từ theo tổng tiền (chi tiết theo chứng từ) bao gồm các thông tin Ma_Ct, Ngay_Ct, So_Ct, Dien_Giai, Ten_Dt, Tong_Tien.
SELECT MAX(Ct.Ma_Ct) AS Ma_Ct, MAX(Ct.Ngay_Ct) AS Ngay_Ct,
MAX(Ct.Dien_Giai) AS Dien_Giai,
MAX(DmDt.Ten_Dt) AS Ten_Dt,
SUM(CtCt.Don_Gia * CtCt.So_Luong) AS Tong_Tien
35
FROM Ct, CtCt, DmDt
WHERE Ct.Stt_Ct = CtCt.Stt_Ct
AND Ct.Ma_Dt = DmDt.Ma_Dt
GROUP BY CtCt.Stt_Ct
Kết quả:
Ma_Ct Ngay_Ct Dien_Giai Ten_Dt
PX 31/05/11 Xuất hàng hóa bán đại lý Cty TNHH ABC
PX 01/06/11 Xuất hàng hóa bán đại lý Cty TNHH ABC
PN 01/06/11 Nhập vật tư phục vụ sản xuất Cty Cổ phần CB thực phẩm miền bắc
PX 01/06/11 Xuất bán hàng hóa Cty TNHH một thviên cấp nước Yên Bái
PN 02/06/11 Nhập nguyên liệu Cty Cổ phần Lạc Hồng
PX 05/06/11 Xuất bán hàng hóa Cty TNHH một thviên cấp nước Yên Bái
7.2. INNER JOIN (nội kết)
Tương tự như phép nối sử dụng mệnh đề WHERE, chúng ta có thể sử dụng INNER JOIN để chỉ ra phép kết nối rõ hơn. Viết lại ví dụ ở phần trên với INNER JOIN như sau:
SELECT CT.Ngay_Ct, CT.So_Ct,
CT.Dien_Giai, DMDT.Ten_Dt,
CT.Ong_Ba, CT.Dia_Chi
FROM DMDT INNER JOIN CT ON DMDT.Ma_Dt = CT.Ma_Dt
Câu lệnh trên tương đối tường minh từ khóa INNER JOIN nằm giữa hai bảng kết nối sau FROM và biểu thức kết nối nằm sau từ khóa ON.
7.3. Sử dụng bí danh của bảng
36
Tương tự như các trường tính toán, khi sử dụng phép nối chúng ta cũng có thể tạo bí danh cho bảng, với việc sử dụng bí danh câu lệnh truy vấn sẽ ngắn ngọn và tường minh hơn, để tìm hiểu kỹ hơn về chủ đề này hãy viết lại các ví dụ phần trước với câu lệnh SQL có sử dụng bí danh.
Ví dụ:
Viết lại các ví dụ sau sử dụng bí danh bảng.
- Lập bảng kê chứng từ nhập hàng chi tiết theo vật tư gồm có các thông tin Ma_Ct, Ngay_Ct, So_Ct, Dien_Giai, Ma_Dt, Ma_Vt, So_Luong, Don_Gia, Thanh_Tien
SELECT Ct.Ma_Ct, Ct.Ngay_Ct,Ct.So_Ct,
Ct.Dien_Giai, Ct.Ma_Dt,
Ct0.Ma_Vt, Ct0.So_Luong, Ct0.Don_Gia,
ISNULL(Ct0.Don_Gia * Ct0.So_Luong, 0) AS Thanh_Tien
FROM Ct, CtCt AS Ct0
WHERE Ct.Stt_Ct = Ct0.Stt_Ct AND Ct.Ma_Ct = ‘PN’
ORDER BY Ct.Ngay_Ct
- Lập bảng kê chứng từ theo tổng tiền (chi tiết theo chứng từ) bao gồm các thông tin Ma_Ct, Ngay_Ct, So_Ct, Dien_Giai, Ten_Dt, Tong_Tien.
SELECT MAX(Ct.Ma_Ct) AS Ma_Ct, MAX(Ct.Ngay_Ct) AS Ngay_Ct,
MAX(Ct.Dien_Giai) AS Dien_Giai,
MAX(Dt.Ten_Dt) AS Ten_Dt,
SUM(Ct0.Don_Gia * Ct0.So_Luong) AS Tong_Tien
FROM Ct, CtCt AS Ct0, DmDt AS Dt
WHERE Ct.Stt_Ct = Ct0.Stt_Ct
37
AND Ct.Ma_Dt = Dt.Ma_Dt
GROUP BY Ct0.Stt_Ct
7.4. OUTER JOIN (Ngoại kết)
Với hai cách kết nối như đã trình bày ở trên kết quả dữ liệu truy vấn trả về là những dữ liệu có quan hệ với nhau, tuy nhiên trong thực tế chúng ta thường xuyên cần lấy cả những dữ liệu ở một bảng nào đó mà chúng chưa có quan hệ với các bảng còn lại, khi đó có thể sử dụng OUTER JOIN. Khi sử dụng OUTER JOIN bắt buộc phải kết hợp với một trong hai từ khóa là RIGHT và LEFT. Hãy cùng tìm hiểu ví dụ sau đây:
Hãy lập danh sách khách hàng, nhà cung cấp bao gồm thông tin mã, tên, địa chỉ và số lượng chứng từ nhập xuất (danh sách bao gồm cả những khách hàng, nhà cung cấp chưa có giao dịch).
SELECT dt.Ma_Dt, max(dt.Ten_Dt) AS Ten_Dt,
MAX(dt.Dia_Chi) AS Dia_Chi,
COUNT(ct.So_Ct) AS So_Ct_Nx
FROM DmDt as dt LEFT OUTER JOIN CT ON dt.Ma_Dt = Ct.Ma_Dt
GROUP BY dt.Ma_Dt
Kết quả
Ma_Dt Ten_Dt Dia_Chi So_Ct_Nx
N001 Công ty TNHH ABC Hà Nội 2
N002 Công ty Cổ phần CB thực phẩm miền bắc
Hà Nội 1
N003 Công ty liên doanh Việt Pháp
Hải Phòng
0
N004 Công ty TNHH một thành viên cấp nước Yên Bái
NULL 0
38
Như vậy toàn bộ dự liệu có quan hệ giữ hai bảng và dữ liệu của bảng bên trái của OUTER JOIN được hiển thị trong kết quả truy vấn.
Trường hợp ngược lại chúng ta có thể dùng từ khóa RIGHT kết quả truy vấn sẽ lấy toàn bộ dữ liệu quan hệ giữa hai bảng và dữ liệu còn lại của bảng bên phải của OUTER JOIN.
Một số ví dụ
- Lập báo cáo tổng hợp nhập kho bao gồm các thông tin Ma_Vt, Ten_Vt, Dvt, So_Luong, Don_Gia, Thanh_Tien.
SELECT Ct0.Ma_Vt, Vt.Ten_Vt, Vt.Dvt,
Ct0.So_Luong, Ct0.Don_Gia,
39
Ct0.So_Luong * Ct0.Don_Gia AS Thanh_Tien
FROM CtCt AS Ct0 LEFT OUTER JOIN DmVt AS Vt
ON Ct0.Ma_Vt = Vt.Ma_Vt
LEFT OUTER JOIN Ct ON Ct0.Stt_Ct = Ct.Stt_Ct
WHERE Ct.Ma_Ct = ‘PN’
Kết quả:
Ma_Vt Ten_Vt Dvt So_Luong Don_Gia Thanh_Tien
VT001 Bột mì loại 1 Kg 120 30.000 3.600.000
VT002 Hương liệu Kg 15 120.000 1.800.000
VT004 Socola nguyên liệu
Kg 30 75.000 2.250.000
VT001 Bột mì loại 1 Kg 32 31.000 992.000
VT003 Bột nở Kg 56 120.000 6.720.000
- Lập bảng kê chứng từ nhập hàng chi tiết theo vật tư gồm có các thông tin Ma_Ct, Ngay_Ct, So_Ct, Dien_Giai, Ten_Dt, Ten_Vt, Dvt, So_Luong
SELECT Ct.Ma_Ct, Ct.Ngay_Ct, Ct.Dien_Giai, Dt.Ten_Dt,
Ct0.Ma_Vt, Vt.Ten_Vt, Vt.Dvt, Ct0.So_Luong
FROM CtCt AS Ct0 LEFT OUTER JOIN Ct ON Ct0.Stt_Ct = Ct.Stt_Ct
LEFT OUTER JOIN DmDt AS Dt ON Ct.Ma_Dt = Dt.Ma_Dt
LEFT OUTER JOIN DmVt AS Vt ON Ct0.Ma_Vt = Vt.Ma_Vt
WHERE Ct.Ma_Ct = ‘PN’
Kết quả:
40
Ma_Ct Ngay_Ct Dien_Giai Ten_Dt Ma_Vt Ten_Vt
PN 01/06/11 Nhập vật tư phục vụ sản xuất
Cty Cổ phần CB thực phẩm miền bắc
VT001 Bột mloại 1
PN 01/06/11 Nhập vật tư phục vụ sản xuất
Cty Cổ phần CB thực phẩm miền bắc
VT002 Hương liệu
PN 02/06/11 Nhập nguyên liệu
Cty Cổ phần Lạc Hồng
VT004 Socola nguyên liệu
PN 02/06/11 Nhập nguyên liệu
Cty Cổ phần Lạc Hồng
VT001 Bột mloại 1
PN 02/06/11 Nhập nguyên liệu
Cty Cổ phần Lạc Hồng
VT003 Bột nở
8. Kết hợp các query
Hầu hết các query SQL chứa một câu lệnh SELECT đơn vốn trả về dữ liệu từ một hoặc nhiều bảng. Tuy nhiên SQL cũng cho phép bạn thực hiện nhiều câu Query và kết quả trả về dưới dạng một tập hợp dữ liệu từ các Query đơn.
Để kết hợp các Query đơn với nhau chúng ta dùng từ khóa UNION đặt giữa mỗi câu lệnh SELECT, cũng ở ví dụ phần trước chúng ta thêm một dòng tổng cộng để biết xem tổng số chứng từ nhập xuất của tất cả khách hàng nhà cung cấp.
Câu lệnh SQL như sau:
SELECT dt.Ma_Dt, max(dt.Ten_Dt) AS Ten_Dt,
MAX(dt.Dia_Chi) AS Dia_Chi,
COUNT(ct.So_Ct) AS So_Ct_Nx
FROM DmDt as dt LEFT OUTER JOIN CT ON dt.Ma_Dt = Ct.Ma_Dt
GROUP BY dt.Ma_Dt
UNION
41
SELECT '' AS Ma_Dt, N'Tổng cộng' AS Ten_Dt,
'' AS Dia_Chi, COUNT(*) AS So_Ct_Nx
FROM CT
Kết quả:
Ma_Dt Ten_Dt Dia_Chi So_Ct_Nx
Tổng cộng 3
N001 Công ty TNHH ABC Hà Nội 2
N002 Công ty Cổ phần CB thực phẩm miền bắc
Hà Nội 1
N003 Công ty liên doanh Việt Pháp
Hải Phòng
0
N004 Công ty TNHH một thành viên cấp nước Yên Bái
NULL 0
Lưu ý:
- Một UNION phải có từ 2 câu lệnh SELECT trở lên, mỗi câu lệnh được tách bởi từ khóa UNION
- Danh sách cột của các câu SELECT trong cùng một UNION phải tương ứng và cùng kiểu
- Sử dụng UNION ALL khi muốn lấy tất cả các lần xuất hiện của các giá trị thỏa mãn
9. Chèn dữ liệu
9.1. Chèn dữ liệu trực tiếp
Cú pháp:
INSERT INTO <Ten_Bang> [(Danh_Sach_Truong)]
VALUE (<Danh_Sach_Gia_Tri>)
Giải thích:
- <Ten_Bang>: Tên bảng cần chèn dữ liệu
42
- [(Danh_Sach_Truong]): Danh sách trường cần chèn dữ liệu được liệt kê trong dấu ngoặc đơn, danh sách trường có thể bỏ trắng nếu chèn dữ liệu vào tất cả các dòng.
- <Danh_Sach_Gia_Tri>: Danh sách giá trị tương ứng với danh sách trường cần chèn dữ liệu
Ví dụ:
Viết câu lệnh chèn dữ liệu trong danh sách sau vào bảng DmVt
Ma_Vt Ten_Vt Dvt Quy_Cach
TP001 Bánh trứng Custas Hộp Hộp 20 cái
TP002 Bánh kem xốp Gói Gói 200 gram
TP003 Bánh kem bơ Gói Gói 150 gram
TP004 Bánh Socola Vinasun
Hộp Hộp 6 cái
INSERT INTO DmVt
(
Ma_Vt,
Ten_Vt,
Dvt,
Quy_Cach
)
VALUES
(
N‘TP001’,
N‘Bánh trứng Custas’,
N’Hộp’,
N’Hộp 20 cái’
)
43
9.2. Chèn dữ liệu truy vấn
Cú pháp:
INSERT INTO <Ten_Bang> [(Danh_Sach_Truong)]
SELECT <Danh_Sach_Truong_Truy_Van>
FROM <Ten_Bang_Truy_Van>
...
Giải thích:
- Giá trị dữ liệu có thể được lấy từ một Query, danh sách trường trong câu Query này phải tương ứng với các trường cần chèn dữ liệu.
- Các tùy chọn và mệnh đề có thể sử dụng trong Query lấy dữ liệu như WHERE, GROUP BY.
9.3. Sao chép dữ liệu từ bảng khác
Cú pháp:
SELECT * INTO <Ten_Bang_Can_Chen_DL>
FROM <Ten_Bang_Chua_DL>
Giải thích:
- <Ten_Bang_Can_Chen_DL>: Bảng cần chèn dữ liệu
- <Ten_Bang_Chua_DL>: Bảng chứa dữ liệu cần chèn
- Bất kỳ các tùy chọn và mệnh đề SELECT có thể sử dụng bao gồm WHERE và GROUP BY.
10. Cập nhật, xóa dữ liệu
10.1. Cập nhật chỉnh sửa dữ liệu
Cú pháp:
UPDATE <Ten_Bang>
SET <Truong_Cap_Nhat1> = <Gia_Tri_Cap_Nhat1>,
44
<Truong_Cap_Nhat2> = <Gia_Tri_Cap_Nhat2>,
.....................................
<Truong_Cap_NhatN> = <Gia_Tri_Cap_NhatN>
WHERE <Dieu_Kien_Cap_Nhat>
Giải thích:
- <Ten_Bang>: Tên bảng cần cập nhật dữ liệu
- <Truong_Cap_Nhat>: Tên trường cần cập nhật dữ liệu
- <Gia_Tri_Cap_Nhat>: Giá trị mới cần cập nhật và trường tương ứng
- <Dieu_Kien_Cap_Nhat>: Biểu thức điều kiện cập nhật dữ liệu
Ví dụ:
- Sửa lại tên cho vật tư có “Bánh trứng Custas” thành “Bánh trứng Custas loại 1” trong bảng DmVt.
UPDATE DmVt
SET Ten_Vt = N’Bánh trứng Custas loại 1’
WHERE Id = 1
- Sửa lại mã “Công ty TNHH ABC” từ “N001” thành “N009”
- Do mã số của “Công ty TNHH ABC” bị thay đổi ở phần trước hãy tìm và thay đổi tất cả thông tin này ở các bảng tương ứng.
10.2. Xóa dữ liệu
Cú pháp:
DELETE FROM <Ten_Bang>
WHERE <Dieu_Kien_Xoa>
Giải thích:
- <Ten_Bang>: Tên bảng cần xóa dữ liệu
45
- <Dieu_Kien_Xoa>: Biểu thức điều kiện xóa dữ liệu
Ví dụ:
- Do sai sót nhân viên kho nhập nhầm vật tư có mã “VT002” hãy xóa vật tư này khỏi DmVt
DELETE FROM DmVt WHERE Ma_Vt = ‘VT002’
- Do vật tư có mã “VT002” không tồn tại hãy tìm và xóa phát sinh của vật tư này trong các bảng tương ứng để đảm bảo toàn vẹn dữ liệu.
Lưu ý khi thực thi câu lệnh UPDATE hoặc DELETE
- Nếu một câu lệnh cập nhật hoặc xóa dữ liệu không có mệnh đề WHERE nó sẽ áp dụng cho tất cả dữ liệu trong bảng.
- Trước khi thực hiện hai câu lệnh trên hãy sử dụng mệnh đề WHERE trong một lệnh SELECT để chắc chắn dữ liệu cần cập nhật hay xóa là chính xác.
- Không nên cập nhật hoặc xóa các dữ liệu có quan hệ với các bảng khác trong cùng một cơ sở dữ liệu.
11. Bài tập thực hành
- Lập danh sách những mặt hàng chưa được bán trong tháng 06 năm 2011 bao gồm các thông tin Ma_Vt, Ten_Vt, Dvt.
- Lập danh sách những mặt hàng bán chạy nhất trong tháng 06 năm 2011 bao gồm các thông tin Ma_Vt, Ten_Vt, Dvt, So_Luong, kết quả sắp xếp giảm dần theo số lượng.
- Lập bảng kê chứng từ nhập kho tháng 06 năm 2011 bao gồm các thông tin Ma_Ct, Ngay_Ct, So_Ct, Dien_Giai, Tong_Tien, Ten_Dt.
- Lập danh sách 02 khách hàng mua nhiều nhất trong tháng 06 năm 2011 (tính theo doanh số) bao gồm các thông tin Ma_Dt, Ten_Dt, Dia_Chi, So_Dt, Doanh_So.
- Lập danh sách những khách hàng mua hàng có tổng trị giá lớn hơn 5 triệu trong tháng 06 năm 2011 để làm căn cứ tính chiết khấu, danh
46
sách này giảm dần theo doanh số bán hàng. Kết quả hiển thị bao gồm các trường Ma_Dt, Ten_Dt, Dia_Chi, Doanh_So
- Thông kê 2 loại vật tư nhập nhiều nhất trong tháng 06 bao gồm các thông tin Ma_Vt, Ten_Vt, Dvt, Tien_Nhap.
- Lập danh sách những mặt hàng bán trong tháng 05 năm 2011 nhưng lại chưa được bán trong tháng 06 năm 2011, kết quả bao gồm các thông tin Ma_Vt, Ten_Vt, Dvt, So_Luong_T5, Don_Gia_T5, Thanh_Tien_T5.
- Lập báo cáo tổng hợp nhập kho theo quy cách sau đây: Ma_Vt, Ten_Vt, Dvt, So_Luong_T5, So_Luong_T6.
- Lập báo cáo nhập xuất vật tư đơn giản theo mẫu sau: Ma_Vt, Ten_Vt, Dvt, So_Luong_Nhap, So_Luong_Xuat.
- Thống kê vật tư nhập theo kho với các thông tin sau: Ten_Kho, Ten_Vt, So_Luong, Don_Gia, Thanh_Tien.
47
Bài 2 – Giới thiệu về phiên bản SQL Server 2008
1. Hệ quản trị cơ sở dữ liệu
Giới thiệu chung về hệ quản trị cơ sở dữ liệu
Hệ quản trị cơ sở dữ liệu (tiếng Anh: Database Management System - DBMS), là phần mềm hay hệ thống được thiết kế để quản trị một cơ sở dữ liệu. Cụ thể, các chương trình thuộc loại này hỗ trợ khả năng lưu trữ, sửa chữa, xóa và tìm kiếm thông tin trong một cơ sở dữ liệu (CSDL). Có rất nhiều loại hệ quản trị CSDL khác nhau: từ phần mềm nhỏ chạy trên máy tính cá nhân cho đến những hệ quản trị phức tạp chạy trên một hoặc nhiều siêu máy tính.
Tuy nhiên, đa số hệ quản trị CSDL trên thị trường đều có một đặc điểm chung là sử dụng ngôn ngữ truy vấn theo cấu trúc mà tiếng Anh gọi là Structured Query Language (SQL). Các hệ quản trị CSDL phổ biến được nhiều người biết đến là MySQL, Oracle, PostgreSQL, SQL Server, DB2, Infomix, v.v. Phần lớn các hệ quản trị CSDL kể trên hoạt động tốt trên nhiều hệ điều hành khác nhau như Linux, Unix và MacOS ngoại trừ SQL Server của Microsoft chỉ chạy trên hệ điều hành Windows.
- Ưu điểm của HQTCSDL:
+ Quản lý được dữ liệu dư thừa.
+ Đảm báo tính nhất quán cho dữ liệu.
48
+ Tạo khả năng chia sẻ dữ liệu nhiều hơn.
+ Cải tiến tính toàn vẹn cho sữ liệu.
- Nhược điểm:
+ HQTCSDL tốt thì khá phức tạp.
+ HQTCSDL tốt thường rất lớn chiếm nhiều dung lượng bộ nhớ.
+ Giá cả khác nhau tùy theo môi trường và chức năng.
+ HQTCSDL được viết tổng quát cho nhiều người dùng thì thường chậm.
Giới thiệu về phiên bản SQL Server 2008
Microsoft SQl server là một hệ quản trị cơ sở dữ liệu quan hệ (relational database management system – RDBMS) do Microsoft phát triển.
SQL Server là một hệ quản trị cơ sở dữ liệu quan hệ mạng máy tính hoạt động theo mô hình khách chủ cho phép đồng thời cùng lúc có nhiều người dùng truy xuất đến dữ liệu, quản lý việc truy nhập hợp lệ và các quyền hạn của từng người dùng trên mạng.
Ngôn ngữ truy vấn quan trọng của Microsoft SQL server là Transact-SQL
Lần lượt các phiên bản của Microsoft SQL Server đã ra đời sau sự kiện này, từ 4.2 sau đó được nâng cấp thành 4.21, 6.0, 6.5, 7.0 và hiện giờ là Microsoft SQL Server 2000, 2005 và mới nhất là Microsoft SQL Server 2008.
- SQL Server 2005: SQL Server 2005, được phát hành vào tháng 11 năm 2005, là phiên bản tiếp theo của SQL Server 2000. Sử dụng trên nền Net Framework 2.0
- SQL Server 2008: Đây là phiên bản mới nhất của SQl Server. Ngày 27/02/2008, Sử dụng trên nền Net Framework 3.0.
2. Cài đặt SQL Server 2008
49
Đối với các máy tính chưa được cài đặt .Net FrameWork phiên bản 3.5 trở lên trước khi cài SQL Server 2008 hệ thống yêu cầu cài đặt .Net FrameWork 3.5 và bản nâng cấp Windows. Trường hợp này thường xảy ta với các máy sử dụng Windows XP hoặc Windows Server từ bản 2003 trở xuống.
2.1. Cài đặt .Net FrameWork 3.5
- Chạy File cài đặt .Net FrameWork 3.5 nếu có hoặc tải về từ đường dẫn: http://go.microsoft.com/fwlink/?LinkId=159615. Một cách đơn giản hơn bạn hãy nhấp đúp chọn File cài đặt SQL 2008 máy tính sẽ tự động kiểm tra và thông báo như hộp thoại dưới đây:
Nhấp chọn các đường Link tương ứng để tải File về máy tính
- Chờ trong giây lát hộp thoại cài đặt .Net FrameWork 3.5 xuất hiện như hình dưới đây:
50
Tích chọn mục “I have read and ACCEPT terms…” sau đó nhấp nút Install.
- Hộp thoại tiến trình cài đặt xuất hiện
51
- Chờ máy tính thực hiện tiến trình, cuối cùng nhấp chọn Exit để hoàn tất.
52
2.2. Cài đặt bản nâng cấp Windows
- Tương tự như cài đặt .Net FrameWork 3.5, thực hiện cài bản nâng cấp cho Windows bằng cách nhấp chọn File cài đặt này sau khi đã tải về máy tính. Hộp thoại cài đặt xuất hiện nhấp Next để chuyển sang bước tiếp theo.
53
Trong hộp thoại thông báo các điều khoản cam kết bản quyền với nhà cung cấp nhấp chọn “I Agree” sau đó nhấp Next để tiến hành cài đặt.
54
- Sau khi cài đặt xong máy tính sẽ xuất hiện thông báo yêu cầu khởi động lại máy tính, hãy nhấp Finish để hoàn tất.
2.3. Cài đặt SQL Server 2008
Sau khi máy tính đã được cập nhật đầy đủ hãy tiến hành cài đặt SQL Server 2008 theo các bước dưới đây:
Bước 1: Nhấp đúp chuột vào File setup.exe trong thư mục chứa bộ cài đặt. Hộp thoại SQL Server Installation Center xuất hiện, nhấp chọn New installation or add features to…
55
Bước 1: Nhấp đúp chuột vào File setup.exe trong thư mục chứa bộ cài đặt. Hộp thoại SQL Server Installation Center xuất hiện, nhấp chọn New installation or add features to…
Chờ giây lát cho các xử lý hệ thống
Bước 2: Trong màn hình Setup Support Files nhấp Istall để bắt đầu cài đặt
56
Bước 3: Trong cửa sổ Installation Type:
- Tùy chọn New installation or add shared features: Cài đặt SQL trên Instance Name mới (SQL có thể chứa nhiều Instance Name khác nhau trên cùng một hệ thống).
- Tùy chọn Add features to an exiting instance of SQL Server…: Cài đặt SQL trên Instance Name đã tồn tại.
Nhấp Next để chuyển sang bước tiếp theo
Bước 4: Tích chọn I accept the license terms
57
Bước 5: Tích chọn tất cả các mục trong phần Features:
Bước 6: Trong hộp thoại Instance Configuration:
- Default instance: Cài trên Instance Name mặc định.
- Named instance: Chỉ định tên Install Name mới.
- Instance ID: Id của Instance Name (để mặc định)
- Instance root derectory: Thư mục vật lý cài đặt Instance Name (để mặc định)
Thông thường nên chọn mục Named instance và đặt tên cho Instance Name mới như hình ảnh trên. Nhấp Next để chuyển sang bước tiếp theo.
58
Bước 7: Trong cửa sổ khai báo tài khoản cho các dịch vụ chúng ta để mặc đinh và nhấp Next để chuyển sang bước tiếp theo.
Bước 8: Cửa sổ Database Engine Configuration:
- Windows authentication mode: Truy cập Database với tài khoản của Windows.
- Mixed Mode: Truy cập Database với tài khoản sa của SQL, với tùy chọn này bạn phải đặt tài Password cho tài khoản sa ở mục Enter password và confirm password.
Thông thường chúng ta tích chọn mục Windows authentication Mode, sau đó nhấp Next để chuyển bước tiếp theo.
59
Bước 9: Nhấp Next để máy tính bắt đầu cài đặt
Bước 10: Chờ máy tính cài đặt trong giây lát, cuối cùng nhấp Close để hoàn tất
2.4. Khởi động SQL server 2008
- Từ thanh Start nhấp chọn All Program/ Microsoft SQL Server 2008 R2/ SQL Server Management Studio.
- Trong mục Server Name nhập đầy đủ tên máy tính và Install Name vừa cài đặt.
60
Trong hình ảnh trên chúng ta thấy tên máy tính được ngăn cách với tên Istance Name bằng ký tự “\”.
- Tiếp theo nhấp Connect để truy cập vào SQL Server 2008, kết quả như hình dưới đây:
3. Một số thao tác cơ bản với SQL Server 2008
61
Tìm hiểu giao diện và các thành phần cơ bản
3.1. Kết nối tới Sever
Để kết nối tới Server chúng ta thực hiện các bước sau:
Bước 1: Chọn Connect/Database Engine… trong cửa sổ Object Explorer
62
Bước 2: Hộp thoại Connect to Server xuất hiện
Trong mục Server name chọn tới Server cần kết nối
63
Bước 3: Nhấp Connect để thực hiện kết nối.
3.2. Tìm hiểu cửa sổ New Query
Cửa sổ New Query dùng để viết và thực thi các câu lệnh SQL giao tác với các thành phần của Server. Dưới đây là các bước đơn giản để viết và thực thi một câu lệnh SQL đơn giản sử dụng cửa sổ New Query.
Bước 1: Nhấp chọn biểu tượng New Query trên thanh công cụ
Một màn hình soạn thảo xuất hiện chính giữa cửa sổ giao diện
Bước 2: Chọn Database cần giao tác trong hộp chọn Available Database
64
Bước 3: Viết câu lệnh SQL trong màn hình soạn thảo New Query
Bước 4: Nhấn F5 hoặc nhấp chọn biểu tượng Execute để thực thi câu lệnh
Kết quả câu lệnh SQL hiển thị trên màn hình soạn thảo New Query
65
4. Quản lý Database đơn giản
4.1. Tạo mới một DataBase
Bước 1: Đăng nhập SQL Server 2008
Bước 2: Trong cửa sổ Object Explorer nhấp phải chuột vào mục DataBase chọn New DataBase.
66
Bước 3: Hộp thoại tạo DataBase mới xuất hiện như hình dưới đây:
Trong Tab General
- DataBase Name: Nhập vào tên DataBase cần tạo
- Database file: Tại cột Path nhập vào đường dẫn chứa File DataBase (bao gồm cả đường dẫn cho File Log).
Như ví dụ trên chúng ta đang tạo một DataBase mới có tên QLHTK và được lưu trữ tại ổ D: của máy tính.
Bước 4: Cuối cùng nhấp Ok để hoàn tất, như vậy trong danh sách Database ở cửa sổ Object Explorer đã xuất hiện một DataBase mới có tên là QLHTK.
67
Lưu ý: Sau khi thực hiện xong các bước trên mà vẫn không thấy Database mới xuất hiện trong danh sách, hãy nhấp phải chuột vào mục Database trong cửa sổ Object Explorer chọn Refresh.
Sau khi đã tạo được DataBase mới để có thể thực hành những ví dụ đơn giản với SQL Server 2008 chúng ta có thể tạo một bảng đơn giản bằng các bước như sau:
Bước 1: Trong cửa sổ Object Explorer chọn tới mục Table trong cơ sở dữ liệu vừa tạo, nhấp phải chuột chọn New Table…
68
Bước 2: Hộp thoại tạo bảng xuất hiện như hình dưới đây:
69
Ở phần phía trên khai báo danh sách cột gồm các thông tin sau:
- Column Name: Tên cột (trường)
- Data Type: Kiểu dữ liệu
- Allow Nulls: Tích chọn nếu cho phép trường nhận giá trị NULL, ngược lại không tích chọn nếu không cho phép trường nhận giá trị NULL.
Ở phần phía dưới Column Properties cho phép khai báo các thuộc tính cho từng cột (trường) phần này sẽ được trình bày chi tiết trong các bài tiếp theo.
Nhấp vào dòng dưới cùng trên phần khai báo danh sách cột để thêm một cột mới
Bước 3: Sau khi đã nhập đầy đủ các cột (trường) cho bảng, hãy vào File\Save để lưu lại bảng, hộp thoại Choose Name xuất hiện, nhập tên cho bảng cần thêm mới sau đó nhấp Ok để hoàn tất.
70
Bước 4: Thử tìm xem bảng vừa tạo đang ở đâu? Trong cửa sổ Object Explorer chọn tới DataBase vừa tạo mở rộng mục Table trong phần này sẽ chứa bảng mà chúng ta vừa tạo.
4.2. Cất dữ DataBase (Backup)
Khi cần cất trữ DataBase chúng ta sử dụng chức năng Backup để ném dữ liệu và cất trữ ở dạng File vật lý. Các bước thực hiện như sau:
Bước 1: Chọn DataBase cần cất trữ trong cửa sổ Object Explorer.
71
Giả sử như chúng ta chọn Database vừa tạo
Bước 2: Nhấp phải chuột vào Database này chọn Tasks/Back Up…
72
Bước 3: Cửa sổ Back up.. Database xuất hiện như hình dưới đây:
Trong Tab General, tại mục Destination thông thường SQL Server 2008 chọn sẵn thư mục lưu File Backup tại ổ C:\ của máy tính, tuy nhiên chúng ta nên lưu tại một đường dẫn nào đó an toàn hơn bằng cách nhấp chọn Remove, sau đó nhấp nút Add.
Bước 4: Hộp thoại Select Backup Destination xuất hiện như hình dưới đây:
73
Nhấp chuột vào nút (…) để chọn đường dẫn mới
74
Như hình ảnh trên chúng ta lưu File Backup tại ổ đĩa D:\ của máy tính, bạn đừng quên đặt tên cho File Backup trong mục File name với phần mở rộng là .bak, như ví dụ trên File Backup sẽ được lưu tại ổ D:\ và có tên là QLHTK.bak. Nhấp Ok để chọn đường dẫn và xác nhận tên File Backup, tiếp tục nhấp Ok ở màn hình Select Backup Destination với đường dẫn mới.
75
Bước 5: Sau bước trên chúng ta được kết quản màn hình Backup Database như hình dưới đây:
76
Bạn tiếp tục chọn tới Tab Options trong mục Select a page
Trên Tab này nhấp chọn mục Overwrite all existing backup set để ghi đè lên dữ liệu cũ đã tồn tại nếu có. Cuối cùng nhấp Ok để máy tính thực hiện Backup, chờ trong giây lát chương trình sẽ thông báo hoàn tất thao tác như hình dưới đây:
Bước 6: Bây giờ hãy kiểm tra lại bằng cách truy cấp vào ổ D:\ của máy tính
77
Kết quả chúng ta sẽ thấy xuất hiện File Backup mới như hình ảnh trên.
4.3. Xóa DataBase (Delete)
Xóa vĩnh viễn Database khởi hệ quản trị cơ sở dữ liệu Sql Server 2008 và máy tính, các bước thực hiện như sau:
Bước 1: Chọn Database cần xóa trong Object Explorer.
Bước 2: Nhấp phải chuột vào Database này chọn Delete
78
Bước 3: Hộp thoại Delete Object xuất hiện nhấp Ok để thực hiện xóa.
79
4.4. Phục hồi DataBase (Restore)
Phục hồi Database Backup, chỉ thực hiện được khi chúng ta có File Backup về Database đó, cách thực hiện như sau:
Bước 1: Nhấp phải chuột vào mục Database trong Object Explorer chọn Restore DataBase…
80
Bước 2: Hộp thoại Restore Database xuất hiện như hình dưới đây:
Chúng ta có thể chọn Database để phục hồi dữ liệu từ File Backup hoặc phục hồi dữ liệu Backup thành một File mới, dưới đây chúng
81
ta sẽ thực hiện theo trường hợp thứ 2. Như vậy tại Tab General trong mục To Database hãy nhập trực tiếp vào tên Database mới cần tạo từ File backup ví dụ như hình ảnh trên chúng ta sẽ tạo ra một Database mới có tên QLHTK.
Bước 3: Cũng tại Tab General chọn From device sau đó nhấp chọn nút (…) hộp thoại Specify backup xuất hiện như hình dưới đây:
Nhấp Add để tìm tới File Backup cần Restore.
82
Giả sử chúng ta tìm thấy File cần Restore có tên là QLHTK.bak được lưu tại ổ D:\, nhấp chọn File này và nhấp Ok.
83
Trở lại với của sổ Specify Backup bạn tiếp tục nhấp Ok để xác nhận đường dẫn vừa chọn.
Bước 4: Khi đó màn hình Restore Database sẽ xuất hiện với những thông tin về Database backup, bạn hãy tích chọn vào cột Restore trong mục Select the backup set to restore.
84
Bước 5: Tích chọn Tab Options trong mục Select a page
85
Trong mục Restore the Database file as ở cột Restore As hãy chọn tới đường dẫn cần lưu File Database khi Restore, đây là đường dẫn đầy đủ bao gồm cả tên File và phần mở rộng. Thông thường ở dòng thứ nhất tên File có phần mở rộng là .mdf, dòng thứ 2 lưu File Log có phần mở rộng là .ldf.
Bước 6: Cuối cùng nhấp Ok để thực hiện Restore. Chúng ta có thể kiểm tra việc thực thi chức năng như phần thêm mới một Database.
4.5. Gở bỏ DataBase (Detach)
Khác với việc xóa Database, Detach chỉ gỡ bỏ Database khởi sự quản lý của hệ quản trị cơ sở dữ liệu SQL Server 2008 hiện thời. Các bước thực hiện như sau:
Bước 1: Chọn Database cần Detach trong cửa sổ Object Explorer
Bước 2: Nhấp phải chuột chọn Task/Detach…
86
Bước 3: Hộp thoại Detach Database xuất hiện nhấp Ok để thực hiện Detach
87
4.6. Đính kèm DataBase (Attach)
Gắn Database được Detach vào hệ quản trị cơ sở dữ liệu (HQTCSDL) SQL Server 2008, như vậy Attach chỉ thực hiện với những Database đã được Detach trước đó các bước thực hiện như sau:
Bước 1: Nhấp phải chuột vào mục Database trong cửa sổ Object Explorer chọn Attach…
88
Bước 2: Hộp thoại Attach Database xuất hiện như hình dưới đây:
Nhấp Add… để chọn tới Database cần Attach.
89
Bước 3: Sau bước 2 hộp thoại chọn Database xuất hiện
Như hình ảnh trên chúng ta chọn tới Database QLHTK.mdf lưu tại ổ D: của máy tính và vừa được Detach từ phần trước. Nhấp Ok để xác nhận chọn Database.
Bước 4: Bây giờ trở lại với cửa sổ Attach Database
90
Nhấp Ok để thực hiện Attach.
91
Bài 3 – Các đối tượng và một số xử lý trong SQL Server 2008
Thời lượng: 04 buổi
Nội dung cơ bản:
1. Câu lệnh SQL
1.1. Đối tượng
SQL Server được thiết kế theo kiểu hướng đối tượng vì vậy chúng ta có thể dễ dàng can thiệp tới chúng bằng câu lệnh T-SQL thông qua tên đối tượng. Tên đối tượng ở đây có thể là tên bảng, tên view, tên Trigger, tên thủ tục lưu (Store Procedure),…
Thông thường chúng ta có thể truy vấn trực tiếp bằng tên của đối tượng ví dụ:
USE QLHTK
SELECT * FROM DMDT
Như ví dụ trên “QLHTK” là tên Database và DMDT là tên bảng.
Trong một số trường hợp đặc biệt, khi tên đối tượng trùng với từ khóa hoặc chứa dấu khoảng trắng thì tên đối tượng đó phải đặt trong dấu ngoặc vuông.
SELECT Id, [Date], Code, Name FROM tblStaff
SELECT * FROM [INDEX]
1.2. Biến
- T-SQL cũng giống như các ngôn ngữ lập trình khác nghĩa là cần phải khai báo biến và kiểu dữ liệu cho biến trước khi sử dụng
- Tên biến bắt đầu bằng ký tự @ (Ví dụ: @_Ngay_Ct, @_Ma_Vt)
- Cú pháp khai báo biến:
DECLARE @<Ten_Bien> <Kieu_Du_Lieu>
92
+ Tên biến: Tên biến là tập hợp các ký tự chuỗi và số, tên biến không bao gồm khoảng trắng và ký tự đặc biệt.
+ Kiểu dữ liệu: Là một trong các kiểu chuẩn của SQL hoặc kiểu dữ liệu do người dùng tự định nghĩa.
- Gán giá trị cho biến:
SET @<Ten_Bien> = <Gia_Tri>
Hoặc
SELECT @<Ten_Bien> = <Gia_Tri>
- Ví dụ:
DECLARE @_Ho_Ten NVARCHAR(32)
DECLARE @_Nam_Sinh INT
DECLARE @_Nguyen_Quan NVARCHAR(64)
SET @_Ho_Ten = N‘Nguyễn Văn A’
SET @_Nam_Sinh = 1989
SET @_Nguyen_Quan = N‘Hải Dương’
/*In ra bien @_Ho_Ten sử dụng hàm RTRIM() để cắt khoảng trắng bên phải giá trị của biến*/
PRINT N‘Tên tôi là: ’ + RTRIM(@_Ho_Ten)
/*In ra bien @_Nam_Sinh sử dụng hàm CAST() để chuyển đổi kiểu INT thành kiểu CHAR()*/
PRINT N‘Sinh năm: ’ + CAST(@_Nam_Sinh AS CHAR(4))
PRINT N‘Nguyên quán: ’ + RTRIM(@_Nguyen_Quan)
Chúng ta có thể viết lại ví dụ trên sử dụng từ khóa SELECT để gán giá trị cho biến:
DECLARE @_Ho_Ten NVARCHAR(32)
DECLARE @_Nam_Sinh INT
DECLARE @_Nguyen_Quan NVARCHAR(64)
93
SELECT @_Ho_Ten = N‘Nguyễn Văn A’,
@_Nam_Sinh = 1989,
@_Nguyen_Quan = N‘Hải Dương’
/*In ra bien @_Ho_Ten sử dụng hàm RTRIM() để cắt khoảng trắng bên phải giá trị của biến*/
PRINT N‘Tên tôi là: ’ + RTRIM(@_Ho_Ten)
/*In ra bien @_Nam_Sinh sử dụng hàm CAST() để chuyển đổi kiểu INT thành kiểu CHAR()*/
PRINT N‘Sinh năm: ’ + CAST(@_Nam_Sinh AS CHAR(4))
PRINT N‘Nguyên quán: ’ + RTRIM(@_Nguyen_Quan)
Bài tập thực hành:
- Tạo biến để lưu trữ các thông tin về thẻ sinh viên bao gồm: Họ đệm, Tên, Mã sinh viên, Khóa học, Khoa, lớp
- In ra các biến ra màn hình theo quy chuẩn dưới đây:
+ Họ tên:……………………………………..
+ Mã sinh viên:……………………………….
+ Lớp: ………………Khoa:………………….
+ Khóa học: …………………………………..
1.3. Kiểu dữ liệu
Trong SQL Server, mỗi cột, biến địa phương, thể hiện và tham số có một kiểu dữ liệu liên quan. Một kiểu dữ liệu là một thuộc tính chỉ định kiểu dữ liệu mà các đối tượng có thể giữ: số nguyên, ký tự, tiền tệ, ngày tháng và thời gian, các chuỗi nhị phân, và như vậy SQL Server cung cấp một bộ các hệ thống kiểu dữ liệu để xác định tất cả các loại dữ liệu có thể được sử dụng với SQL Server. Ngoài ra bạn cũng có thể tự định nghĩa kiểu dữ liệu cho riêng mình (Học viên tự nghiên cứu)
Kiểu số
94
Kiểu dữ liệu Giới hạn mô tả Byte
Lưu trữ
Bigint Từ -2^63 (-9,223,372,036,854,775,808) đến 2^63-1 (9,223,372,036,854,775,807)
8 Bytes
Int Từ -2^31 (-2,147,483,648) đến 2^31-1 (2,147,483,647)
4 Bytes
Smallint Từ -2^15 (-32,768) đến 2^15-1 (32,767)
2 Bytes
Tinyint Từ 0 đến 255 1 Byte
Bit Nhận giá trị 0 (False), 1 (True) hoặc NULL
Decimal Từ - 10^38 +1 đến 10^38 - 1 Phụ thuộc và mô tả, từ 5 đến 17 Bytes
Numeric Từ - 10^38 +1 đến 10^38 - 1 Phụ thuộc và mô tả, từ 5 đến 17 Bytes
Money Từ -922,337,203,685,477.5808 đến 922,337,203,685,477.5807
8 bytes
Smallmoney - 214,748.3648 to 214,748.3647 4 bytes
Float Từ - 1.79E+308 đến -2.23E-308, 0 và từ 2.23E-308 đến 1.79E+308
Phụ thuộc vào mô tả
Real Từ - 3.40E + 38 đến -1.18E - 38, 0 và từ 1.18E - 38 đến 3.40E + 38
4 Bytes
Kiểu ngày tháng
Kiểu dữ liệu Giới hạn mô tả Byte
Lưu trữ
Date Từ 01/01/0001 đến 31/12/9999 3 Bytes
Time Từ 00:00:00.0000000 đến 23:59:59.9999999
5 Bytes
95
Datetime Ngày từ 1/1/1753 đến 31/12/9999
Giờ từ 00:00:00 đến 23:59:59.997
8 Bytes
SmallDatetime Ngày từ 01/01/1900 đến 06/06/2079
Giờ từ 00:00:00 đến 23:59:59
4 Byte
Kiểu ký tự
Kiểu dữ liệu Giới hạn mô tả Byte
Lưu trữ
Char Cú pháp: char(n), n từ 0 đến 8.000
n Bytes
Varchar Cú pháp: varchar(n), n từ 0 đến 8.000
n Bytes + 2 Bytes
Text Lưu trữ tối đa 2,147,483,647 Ký tự
Tối đa 2,147,483,647 bytes
nChar Cú pháp: nchar(n), n từ 0 đến 4.000
2*n Byte
nVarchar Cú pháp: nvarchar(n), n từ 0 đến 4.000
2*n Bytes + 2 Bytes
nText Lưu trữ tối đa 1,073,741,823 ký tự
1.4. Hàm
Hàm thống kê
Các hàm này sử dụng để thống kê các giá trị trong câu lệnh SELECT với mệnh đề GROUP BY
AVG Lấy giá trị trung bình
COUNT Đếm bản ghi
MIN Lấy giá trị nhỏ nhất
MAX Lấy giá trị lớn nhất
SUM Tính tổng
96
Hàm xử lý ngày tháng
a. GETDATE: Trả lại giờ hệ thống của máy trạm hiện thời
Cú pháp:
GETDATE()
b. GETUTCDATE: Trả về giờ hệ thống của Server
Cú pháp:
GETUTCDATE()
c. DATENAME: Trả về chuỗi tham số thời gian
Cú pháp:
DATENAME ( datepart , date )
Trong đó:
- datepart được chỉ định theo bảng dưới đây
datepart Viết rút gọn
year yy, yyyy
quarter qq, q
month mm, m
dayofyear dy, y
day dd, d
week wk, ww
weekday dw
hour hh
minute mi, n
second ss, s
97
- date: Giá trị ngày tháng cần lấy tham số
Ví dụ:
Ví dụ Kết quả
DATENAME ( year , '1/1/1991') 1991 – Năm của tham số ngày tháng
DATENAME ( dy , '8/12/1991') 244 – Ngày thứ 244 trong năm
DATENAME ( wk , '2/13/1991') 7 – Tuần thứ 7 của năm
Lưu ý: Nếu không có chỉ định trước SQL hiểu chuỗi ngày tháng bắt đầu bằng tháng sau đó là ngày và cuối cùng là năm.
d. DATEPART: Tương tựu hàm DATENAME nhưng giá trị trả về kiểu Integer
e. DAY: Trả về giá trị ngày của tham số ngày tháng
Cú pháp:
DAY(date)
Trong đó: date là tham số ngày tháng
Ví vụ: DAY(‘1/12/2003’) sẽ cho giá trị là 12
f. MONTH: Trả về giá trị tháng của tham số ngày tháng
Cú pháp:
MONTH(date)
Trong đó: date là tham số ngày tháng
Ví vụ: MONTH(‘1/12/2003’) sẽ cho giá trị là 1
g. YEAR: Trả về giá trị năm của tham số ngày tháng
Cú pháp:
YEAR(date)
Trong đó: date là tham số ngày tháng
98
Ví vụ: YEAR(‘1/12/2003’) sẽ cho giá trị là 2003
h. DATEDIFF: Trả về khoảng cách về năm, tháng, ngày giờ,… tham số ngày bắt đầu và ngày kết thúc
Cú pháp:
DATEDIFF ( datepart , startdate , enddate )
Trong đó:
- datepart: Theo bảng dưới đây:
datepart Viết rút gọn
year yy, yyyy
quarter qq, q
month mm, m
dayofyear dy, y
day dd, d
week wk, ww
weekday dw
hour hh
minute mi, n
second ss, s
- startdate: Ngày bắt đầu
- enddate: Ngày kết thúc
Ví dụ:
Ví dụ Kết quả
DATEDIFF ( year , '1/1/1991', ‘12/31/2011’) 20 - Cách nhau 20
99
năm
DATEDIFF ( d , '8/12/1991', ‘12/01/1992’) 447 - Cánh nhau 447 ngày
DATEDIFF ( wk , '2/13/1991', ‘3/4/2001’) 525 – Cách nhau 525 tuần
i. DATEADD: Cộng thêm giá trị cho tham số ngày tháng
Cú pháp:
DATEADD (datepart , number , date )
Trong đó:
- datepart: Theo bảng dưới đây:
datepart Viết rút gọn
year yy, yyyy
quarter qq, q
month mm, m
dayofyear dy, y
day dd, d
week wk, ww
weekday dw
hour hh
minute mi, n
second ss, s
- number: Giá trị cần cộng thêm
- date: Tham số ngày tháng cần cộng thêm giá trị
100
Ví dụ:
Ví dụ Kết quả
DATEADD ( year , 1, ‘12/31/2011’) 12/31/2012 – Cộng thêm 1 năm
DATEADD( d , -1, '8/1/1991') 07/31/1991 – Trừ đi một ngày
DATEADD ( wk , 3, '2/13/1991') 3/6/1991 – Cộng thêm 3 tuần
j. SET DATEFORMAT: Đặt thứ tự ngày tháng năm trong giá trị biến ngày tháng
Cú pháp:
SET DATEFORMAT format
- format: Định dạng ngày tháng ví dụ dmy hay mdy
Ví dụ: SET DATEFORMAT dmy
Lưu ý: Nếu không được chỉ định bằng hàm này SQL sẽ hiểu định dạng ngày tháng theo kiểu MDY.
- ISDATE: Kiểm tra một giá trị xem có phải kiểu ngày tháng hay không, kết quả trả vể True nếu đúng và False nếu sai
Cú pháp:
ISDATE ( expression )
- expression: Giá trị, biểu thức cần kiểm tra
Hàm xử lý chuỗi
a. PATINDEX: Tìm vị trí đầu tiên của một chuỗi ký tự trong chuỗi gốc
Cú pháp:
PATINDEX ('%pattern%' , expression)
- ‘pattern’: Chuỗi cần tìm vị trí được đặt trong hai dấu %
101
- expression: Chuỗi gốc chứa chuỗi ký tự cần tìm vị trí
Ví dụ Kết quả
PRINT PATINDEX (N’%Khương%’, N‘Lê Minh Khương’)
9
PRINT PATINDEX (N’%C%’, N’Toán cao cấp’) 6
b. SPACE: Trả về một chuỗi khoảng trắng tương ứng với đối số
Cú pháp:
SPACE ( integer_expression )
- integer_expression: Số ký tự trắng
Ví dụ Kết quả
PRINT N‘Lê Minh’ + SPACE(1) + N‘Khương’
Lê Minh Khương
PRINT N’Toán cao cấp:’ + SPACE(5) + ‘7’ Toán cao cấp: 7
c. CHARINDEX: Tìm vị trí đầu tiên của một chuỗi ký tự trong chuỗi gốc
Cú pháp:
CHARINDEX ( expression1 ,expression2 [ , start_location ] )
- expression1: Chuỗi cần tìm vị trí
- expression2: Chuỗi gốc chứa chuỗi ký tự cần tìm vị trí
- start_location: Vị trí bắt đầu tìm (nếu không có tham số này hàm tự hiểu tìm từ ký tự đầu tiên)
Ví dụ Kết quả
PRINT CHARINDEX(N’Khương’, N‘Lê Minh Khương’)
9
102
PRINT CHARINDEX (N’C’, N’Toán cao cấp’, 7) 10
d. STR: Chuyển kiểu số thành chuỗi
Cú pháp:
STR ( float_expression [ , length [ , decimal ] ] )
- float_expression: Biểu thức số cần chuyển thành chuỗi
- length: Độ dài của chuỗi mới
- decimal: Số ký tự trắng được đưa vào bên trái của chuỗi
Ví dụ Kết quả
PRINT STR(564.123, 5, 3) ----------
564.1
PRINT STR(564.123) --------
564
e. REPLACE: Thay thế các ký tự trong chuỗi
Cú pháp:
REPLACE(string_expression, string_pattern, string_replacement)
- string_expression: Chuỗi chứa các ký tự cần thay thế
- string_pattern: Các ký tự cần thay thế
- string_replacement: Các ký tự mới thay thế vào chuỗi
Ví dụ Kết quả
PRINT REPLACE(N‘Cty Cổ phần ABC’, N‘Cty’, N‘Công ty’)
Công ty Cổ phần ABC
PRINT REPLACE(N’ Tên: Minh – 0912 121 211’, ‘ - ’, N‘ – Điện thoại: ’
Tên: Minh – Điện thoại: 0912 121 211
103
f. LEFT: Cắt một số ký tự bên trái của chuỗi
Cú pháp:
LEFT(str, number)
- str: Chuỗi cần cắt ký tự
- number: Số ký tự cần cắt
g. REPLICATE: Lặp lại các ký tự cho trước
Cú pháp:
REPLICATE ( string_expression ,integer_expression )
- string_expression: Chuỗi cần lặp
- integer_expression: Số lần lặp các ký tự
Ví dụ Kết quả
PRINT N'Bánh: 10 ' + REPLICATE ('0', 3) + N'(đồng)'
Bánh: 10 000(đồng)
h. SUBSTRING: Cắt một phần của chuỗi
Cú pháp:
SUBSTRING(value_expressio, start_expression, length_expression)
- value_expressio: Chuỗi gốc cần cắt ký tự
- start_expression: Vị trí bắt đầu cắt
- length_expression: Số ký tự cần cắt
Ví dụ Kết quả
PRINT SUBSTRING(N’Lớp học SQL 2008’, 8, 9) SQL 2008
i. LEN: Trả về độ dài của chuỗi
104
Cú pháp:
LEN(str)
- str: Chuỗi cần kiểm tra độ dài
j. LOWER: Chuyển thành chuỗi chữ thường
Cú pháp:
LOWER(str)
- str: Chuỗi cần chuyển thành chữ thường
k. RIGHT: Cắt các ký tự bên phải của chuỗi
Cú pháp:
RIGHT(str, number)
- str: Chuỗi cần cắt ký tự
- number: Số ký tự cần cắt
l. UPPER: Chuyển thành chuỗi chữ hoa
Cú pháp:
UPPER(str)
- str: Chuỗi cần đổi thành chữ hoa
m. LTRIM: Cắt các khoảng trắng bên trái của chuỗi
Cú pháp:
LTRIM(str)
- str: Chuỗi cần cắt khoảng trắng
n. RTRIM: Cắt các khoảng trắng bên phải của chuỗi
Cú pháp:
RTRIM(str)
- str: Chuỗi cần cắt khoảng trắng
Một số hàm khác
a. CAST: Chuyển đổi dạng dữ liệu
105
Cú pháp:
CAST ( expression AS data_type)
- expression: Giá trị chuyển đổi
- data_type: Kiểu dữ liệu chuyển đổi
Ví dụ:
DECLARE @_Ngay_Sinh SMALLDATETIME
SET @_Ngay_Sinh = '3/25/1989'
PRINT N'Ban sinh năm: ' + CAST(YEAR(@_Ngay_Sinh) AS CHAR(4))
b. ISNULL: Kiểm tra giá trị NULL
Cú pháp:
ISNULL(expression, value)
- expression: Giá trị cần kiểm tra
- value: Giá trị trả về nếu giá trị kiểm tra thực sự NULL
c. ISNUMERIC: Kiểm tra dữ liệu kiểu số, nếu đúng hàm trả về giá trị 1 ngược lại trả về giá trị 0
Cú pháp:
ISNUMERIC(expression)
- expression: Đối số cần kiểm tra
d. CASE: Kiểm tra giá trị theo nhiều nhánh
Cú pháp 1:
CASE <Gia_Tri_Can_Kiem_Tra>
WHEN <Mien_Gia_Tri1> THEN <Ket_Qua1>
[WHEN <Mien_Gia_Tri2> THEN <Ket_Qua2>]
[ ...n ]
[
106
ELSE <Ket_Qua_n+1>
]
END
- Gia_Tri_Can_Kiem_Tra: Thông thường là biến cần kiểm tra giá trị
- Mien_Gia_Tri: Miền giá trị cần kiểm tra
- Ket_Qua: Giá trị trả về tương ứng với miền giá trị
Cú pháp 2:
CASE
WHEN <Bieu_Thuc_Dk1> THEN <Ket_Qua1>
[WHEN <Bieu_Thuc_Dk2> THEN <Ket_Qua2>]
[ ...n ]
[
ELSE Ket_Qua_N+1
]
END
- Bieu_Thuc_Dk: Biểu thức miền giá trị cần kiểm tra
- Ket_Qua: Kết quả trả về tương ứng với miền giá trị
Ví dụ: Lập bảng chiết khấu cho từng khách hàng theo tỉnh thành với điều kiện sau đây:
Tỉnh % Chiết khấu
Hà Nội 1
Hải Phòng 3
Hải Dương 2
Lạng Sơn 6
107
Khác 0
Cú pháp 1:
SELECT Ma_Dt, Ten_Dt, Dia_Chi,
CASE Dia_Chi
WHEN N'Hà Nội' THEN 1
WHEN N'Hải phòng' THEN 3
WHEN N'Hải dương' THEN 2
WHEN N'Lạng Sơn' THEN 6
ELSE 0 END
AS Chiet_Khau
FROM DMDT
Cú pháp 2:
SELECT Ma_Dt, Ten_Dt, Dia_Chi,
CASE
WHEN Dia_Chi LIKE N'%Hà Nội%' THEN 1
WHEN Dia_Chi LIKE N'%Hải phòng%' THEN 3
WHEN Dia_Chi LIKE N'%Hải dương%' THEN 2
WHEN Dia_Chi LIKE N'%Lạng Sơn%' THEN 6
ELSE 0 END
AS Chiet_Khau
FROM DMDT
Bằng một trong hai cách kết quả cho ra giống nhau
108
1.5. Câu lệnh có cấu trúc
Câu điều kiện IF
Cú pháp:
IF <Bieu_Thuc_Dieu_Kien>
BEGIN
<Cau_lenh_Sql>
END
[ ELSE BEGIN
<Cau_lenh_Sql>
END]
Trong đó:
- Bieu_Thuc_Dieu_Kien: Biểu thức điều kiện
- Cau_lenh_Sql: Câu lệnh SQL
Ví dụ:
DECLARE @_Ngay_Sinh SmallDatetime
SET @_Ngay_Sinh = '6/15/1988'
IF DATEDIFF(year, @_Ngay_Sinh, GETDATE()) > 16
PRINT N'Bạn đã đến tuổi vị thành niên'
ELSE
PRINT N'Bạn chưa đến tuổi vị thành niên'
109
Vòng lặp While
Cú pháp:
WHILE <Bieu_Thuc_Dieu_Kien>
BEGIN
<Cau_Lenh_Sql>
[ BREAK ]
[ CONTINUE ]
END
Trong đó:
- Bieu_Thuc_Dieu_Kien: Biểu thức điều kiện lặp
- Cau_Lenh_Sql: Câu lệnh Sql thực thi trong vòng lặp
- BREAK: Từ khóa chỉ định thoát khỏi vòng lặp dù điều kiện lặp vẫn đang thỏa mãn
- CONTINUE: Từ khóa chỉ định tiếp tục vòng lặp khi điều kiện lặp đang thỏa mãn
Ví dụ:
DECLARE @_i INT
SET @_i = 1
WHILE @_i<10
BEGIN
PRINT @_i
SET @_i = @_i + 1
END
1.6. Viết câu lệnh T-SQL trên New Query của SQL Server 2008
Lưu lại nội dụng Query
Ở phần trước chúng ta đã được trình bày về cách sử dụng công cụ New Query tuy nhiên sau khi viết các câu lệnh T-SQL chúng ta có
110
thể lưu chúng lại thành các File vật lý và sử dụng cho các lần tiếp theo, cách thực hiện như sau:
Bước 1: Mở cửa sổ New Query (Nhấp chọn biểu tượng New Query trênh thanh công cụ).
Bước 2: Soạn thảo nội dung cho Query
Bước 3: Nhấp biểu tượng Save để lưu lại Query
111
Như vậy chúng ta đã lưu lại một Query ở đường dẫn D:\ với tên là HocSql.sql
Khi muốn sử dụng lại bạn có thể thực hiện theo các bước sau đây:
Bước 1: Khởi động SQL Server 2008
Bước 2: Connect đến Server cần sử dụng
112
Bước 3: Từ menu File chọn Open/File…
Bước 4: Tìm đến đường dẫn lúc trước đã lưu File Sql
113
Chọn File nhấp Open để mở File và sử dụng lại.
Thực thi một nhóm câu lệnh trên cửa sổ New Query
Ở phần trước chúng ta sử dụng phím F5 hoặc nhấp chọn nút Execute để thực thi câu lệnh trên của sổ New Query, khi đó toàn bộ các câu lệnh được viết trong màn hình soạn thảo sẽ được thực thi, tuy nhiên bạn có thể chỉ thực hiện một nhóm các câu lệnh trong màn hình này bằng cách bôi đen nhóm câu lệnh đó rồi nhấn phím F5 hoặc nhấp nút Excute.
114
1.7. Bài tập thực hành
1. Viết Query tính lương với biến lưu các thông tin dưới đây:
+ Họ tên: Nguyễn Văn A
+ Lương cơ bản: 2.000.000
+ Ngày công thực tế: 28
+ Tạm ứng: 300.000
+ Thực lĩnh: …………………………….
- Tính thực lĩnh cho nhân viên trên theo công thức:
Thực lĩnh = (Lương cơ bản / 30 * ngày công thực tế) - Tạm ứng.
- In toàn bộ thông tin về bảng lương ra màn hình theo trình bày như trên
- Lưu Query này lại với tên là Tinh_Luong.sql tại ổ D: của máy tính.
2. Viết Query tính điểm trung bình với biến lưu các thông tin dưới đây:
+ Tên sinh viên: Nguyễn Văn A
+ Điểm môn xác xuất: 8
115
+ Đơn vị học trình môn xác xuất: 4
+ Điểm môn tiếng Anh: 6
+ Đơn vị học trình môn tiếng Anh: 3
+ Điểm môn nguyên lý kế toán: 8
+ Đơn vị học trình môn nguyên lý kế toán: 5
+ Điểm trung bình: …………………………
- Tính điểm trung bình các môn học
- In toàn bộ thông tin bảng điểm theo trình bày như trên
- Lưu lại Query với tên Tinh_Diem.sql tại ổ D: của máy tính
3. Hãy viết Query nhập vào tên và ngày tháng năm sinh của một bạn sinh viên, từ đó in ra xem bạn sinh vào ngày nào, tháng nào, năm nào và vào ngày thứ mấy trong tuần.
4. Nhập vào một ngày bất kỳ hãy tính toán và in ra ngày cuối tháng đó.
5. Nhập vào một ngày bất kỳ kiểm tra nếu ngày đó là chủ nhật thì in ra thông báo “Hôm nay là chủ nhật bạn được nghỉ” ngược lại in ra thông báo “Hôm nay vẫn là ngày làm việc”
6. Thực hiện bài toán chuẩn xâu theo một số yêu cầu sau:
- Không được có hai dấu khoảng trắng liền nhau
- Sau dấu chấm, dấu phẩy phải có dấu khoảng trắng
- Trước dấu chấm, dấu phẩy không có dấu khoảng trắng
- Sau dấu chấm phải viết hoa
- Đầu xâu, cuối xâu không được có dấu khoảng trắng
7. Nhập vào số đầu và số cuối, in ra xem có bao nhiêu số chẵn
2. Bảng
2.1. Tạo bảng
116
Ở bài trước chúng ta đã thực hành cách tạo bảng bằng công cụ trên SQL Server 2008, tuy nhiên bạn hoàn toàn có thể tạo bảng bằng câu lệnh SQL theo cú pháp dưới đây:
CREATE TABLE <Ten_Bang>
(
<Ten_Truong1> <Kieu_Du_Lieu> [NOT NULL | NULL]
[DEFAULT (<Gia_Tri_Mac_Dinh>)],
<Ten_Truong2> <Kieu_Du_Lieu> [NOT NULL | NULL]
[DEFAULT (<Gia_Tri_Mac_Dinh>)],
...
<Ten_Truong_n> <Kieu_Du_Lieu> [NOT NULL | NULL]
[DEFAULT (<Gia_Tri_Mac_Dinh>)],
[CONSTRAINT <Ten_Khoa> PRIMARY KEY CLUSTERED
(
<Truong_Khoa> [ASC | DESC]
)]
)
Giải thích:
- Ten_Bang: Tên bảng cần tạo
- Ten_Truong: Tên trường cần tạo cho bảng
- Kieu_Du_Lieu: Kiểu dữ liệu của trường
- Gia_Tri_Mac_Dinh: Gán giá trị ngầm định cho trường nếu có
- Ten_Khoa: Tên khóa chính của bảng thông thường đặt là PK_<Ten_Bang>, ví dụ PK_DMDT
117
- Truong_Khoa: Tên trường khóa chính của bảng
Ví dụ: Tạo bảng danh mục đối tượng với các thông tin như sau:
Tên bảng: DMDT
Khóa chính: Ma_Dt
Stt Trường Kiểu & độ rộng
Diễn giải
1 Id Int Trường tăng tự động, xác định bản ghi duy nhất
2 Ma_Dt Nchar(16) Trường khóa, lưu mã đối tượng
3 Ten_Dt Nvarchar(96) Tên đối tượng
4 Dia_Chi Nvarchar(64) Địa chỉ
5 So_Dt char(20) Số điện thoại
6 Fax char(20) Số Fax
7 Email Nvarchar(64) Thư điện tử
8 Ghi_Chu Ntext Thông tin ghi chú
Chúng ta sẽ thực hiện tạo bảng bằng hai cách:
Cách 1: Sử dụng công cụ trên giao diện SQL Server 2008, các bước thực hiện như sau:
Bước 1: Khởi động SQL Sever 2008
Bước 2: Connect tới Server chứa DataBase
Bước 3: Chọn DataBase cần tạo bảng trong cửa sổ Object Explorer.
118
Tìm tới mục Tables nhấp phải chuột chọn New Table…
Bước 4: Trong cửa sổ New Table nhập vào danh sách trường và các thiết lập như đầu bài
119
Bước 5: Tiếp theo nhấp phải chuột chọn vào cột đánh dấu tương ứng với dòng Ma_Dt chọn Set Primary Key để thiết lập trường khóa.
Sau khi thiết lập xong trường khóa chính sẽ có biểu tượng như hình dưới dưới đây:
120
Bước 6: Cuối cùng nhấp nút Save trên thanh công cụ để lưu lại bảng với tên là DMDT.
Như vậy khi chúng ta trở lại mục Tables trong Database hiện thời sẽ thấy xuất hiện bảng mới vừa thêm.
- Để chỉnh sửa lại bảng nhấp phải chuột chọn Design
121
- Để mở dữ liệu trong bảng nhấp phải chuột chọn Select Top 1000 Rows
Cách 2: Sử dụng câu lệnh T-SQL, các bước thực hiện như sau:
Bước 1: Khởi động Sql Server 2008
Bước 2: Chọn tới Database cần tạo bảng sau đó nhấp chuột vào biểu tượng New Query trên thanh công cụ.
122
Bước 3: Cửa sổ New Query xuất hiện hãy nhập vào nội dung câu lệnh tạo bảng dưới đây:
USE [QLHTK]
CREATE TABLE [dbo].[DMDT](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Ma_Dt] [nchar](16) NOT NULL,
[Ten_Dt] [nvarchar](64) NOT NULL,
[Dia_Chi] [nvarchar](50) NOT NULL,
[Ghi_Chu] [text] NOT NULL,
CONSTRAINT [PK_DMDT] PRIMARY KEY CLUSTERED
(
[Ma_Dt] ASC
)
)
Sau khi nhập xong nhấn phím F5 hoặc nhấn nút Execute trên thanh công cụ để thực thi câu lệnh.
123
Bước 4: Bây giờ hãy vào mục Tables của Database nhấp phải chuột chọn Refresh, một bảng mới sẽ xuất hiện với tên là DMDT.
2.2. Cập nhật dữ liệu vào bảng
Việc cập nhật dữ liệu vào bảng là một công việc thường xuyên và vô cùng quan trọng vì một bảng chỉ có ý nghĩa quản lý khi nó chứa dữ liệu. Công việc cập nhật bao gồm thêm, sửa, xóa dữ liệu, tương tự như tạo bảng khi cập nhật dữ liệu vào bảng trong SQL Server 2008 chúng ta cũng có thể sử dụng 2 cách một là thông qua các công cụ trên giao diện, hai là sử các câu lệnh T-SQL.
Thêm mới một dòng dữ liệu
Để thêm dữ liệu vào bảng chúng ta có hai cách sau đây:
Cách 1: Sử dụng công cụ giao diện SQL Server 2008, với bảng DMDT vừa tạo ở phần trên chúng ta thực hiện thêm dữ liệu theo các bước sau đây:
Bước 1: Khởi động SQL Server 2008
Bước 2: Chọn tới Database QLHTK, trong phần Tables nhấp phải chuột vào bảng DMDT chọn Edit Top 200 Rows.
124
Bước 3: Cửa sổ danh sách dữ liệu xuất hiện
Hãy nhập dữ liệu vào dòng cuối cùng, sau khi đã điền dữ liệu đầy đủ cho các trường hãy nhấp chuột xuống dòng dưới để xác nhận.
125
Bước 4: Như vậy chúng ta đã nhập dữ liệu cho dòng đầu tiên của bảng vừa tạo, hãy thực hiện tương tự với các dòng (bản ghi) tiếp theo
Cách 2: Sử dụng câu lệnh T-SQL, các bước thực hiện như sau:
Bước 1: Khởi động SQL Server 2008
Bước 2: Chọn tới Database chứa bảng cần thêm dữ liệu
Bước 3: Mở cửa sổ New Query và nhập vào nội dung sau:
INSERT INTO [DMDT]
([Ma_Dt]
,[Ten_Dt]
,[Dia_Chi]
,[Ghi_Chu])
VALUES
(N'DT002'
,N'Công ty Cổ phần ANJ'
,N'Hải phòng'
,N'')
Nhấn F5 hoặc nhấp chuột nút Execute trên thanh công cụ để thực hiện câu lệnh
126
Bước 4: Hãy mở bảng DMDT chúng ta sẽ thấy một bản ghi mới được thêm với nội dụng như câu lệnh vừa thực hiện.
Sửa dữ liệu
Cũng với bảng dữ liệu trên chúng ta tiến hành sửa đổi địa chỉ của “công ty Cổ phần ANJ“ từ “Hải phòng’ thành “Hải Dương”. Bạn có thể thực hiện theo một trong hai cách sau đây:
Cách 1: Sử dụng công cụ giao diện SQL Server 2008, các bước thực hiện như sau:
Bước 1: Khởi động SQL Server 2008
Bước 2: Mở bảng ở dạng chỉnh sửa bản ghi bằng cách chọn tới Database QLHTK, trong phần Tables nhấp phải chuột vào bảng DMDT chọn Edit Top 200 Rows.
127
Bước 3: Bạn nhấp chuột vào cột địa chỉ của dòng tương ứng với “công ty cổ phần ANJ”
Bước 4: Bây giờ hãy sửa giá trị này thành “Hải dương” sau đó nhấp chuột sang dòng khác để xác nhận sửa đổi, kết quả sẽ được như hình dưới đây.
128
Cách 2: Sử dụng câu lệnh T-SQL, các bước thực hiện như sau:
Bước 1: Khởi động SQL Server 2008
Bước 2: Chọn tới Database chứa bảng cần sửa dữ liệu
Bước 3: Mở cửa sổ New Query và nhập vào nội dung sau:
UPDATE [DMDT]
SET [Dia_Chi] = N'Hải dương'
WHERE Ma_Dt = 'DT002'
Nhấn F5 hoặc nhấp chuột nút Execute trên thanh công cụ để thực hiện câu lệnh
Bước 4: Hãy mở bảng DMDT chúng ta sẽ thấy kết quả được thực hiện tương tự như cách 1
Lưu ý:
- Trong trường hợp này “Công ty Cổ phần ANJ” có mã là DT002 và đây là trường khóa xác định bản ghi duy nhất vì vậy chúng ta sử dụng làm điều kiện sửa đổi bản ghi.
- Bạn cũng có thể áp dụng sửa đổi cho nhiều trường cùng một lúc bằng câu lệnh T-SQL
Xóa dữ liệu
Giả sử chúng ta cần xóa “Công ty Cổ phần ANJ” trong bảng DMDT, bạn có thể thực hiện theo một trong hai cách sau đây:
129
Cách 1: Sử dụng công cụ giao diện SQL Server 2008, các bước thực hiện như sau:
Bước 1: Khởi động SQL Server 2008
Bước 2: Mở bảng cần xóa dữ liệu
Bước 3: Nhấp phải chuột vào cột đánh dấu của bản ghi cần xóa chọn Delete.
Hộp thoại xác nhận xuất hiện chọn Yes để thực hiện xóa
Cách 2: Sử dụng câu lệnh T-SQL, các bước thực hiện như sau:
Bước 1: Khởi động SQL Server 2008
Bước 2: Chọn tới Database cần thao tác, sau đó mở cửa sổ New Query và nhập vào nội dung sau:
DELETE [DMDT] WHERE Ma_Dt = 'DT002'
130
Bước 3: Nhấn F5 hoặc nhấp chuột chọn nút Excute trên thanh công cụ để thực hiện xóa dữ liệu
2.3. Bài tập thực hành
1. Tạo các bảng dưới đây bằng công cụ trên giao diện hoặc bằng câu lệnh SQL
Bảng danh mục đối tượng (Lưu khách hàng hoặc nhà cung cấp)
Tên bảng: DMDT
Khóa chính: Ma_Dt
Stt Trường Kiểu & độ rộng
Diễn giải
1 Id Int Trường tăng tự động, xác định bản ghi duy nhất
2 Ma_Dt Nchar(16) Trường khóa, lưu mã đối tượng
3 Ten_Dt Nvarchar(96) Tên đối tượng
4 Dia_Chi Nvarchar(64) Địa chỉ
5 So_Dt char(20) Số điện thoại
6 Fax char(20) Số Fax
7 Email Nvarchar(64) Thư điện tử
8 Ghi_Chu Ntext Thông tin ghi chú
Bảng danh mục vật tư
Tên bảng: DMVT
Khóa chính: Ma_Vt
Stt Trường Kiểu & độ
rộng Diễn giải
1 Id Int Trường tăng tự động, xác định bản ghi duy nhất
2 Ma_Vt Nchar(16) Trường khóa, lưu mã vật tư, hàng hóa
3 Ten_Vt Nvarchar(96) Tên vật tư hàng hóa
131
4 Dvt Nvarchar(10) Đơn vị tính
5 Quy_Cach Nvarchar(96) Quy cách sản phẩm
6 Ghi_Chu Ntext Thông tin ghi chú
Bảng danh mục kho
Tên bảng: DMKHO
Khóa chính: Ma_Kho
Stt Trường Kiểu & độ
rộng Diễn giải
1 Id Int Trường tăng tự động, xác định bản ghi duy nhất
2 Ma_Kho Nchar(16) Trường khóa, lưu mã kho
3 Ten_Kho Nvarchar(96) Tên kho hàng
4 Ghi_Chu Ntext Thông tin ghi chú
Bảng tồn kho đầu kỳ
Tên bảng: TONDK
Khóa chính: Id
Stt Trường Kiểu & độ
rộng Diễn giải
1 Id Int Trường tăng tự động, xác định bản ghi duy nhất
2 Ma_Kho Nchar(16) Mã kho tồn
3 Ma_Vt Nchar(16) Mã vật tư hàng hóa tồn kho
4 So_Luong Numeric(15, 3)
Số lượng tồn
5 Don_Gia Numeric(18, 0)
Giá tồn kho
6 Ghi_Chu Ntext Thông tin ghi chú
Bảng chứng từ
132
Tên bảng: CT
Khóa chính: Stt_Ct
Stt Trường Kiểu & độ
rộng Diễn giải
1 Stt_Ct Char(10) Là trường khóa chính lưu số thứ tự chứng từ
2 Ma_Ct Char(3) Mã chứng từ (PX, PN)
3 Nhom_Ct Tinyint Nhóm chứng từ (1: Nhập, 2: Xuất)
4 So_Ct Char(10) Số chứng từ
5 Ngay_Ct DateTime Ngày chứng từ
6 Ma_Dt Char(16) Mã khách hàng hoặc nhà cung cấp
7 Ong_Ba Nvarchar(32) Người thực hiện chứng từ
8 Dia_Chi Nvarchar(96) Địa chỉ
9 Dien_Giai Nvarchar(128) Diễn giải chứng từ
10 Dia_Diem Nvarchar(96) Địa điểm nhập, xuất hàng
Bảng chứng từ chi tiết
Tên bảng: CTCT
Khóa chính: Stt_Ct, Stt_Dong
Stt Trường Kiểu & độ
rộng Diễn giải
1 Stt_Ct Char(10) Là trường khóa chính lưu số thứ tự chứng từ
2 Stt_Dong Char(3) Số thứ tự từng dòng chi tiết chứng từ
3 Ma_Vt Nchar(16) Mã vật tư hàng hóa
4 So_Luong Numeric(15, 3)
Số lượng vật tư hàng hóa nhập, xuất
5 Don_Gia Numeric(18, Đơn giá
133
0)
6 Ma_Kho Numeric(18, 0)
Mã kho nhập, xuất vật tư hàng hóa
2. Thêm các dữ liệu mẫu dưới đây vào bảng tương ứng
Bảng tồn kho đầu kỳ (TONDK)
Id Ma_Vt Ma_Kho So_Luong Don_Gia Ghi_Chu
1 TP001 KTP 10 125.000
2 VT004 KVT 20 75.000
3 VT003 KVT 4 110.000
Bảng danh mục đối tượng (DMDT)
Id Ma_Dt Ten_Dt Dia_Chi So_Dt Fax Email
1 N001 Cty TNHH ABC
Hà Nội 04 3640 0119
3 N002 Cty Cổ phần CB thực phẩm miền bắc
Hà Nội 046 3423 3438
4 N003 Cty liên doanh Việt Pháp
Hải Phòng
033 6534 391
5 N004
Cty TNHH một thành viên cấp nước Yên Bái
Yên Bái 02183 543 443
6 N005 Cty Cổ phần Lạc Hồng
Bắc Ninh
0240 362 552
7 N006 Cty XNK Á Châu
Hải Dương
0320 3111 411
Bảng danh mục vật tư, hàng hóa (DMVT)
Id Ma_Vt Ten_Vt Dvt Quy_Cach
1 TP001 Bánh trứng Custas Hộp Hộp 20 cái
2 TP002 Bánh kem xốp Gói Gói 200
134
gram
3 VT001 Bột mì loại 1 Kg
4 VT002 Hương liệu Kg
5 VT003 Bột nở Kg
6 TP003 Bánh kem bơ Gói Gói 150 gram
7 TP004 Bánh Socola Vinasun Hộp Hộp 6 cái
8 VT004 Socola nguyên liệu Kg
9 VT005 Sửa ông thọ Thùng
Bảng chứng từ (CT)
SttCt
Ma_Ct
Nhom_Ct
So_Ct Ngay_C
t Ma_D
t Ong_Ba
Dia_Ch
1 PX 1 PX001 31/05/11 N001 Lê Văn Khương
Hà N
2 PX 1 PX002 01/06/11 N001 Đào Thị Hạnh Hà N
3 PN 2 PN001 01/06/11 N002 Tạ Thu Loan Công ty
4 PX 1 PX003 01/06/11 N004 Phan Thế Anh Hà N
5 PN 2 PN002 02/06/11 N005 Tạ Thị Minh Hà Tây
6 PX 1 PX004 05/06/11 N004 Phan Thế Anh Hà N
Bảng chi tiết chứng từ (CTCT)
Stt_Dong Stt_Ct Ma_Vt Ma_Kho So_Luong Don_Gia
1 1 TP001 KTP 120.000 120,00
2 1 TP002 KTP 23.500 45,00
1 2 TP001 KTP 11.500 35,00
1 3 VT001 KVT 30.000 120,00
2 3 VT002 KVT 120.000 15,00
1 4 TP001 KTP 110.000 75,00
135
2 4 TP004 KTP 34.000 44,00
1 5 VT004 KVT 75.000 30,00
2 5 VT001 KVT 31.000 32,00
3 5 VT003 KVT 120.000 56,00
1 6 TP001 KVT 13.000 78,00
3. View
3.1. Định nghĩa
Ðịnh nghĩa một cách đơn giản thì view trong SQL Server tương tự như Query trong Access database. View có thể được xem như một table ảo mà dữ liệu của nó được chọn từ một query. Trong quá trình sử dụng view không khác so với table và có thể đặt ở vị trí của table trong các câu lệnh SQL. Ðặc điểm của View là ta có thể liên kết dữ liệu từ nhiều table và trả về một tập hợp bản ghi đơn. Ngoài ra ta có thể "xào nấu" dữ liệu trước khi trả về cho người dùng bằng cách dùng một số logic checking như (if, case...).
Ví dụ:
CREATE VIEW [dbo].[TonDkView]
AS
SELECT TonDk.Id,
TonDk.Ma_Kho,
TonDk.So_Luong,
TonDk.Ma_Vt,
TonDk.Don_Gia,
TonDk.Ghi_Chu,
DMVT.Ten_Vt,
DMKHO.Ten_Kho
FROM DMKHO INNER JOIN
136
TonDk ON DMKHO.Ma_Kho = TonDk.Ma_Kho INNER JOIN
DMVT ON TonDk.Ma_Vt = DMVT.Ma_Vt
Nói chung câu lệnh SQL trong View có thể từ rất đơn giản như select toàn bộ data từ một table cho đến rất phức tạp với nhiều tính năng của T-SQL.
View thường được sử dùng vào một số công việc sau:
- Tập trung vào một số data nhất định: ta thường dùng view để select một số dữ liệu mà người dùng quan tâm hay chịu trách nhiệm và loại bỏ những dữ liệu không cần thiết.
- Ðơn giản hóa việc xử lý dữ liệu: Ðôi khi ta có những query rất phức tạp và sử dụng thường xuyên ta có thể chuyển nó thành View và đối xử nó như một table, như vậy sẽ làm cho việc xử lý dữ liệu dễ dàng hơn.
- Customize data: Ta có thể dùng view để làm cho người dùng thấy dữ liệu từ những góc độ khác nhau mặc dù họ đang dùng một nguồn dữ liệu giống nhau.
- Export và Import data: Ðôi khi ta muốn export data từ SQL Server sang các ứng dụng khác như Excel chẳng hạn ta có thể dùng view để join nhiều bảng sau đó export dữ liệu từ View.
Khi sử dụng view ta có thể select,insert, update, delete data bình thường như với một table.
3.2. Thêm và chỉnh sửa View
Giả sử chúng ta cần tạo View tồn kho đầu kỳ (TonDkView) bao gồm các thông tin Ma_Vt, Ten_Vt, Ma_Kho, Ten_Kho, So_Luong, Don_Gia, Thanh_Tien, Ghi_Chu.
Sử dụng công cụ trên giao diện SQL Server 2008
Bước 1: Khởi động SQL Server 2008
Bước 2: Chọn tới Database cần tạo View trong cửa sổ Object Explorer
Bước 3: Nhấp phải chuột vào mục View chọn New View…
137
Bước 4: Hộp thoại Add Table xuất hiện, chọn những bảng cấu thành nên View, trong trường hợp này chúng ta sử dụng 3 bảng là DMVT, DMKHO và TONDK, sau khi chọn xong các bạn nhấp nút Add để lần lượt thêm các bảng này vào View.
138
Kết quả:
Bước 5: Chọn các trường cần lấy vào View từ các bảng, đầu tiên hãy tích chọn các trường Id,, Ma_Kho, Ma_Vt, So_Luong, Don_Gia, Ghi_Chu trong bảng TonDk.
139
Tạo liên kết cho bảng TonDk với hai bảng còn lại bằng cách lần lượt kéo thả trường Ma_Vt trong bảng DmVt vào trường Ma_Vt trong bảng TonDk và trường Ma_Kho từ bảng DmKho vào trường Ma_Kho trong bảng TonDk. Kết quả sẽ được như hình dưới đây:
Tiếp tục tích chọn trường Ten_Kho trong DmKho và trường Ten_Vt trong DmVt để lấy vào View.
140
Chúng ta vẫn còn thiếu trường Thanh_Tien được tính toán từ trường Don_Gia và So_Luong trong bản TonDk. Hãy di chuyển xuống dòng cuối cùng của danh sách phía dưới và thêm một dòng mới với nội dung như sau: ở cột “Column” nhập vào nội dung “dbo.TonDk.So_Luong * dbo.TonDk.Don_Gia”, ở cột Alias nhập vào nội dung “Thanh_Tien”.
Như vậy là chúng ta đã vừa thêm một trường tính toán với tên bí danh là Thanh_Tien vào View, công việc dường như đã kết thúc hãy rảo qua câu lệnh SQL ở phía dưới:
Chúng ta sẽ thấy bản chất của View chính là một câu lệnh SELECT được kết nối từ 3 bảng bằng INNER JOIN.
141
Bước 6: Như vậy là đã hoàn tất bạn nhấp tổ hợp phím Ctrl + S để lưu lại View với tên là TonDkView.
Bây giờ trong mục Views tại cửa sổ Object Explorer bạn sẽ thấy có một View mới mà chúng ta vừa thêm
Bạn có thể sử dụng nó như một bảng dữ liệu thông thường
142
Trong trường hợp cần chỉnh sửa bạn hãy nhấp phải chuột vào View cần sửa trong cửa sổ Object Explorer chọn Design.
Nếu muốn xóa View bạn nhấp phải chuột vào View cần xóa trong cửa sổ Object Explorer chọn Delete.
Sử dụng câu lệnh T-SQL và thực thi trên New Query
Ngoài cách sử dụng công cụ trên SQL Server 2008 bạn cũng có thể tạo View bằng cửa sổ New Query với câu lệnh T-SQL, cũng với ví dụ trên chúng ta sẽ thực hiện lại theo cách này nhé.
Bước 1: Khởi động SQL Server 2008
Bước 2: Chọn tới Database cần thêm View
Bước 3: Nhấp chọn biểu tượng New Query trên thanh công cụ
143
Bước 4: Trong màn hình soạn thảo câu lệnh T-SQL xuất hiện hãy nhập vào nội dung sau đây:
(Thực chất nội dụng Query này là đáp án cho câu hỏi “Hãy lấy ra toàn bộ danh sách vật tư tồn đầu kỳ với các thông tin lần lượt là Id, Ma_Vt, Ten_Vt, Ma_Kho, Ten_Kho, So_Luong, Don_Gia, Thanh_Tien”)
CREATE VIEW [dbo].[TonDkView]
AS
SELECT TonDk.Id,
TonDk.Ma_Kho,
TonDk.So_Luong,
TonDk.Ma_Vt,
TonDk.Don_Gia,
TonDk.Ghi_Chu,
DMVT.Ten_Vt,
DMKHO.Ten_Kho
FROM DMKHO INNER JOIN
TonDk ON DMKHO.Ma_Kho = TonDk.Ma_Kho INNER JOIN
DMVT ON TonDk.Ma_Vt = DMVT.Ma_Vt
Trong nội dung trên chúng ta thấy từ khoá CREATE VIEW dùng để tạo một VIEW mới, [dbo].[TonDkView] là tên của View, phần nội dung sau từ khóa AS là câu lệnh T-SQL để trả lời cho câu hỏi như đã trình bày ở trên.
Bước 5: Nhấp chuột chọn nút Execute trên thanh công cụ hoặc nhấn phím F5 để thực thi câu lệnh
Kết quả cuối cùng cho tương tự như cách thứ nhất, trong trường hợp muốn chỉnh sửa View bằng câu lệnh T-SQL bạn chỉ cần nhấp phải
144
chuột vào View cần chỉnh sửa chọn Script View as/ALTER To/New Query Editor Window.
Một cửa sổ Query xuất hiện như hình dưới đây:
Như quan sát chúng ta thấy nội dung Query chỉ thay đổi ở từ khóa CREATE VIEW nay đổi thành ALTER VIEW, bạn có thể tiến hành sửa đổi nội dung cho View sau đó nhấn phím F5 để thực thi câu lệnh đã thay đổi.
145
3.3. Bài tập thực hành
- Tạo View thẻ kho (TheKhoView) với các thông tin sau đây: Ma_Ct, Nh_Ct, So_Ct, Ngay_Ct, Ma_Vt, Ten_Vt, Ma_Kho, Ten_Kho, So_Luong, Don_Gia, Thanh_Tien lấy dữ liệu từ bảng CT, CTCT và các bảng danh mục liên quan.
- Tạo View nhật ký chung (NhatKyChungView) với các thông tin sau đây: Ma_Ct, Nh_Ct, So_Ct, Ngay_Ct, Ong_Ba, Dia_Chi, Dien_Giai, Ma_Dt, Ten_Dt, Ma_Vt, Ten_Ct, So_Luong, Don_Gia, Thanh_Tien, Ma_Kho, Ten_Kho. Dữ liệu lấy từ bảng CT, CTCT và các bảng danh mục liên quan.
4. Stored Procedures (Thủ tục lưu)
4.1. Khái niệm
Trong những bài học trước đây khi dùng New Query chúng ta có thể đặt tên và save các nhóm câu lệnh SQL vào một file dưới dạng script để có thể sử dụng trở lại sau này. Tuy nhiên thay vì save vào text file ta có thể save vào trong SQL Server dưới dạng Stored Procedure. Stored Procedure là một nhóm câu lệnh Transact-SQL đã được compiled (biên dịch) và chứa trong SQL Server dưới một tên nào đó và được xử lý như một đơn vị (chứ không phải nhiều câu SQL riêng lẻ).
Ưu Ðiểm Của Stored Procedure
- Performance : Khi thực thi một câu lệnh SQL thì SQL Server phải kiểm tra permission xem user gởi câu lệnh đó có được phép thực hiện câu lệnh hay không đồng thời kiểm tra cú pháp rồi mới tạo ra một execute plan và thực thi. Nếu có nhiều câu lệnh như vậy gởi qua network có thể làm giảm đi tốc độ làm việc của server. SQL Server sẽ làm việc hiệu quả hơn nếu dùng Stored procedure vì người gởi chỉ gởi một câu lệnh đơn và SQL Server chỉ kiểm tra một lần sau đó tạo ra một execute plan và thực thi. Nếu Stored procedure được gọi nhiều lần thì execute plan có thể được sử dụng lại nên sẽ làm việc nhanh hơn. Ngoài ra cú pháp của các câu lệnh SQL đã được SQL Sever kiểm tra trước khi save nên nó không cần kiểm lại khi thực thi.
146
- Programming Framework: Một khi stored procedure được tạo ra nó có thể được sử dụng lại. Ðiều này sẽ làm cho việc bảo trì (maintainability) dễ dàng hơn. Ví dụ nếu có một sự thay đổi nào đó về mặt logic thì ta chỉ việc thay đổi code bên trong Stored procedure mà thôi. Những ứng dụng dùng Stored procedure này có thể sẽ không cần phải thay đổi mà vẫn tương thích với quy tắc, ràng buộc mới. Cũng giống như các ngôn ngữ lập trình khác stored procedure cho phép ta đưa vào các tham số và trả về các tham số đầu ra đồng thời nó cũng có khả năng gọi các Stored procedure khác.
- Security: Giả sử chúng ta muốn giới hạn việc truy xuất dữ liệu trực tiếp của một user nào đó vào một số tables, ta có thể viết một stored procedure để truy xuất dữ liệu và chỉ cho phép user đó được sử dụng stored procedure đã viết sẵn mà thôi chứ không thể "đụng" đến các bảng đó một cách trực tiếp. Ngoài ra stored procedure có thể được mã hóa để tăng cường tính bảo mật.
Các Loại Stored Procedure
Stored procedure có thể được chia thành 5 nhóm như sau:
- System Stored Prcedure: Là những stored procedure chứa trong Master database và thường bắt đầu bằng tiếp đầu ngữ sp_ . Các stored procedure này thuộc loại built-in và chủ yếu dùng trong việc quản lý database (administration) và security. Ví dụ bạn có thể kiểm tra tất cả các processes đang được sử dụng bởi user DomainName\Administrators bạn có thể dùng sp_who @loginame='DomainName\Administrators' . Có hàng trăm system stored procedure trong SQL Server.
- Local Stored Procedure: Ðây là loại thường dùng nhất. Chúng được chứa trong user database và thường được viết để thực hiện một công việc nào đó. Thông thường người ta nói đến stored procedure là nói đến loại này. Chúng ta sẽ bàn về cách tạo stored prcedure loại này trong phần kế tiếp.
- Temporary Stored Procedure: Là những stored procedure tương tự như local stored procedure nhưng chỉ tồn tại cho đến khi connection đã tạo ra chúng bị đóng lại hoặc SQL Server shutdown. Các stored procedure này được tạo ra trên TempDB của SQL Server
147
nên chúng sẽ bị delete khi connection tạo ra chúng bị cắt đứt hay khi SQL Server down. Temporary stored procedure được chia làm 3 loại : local (bắt đầu bằng #), global (bắt đầu bằng ##) và stored procedure được tạo ra trực tiếp trên TempDB. Loại local chỉ được sử dụng bởi connection đã tạo ra chúng và bị xóa khi disconnect, còn loại global có thể được sử dụng bởi bất kỳ connection nào. Permission cho loại global là dành cho mọi người (public) và không thể thay đổi. Loại stored procedure được tạo trực tiếp trên TempDB khác với 2 loại trên ở chỗ ta có thể set permission, chúng tồn tại kể cả sau khi connection tạo ra chúng bị cắt đứt và chỉ biến mất khi SQL Server shut down.
- Extended Stored Procedure: Ðây là một loại stored procedure sử dụng một chương trình ngoại vi (external program) vốn được compiled thành một DLL để mở rộng chức năng hoạt động của SQL Server. Loại này thường bắt đầu bằng tiếp đầu ngữ xp_ .Ví dụ, xp_sendmail dùng đề gởi mail cho một người nào đó hay xp_cmdshelldùng để chạy một DOS command... Ví dụ xp_cmdshell 'dir c:\' . Nhiều loại extend stored procedure được xem như system stored procedure và ngược lại.
- Remote Stored Procedure: Những stored procedure gọi stored procedure ở server khác.
4.2. Viết Stored Procedure
Tên và những thông tin về Stored Procedure khi được tạo ra sẽ chứa trong SysObjects table còn phần text của nó chứa trong SysComments table. Vì Stored Procedure cũng được xem như một object nên ta cũng có thể dùng các lệnh như CREATE, ALTER, DROP để tạo mới, thay đổi hay xóa bỏ một stored procedure.
Cú pháp:
CREATE PROCEDURE <Ten_Thu_Tuc>
<Danh_Sach_Tham_So>
AS
BEGIN
148
<Noi_Dung_Thu_Tuc>
END
Trong đó:
- <Ten_Thu_Tuc>: Tên thủ tục lưu thông thường bắt đầu bằng tiếp đầu ngữ usp_
- <Danh_Sach_Tham_So>: Danh sách các tham số truyền vào thủ tục lưu
- <Noi_Dung_Thu_Tuc>: Là tập hợp các câu lệnh T-SQL cần thực hiện trong thủ tục
Ví dụ: Viết thủ tục lưu có tên DmDtGetData, với tham số truyền vào là ID, trong trường hợp ID bằng NULL lấy toàn bộ danh sách đối tượng, ngược lại nếu ID có truyền vào giá trị thì lấy ra đối tượng có ID tương ứng. Các bước thực hiện như sau:
Bước 1: Khởi động SQL Server 2008
Bước 2: Chọn tới Database cần thêm thủ tục lưu
Bước 3: Mở một cửa sổ New Query mới, sau đó nhập vào nội dung sau đây:
CREATE PROCEDURE [dbo].[DmDtGetData]
@_Id INT = NULL
AS
BEGIN
SET NOCOUNT ON;
IF @_Id IS NULL
SELECT * FROM DmDt
ELSE
SELECT * FROM DmDt
WHERE Id = @_Id
END
149
Trong nội dung trên chúng ta thấy:
- Sau từ khóa CREATE PROCEDURE là tên thủ tục DmDtGetData
- Tiếp theo @_Id là tham số truyền vào có kiểu là INT và giá trị ngầm định là NULL
- Trong phần BEGIN… END là nội dung thủ tục, câu lệnh SET NOCOUNT ON được sử dụng khi không muốn đếm các kết quả mà câu lệnh T-SQL thực thi.
Bước 4: Nhấn phím F5 hoặc nhấp chọn nút Execute để tạo thủ tục. Sau bước này một thủ tục lưu mới sẽ được tạo chúng ta có thể tìm thấy trong cửa sổ Object Explorer như hình dưới đây:
150
Chỉnh sửa một thủ tục đã tồn tại
Để thực hiện hãy tìm tới thủ tục cần sửa trong cửa sổ Objects Explorer nhấp phải chuột và chọn Modify.
Một cửa sổ Query xuất hiện, chúng ta sẽ thấy phía trước tên thủ tục lưu từ khóa CREATE PROCEDURE được đổi thành ALTRE PROCEDURE. Như vậy bạn có thể thực hiện sửa đổi nội dung sau hoàn tất nhấn phím F5 để Execute lại nội dung đã thay đổi cho thủ tục.
Gọi (thực thi) một thủ tục lưu
151
Việc quan trọng nhất của quá trình tìm hiểu thủ tục lưu là chúng ta phải biết cách sử dụng chúng, bạn có thể gọi một thủ tục lưu và xem kết quả bằng một trong hai cách sau đây:
Cách 1: Sử dụng công cụ trên SQL Server 2008, đầu tiên bạn hãy tìm tới thủ tục lưu cần gọi trong cửa sổ Object Explorer, nhấp phải chuột và chọn Execute Stored Procedure…
Hộp thoại Execute Procedure xuất hiện như hình dưới đây:
152
Hãy nhập vào giá trị cho các tham số ở cột Value (nếu để trắng chương trình sẽ lấy theo giá trị mặc định) sau đó nhấp nút OK. Chúng ta sẽ thấy kết quả trả về như hình dưới đây:
153
Trong trường hợp này chúng ta không điền giá trị cho tham số @_Id vì vậy kết quả sẽ lấy toàn bộ danh sách trong danh mục đối tượng.
Cách 2: Thực thi thủ tục bằng cầu lệnh T-SQL, bạn mở một cửa sổ Query mới và nhập vào đó nội dung sau:
USE [QLHTK]
EXECUTE [dbo].[DmDtGetData] @_Id = 1
Trong nội dung trên câu lệnh USE [QLHTK] sử dụng để chọn tới Database QLHTK, sau từ khóa EXECUTE là tên thủ tục cần thực hiện, tiếp đến là gán giá trị cho tham số, cụ thể chúng ta gán cho tham số @_ID giá trị là 1. Kết quả sẽ cho như hình dưới đây:
Xóa thủ tục lưu
154
Để xóa thủ tục lưu chúng ta có thể sử dụng một trong hai cách sau đây:
Cách 1: Nhấp phải chuột vào thủ tục lưu cần xóa chọn Delete.
Hộp thoại Delete Objects xuất hiện nhấp Ok để thực hiện xóa thủ tục lưu
155
Cách 2: Mở cửa sổ New Query mới, nhập vào đó nội dung sau:
DROP PROCEDURE [dbo].[DmDtGetData]
Nhấn F5 để thực hiện xóa thủ tục lưu
4.3. Sử dụng bảng tạm
Đối với một thủ tục lưu phức tạp, kết quả cuối cùng chỉ có thể có được qua nhiều bước tính toán thì việc sử dụng một câu lệnh T-SQL cho tất cả các công việc đó là vô cùng phức tạp. Tuy nhiên nếu chúng ta sử dụng các bảng chung gian (bảng tạm) để lưu kết quả của từng bước tính toán sau đó kết hợp chúng lại với nhau thì mọi chuyện sẽ trở nên hết sức dễ dàng. Ví dụ chúng ta cần viết báo cáo nhập xuất tồn vật tư, với những gì đã học còn hạn chế ở các phần trước chúng ta sẽ nghĩ ngay đến việc sử dụng UNION để kết hợp nhiều câu lệnh SELECT, đầu tiên là tồn đầu, tiếp theo là nhập, xuất, rồi tính toán ra lượng tồn kho. Tuy nhiên với cách này số liệu về
156
một vật tư sẽ nằm ít nhất ở 4 dòng khác nhau và như vậy tất nhiên không phải là đáp án của đầu bài. Bây giờ hãy cùng suy nghĩa theo một hướng khác giả sử chúng ta tạo ra một bảng tạm có đầy đủ các cột mã, tên vật tư, tồn đầu, xuất, nhập và tồn cuối. Bước thứ nhất chúng ta INSERT vào danh sách vật tư, tiếp theo là số dư đầu tương ứng với từng vật tư trong bảng tạm vừa tạo. Làm tương tự với các giá trị nhập – xuất và tồn chúng ta sẽ có được kết quả như yêu cầu của đầu bài đưa ra. Sau đây là một ví dụ về cách sử dụng bảng tạm:
Viết báo cáo tổng hợp nhập kho bao gồm các thông tin sau: Ma_Vt, Ten_Vt, Dvt, So_Luong, Don_Gia, Thanh_Tien (Đặt tên cho thủ tục lưu là usp_Tong_Hop_Nhap_Kho)
Bạn hãy mở một cửa sổ New Query mới và thêm vào nội dung câu lệnh như sau:
CREATE PROCEDURE [dbo].[usp_Tong_Hop_Nhap_Kho]
AS
BEGIN
SET NOCOUNT ON;
-- Tạo bảng tạm tên bảng tạm bắt đầu bằng dấu #
CREATE TABLE #BaoCao
(Ma_Vt NCHAR(16), Ten_Vt NVARCHAR(64), Dvt NVARCHAR(8),
So_Luong NUMERIC(18, 2), Don_Gia NUMERIC(18, 2),
Thanh_Tien NUMERIC(18, 0))
-- Chèn dữ liệu vào bảng tạm lấy từ CT và CTCT
INSERT INTO #BaoCao
157
SELECT CtCt.Ma_Vt, N'', N'',
SUM(So_Luong) AS So_Luong,
SUM(So_Luong * Don_Gia) / SUM(So_Luong) AS Don_Gia,
SUM(So_Luong * Don_Gia) AS ThanhTien
FROM CtCt LEFT OUTER JOIN Ct ON CtCt.Stt_Ct = Ct.Stt_Ct
WHERE ct.Nhom_Ct = 2
GROUP BY CtCt.Ma_Vt
-- Cập nhật tên và đơn vị tính cho vật tư hàng hóa
UPDATE #BaoCao SET Ten_Vt = vt.Ten_Vt, Dvt = vt.Dvt
FROM #BaoCao AS bc LEFT OUTER JOIN DmVt AS vt
ON bc.Ma_Vt = vt.Ma_Vt
-- Lấy dữ liệu từ bảng tạm
SELECT * FROM #BaoCao
-- Xóa bảng tạm
DROP TABLE #BaoCao
END
Như vậy qua ví dụ trên chúng ta thấy từ cách tạo bảng tới việc sử dụng các câu lệnh SELECT, INSERT, UPDATE,… cho bảng tạm tương tự như bảng thường. Trong một thủ tục lưu bạn có thể tạo nhiều bảng tạm để sử dụng vào nhiều mục đích khác nhau, nhưng
158
lưu ý khi không sử dụng nữa chúng ta nên xóa bảng tạm bằng câu lệnh DROP TABLE.
Cũng với ví dụ trên dưới đây là một cách viết khác mô tả về cách tạo và sử dụng bảng tạm.
CREATE PROCEDURE [dbo].[usp_Tong_Hop_Nhap_Kho]
AS
BEGIN
SET NOCOUNT ON;
-- Ở cách thứ nhất chúng ta phải tạo ra bảng tạm
-- sau đó chèn dữ liệu vào bằng một câu lệnh INSERT
-- Tuy nhiên với cách này bảng tạm được tạo ra ngay từ
-- câu lệnh SELECT kết quả bằng mệnh đề INTO #BaoCao
SELECT CtCt.Ma_Vt,
CAST(N'' AS NVARCHAR(64)) AS Ten_Vt,
CAST(N'' AS NVARCHAR(8)) AS Dvt,
SUM(So_Luong) AS So_Luong,
SUM(So_Luong * Don_Gia) / SUM(So_Luong) AS Don_Gia,
SUM(So_Luong * Don_Gia) AS ThanhTien
INTO #BaoCao
FROM CtCt LEFT OUTER JOIN Ct ON CtCt.Stt_Ct = Ct.Stt_Ct
WHERE ct.Nhom_Ct = 2
GROUP BY CtCt.Ma_Vt
159
-- Các bước tiếp theo sau khi đã tạo bảng tạm
-- tương tự như phần trước
UPDATE #BaoCao SET Ten_Vt = vt.Ten_Vt, Dvt = vt.Dvt
FROM #BaoCao AS bc LEFT OUTER JOIN DmVt AS vt
ON bc.Ma_Vt = vt.Ma_Vt
SELECT * FROM #BaoCao
DROP TABLE #BaoCao
END
Lưu ý: Với cách này chúng ta thấy bảng tạm được tạo bằng mệnh đề INTO đặt sau danh sách trường và trước từ khóa FROM. Ngay sau INTO là tên bảng tạm và được bắt đầu bằng dấu #.
4.4. Tìm hiểu Cursors
Nếu giải thích một cách ngắn gọn thì cursor tương tự như recordset hay dataset trong các ngôn ngữ lập trình. Nghĩa là chúng ta select một số data vào bộ nhớ sau đó có thể lần lượt làm việc với từng bản ghi bằng cách di chuyển lần lượt qua từng bản ghi (Move Next...).
Có 3 loại cursors là Transact- SQL Cursors, API Cursors và Client Cursors. Trong đó Transact-SQL và API thuộc loại Server Cursors nghĩa là cursors được load lên và làm việc bên phía server. Trong khuôn khổ bài học này ta chỉ nghiên cứu Transact-SQL cursors.
Transact-SQL cursors được tạo ra trên server bằng các câu lệnh Transact-SQL và chủ yếu được dùng trong stored procedures và triggers. Trước hết hãy xem qua một ví dụ về cursor:
160
Viết thủ tục sử dụng Cursor để in ra lần lượt danh sách khách hàng, nhà cung cấp trong danh mục đối tượng (thủ tục đặt tên là usp_DmDtPrint).
CREATE PROCEDURE [dbo].[usp_DmDtPrint]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @_Ma_Dt NVARCHAR(40),
@_Ten_Dt NVARCHAR(20)
DECLARE DmDtCursor CURSOR FOR
SELECT Ma_Dt, Ten_Dt FROM DmDt
OPEN DmDtCursor
FETCH NEXT FROM DmDtCursor INTO @_Ma_Dt, @_Ten_Dt
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT N'Đối tượng: ' + RTRIM(@_Ma_Dt) + ' - ' + LTRIM(@_Ten_Dt)
FETCH NEXT FROM DmDtCursor INTO @_Ma_Dt, @_Ten_Dt
END
CLOSE DmDtCursor
DEALLOCATE DmDtCursor
END
Trong ví dụ ở trên ta sẽ select Ma_Dt và Ten_Dt từ bảng DmDt của Database QLHTK và nạp vào DmDtCursor sau đó lần lượt in tên của các đối tượng ra màn hình. Ðể làm việc với một cursor ta cần theo các bước sau:
161
- Dùng câu lệnh DECLARE CURSOR để khai báo một cursor. Khi khai báo ta cũng phải cho biết câu lệnh SELECTsẽ được thực hiện để lấy dữ liệu.
DECLARE DmDtCursor CURSOR FOR
SELECT Ma_Dt, Ten_Dt FROM DmDt
- Dùng câu lệnh OPEN để đưa dữ liệu lên bộ nhớ ảo (memory). Ðây chính là lúc thực hiện câu lệnh SELECT vốn được khai báo ở trên.
OPEN DmDtCursor
- Dùng câu lệnh FETCH để lấy từng hàng data từ record set. Cụ thể là ta phải gọi câu lệnh FETCH nhiều lần. FETCH tương tự như lệnh Move trong ADO recordset ở chỗ nó có thể di chuyển tới lui bằng câu lệnh FETCH FIRST, FETCH NEXT, FETCH PRIOR, FETCH LAST, FETCH ABSOLUTE n, FETCH RELATIVE n nhưng khác ở chỗ là nó lấy data bỏ vào trong variable (FETCH...FROM...INTO variable_name). Thông thường ta FETCH data trước sau đó loop cho tới record cuối của Cursor bằng vòng lặp WHILE bằng cách kiểm tra global variable @@FETCH_STATUS (=0 nghĩa là thành công).
FETCH NEXT FROM DmDtCursor INTO @_Ma_Dt, @_Ten_Dt
- Khi ta di chuyển tới từng bản ghi ta có thể UPDATE hay DELETE tùy theo nhu cầu (trong thí dụ này chỉ dùng lệnh PRINT)
PRINT N'Đối tượng: ' + RTRIM(@_Ma_Dt) + ' - ' + LTRIM(@_Ten_Dt)
- Dùng câu lệnh CLOSE để đóng cursor. Một số tài nguyên (memory resource) sẽ được giải phóng nhưng cursor vẫn còn được khai báo và có thể OPEN trở lại.
CLOSE DmDtCursor
- Dùng câu lệnh DEALLOCATE để phóng thích hoàn toàn các tài nguyên dành cho cursor (kể cả tên của cursor).
DEALLOCATE DmDtCursor
162
Lưu ý: Trong ví dụ ở trên trước khi dùng Cursor chúng ta phải khai báo trước hai biến @_Ma_Dt và @_Ten_Dt để chứa các giá trị lấy được từ cursor.
4.5. Bài tập thực hành
- Viết báo cáo bảng kê chứng từ bao gồm các thông tin: Mã Ct, Số Ct, Ngày Ct, Diễn giải, Mã Đt, Mã Vt, Tên Vt, Đvt, Số lượng, Đơn giá, Thành Tiền.
- Viết báo cáo tổng hợp nhập kho bao gồm các thông tin: Mã vật tư, Tên Vt, Đvt, Số lượng, Đơn giá, Thành tiền (nhóm theo từng vật tư).
- Viết báo cáo tổng hợp xuất kho bao gồm các thông tin: Mã vật tư, Tên Vt, Đvt, Số lượng, Đơn giá, Thành tiền (nhóm theo từng vật tư).
- Viết báo cáo sổ chi tiết vật tư bao gồm các thông tin: Mã Ct, Số Ct, Ngày Ct, Diễn giải, Mã Vt, Tên Vt, Đvt, Sl Nhập, Tiền nhập, Sl xuất, Tiền xuất, Sl tồn, giá trị tồn (liệt kê chi tiết các lần nhập xuất).
- Viết báo cáo tổng hợp nhập – xuất – tồn bao gồm các thông tin: Mã vật tư, Tên vật tư, Đvt, Tồn đầu, dư đầu, Sl Nhập, Tiền nhập, Sl Xuất, Tiền Xuất, Tồn cuối, Dư cuối (Nhóm theo từng vật tư).
5. Trigger
5.1. Định nghĩa
Trigger là một loại Stored Procedure đặc biệt được thực thi một cách tự động khi có một sự kiện thay đổi dữ liệu xảy ra như Update, Insert hay Delete trong một bảng hoặc View nào đó. Trigger được dùng để đảm bảo toàn vẹn dữ liệu hay thực hiện các các công việc nào đó.
Ví dụ: Tạo thêm trường ModifiedAt trong bảng DmDt dùng để lưu thông tin về thời gian cập nhật các bản ghi trong bảng này. Công việc cập nhật được thực hiện tự động bảng Trigger có nội dung như sau:
-- =============================================
163
-- Author: Hoang Anh Quang
-- Create date: 27/07/2011
-- Description: Ghi lai thoi gian cap nhat ban nghi
-- =============================================
CREATE TRIGGER [dbo].[DmDtTriggerLog]
ON [dbo].[DmDt]
AFTER INSERT, UPDATE
AS
BEGIN
UPDATE [DmDt] SET [ModifiedAt] = GETUTCDATE()
WHERE [Id] IN (SELECT [Id] FROM inserted);
END
Giải thích: Trong ví dụ trên:
+ DmDtTriggerLog: Là tên Trigger
+ [dbo].[DmDt]: Tên bảng chứa Trigger
+ INSERT, UPDATE: Trigger được áp dụng trong sự kiện thêm mới và chỉnh sửa
+ Sau phần BEGIN là nội dung thực thi Trigger
- Ta nên sử dụng trigger khi mà các biện pháp bảo đảm toàn vẹn dữ liệu không thể thực hiện thông qua ứng dụng.
- Một Trigger có thể làm nhiều công việc khác nhau và có thể được kích hoạt bởi nhiều hơn một biến cố. Ví dụ ta có thể viết một Trigger được kích hoạt bởi bất kỳ biến cố nào như Update, Insert hay Delete và bên trong trigger ta sẽ viết code để giải quyết cho từng trường hợp.
164
- Trigger không thể được tạo ra trên System table.
- Trigger chỉ có thể được kích hoạt một cách tự động bởi một trong các biến cố Insert, Update, Delete mà không thể chạy “thủ công” (manually) được.
- Có thể áp dụng trigger cho View.
- Khi một Trigger được kích hoạt thì dữ liệu mới vừa được insert hay mới vừa được thay đổi sẽ được chứa trong Inserted table còn data mới vừa được delete được chứa trong Deleted table. Ðây là 2 bảng tạm chỉ chứa trên bộ nhớ ảo (memory) và chỉ có giá trị bên trong Trigger mà thôi (nghĩa là chỉ nhìn thấy và được query trong Trigger mà thôi). Ta có thể dùng thông tin trong 2 bảng này để so sánh dữ liệu cũ và mới hoặc kiểm tra xem dữ liệu mới vừa thay đổi có hợp lệ không.
- Có 2 loại Triggers: INSTEAD OF và AFTER. Loại INSTEAD OF sẽ thực hiện các dòng lệnh SQL bên trong Trigger trước khi thay đổi dữ liệu. Ngược lại loại AFTER sẽ thực hiện các câu lệnh bên trong trigger sau khi thực hiện thay đổi dữ liệu.
5.2. Tạo mới và sửa đổi Trigger
Cũng với ví dụ phần trước chúng ta thực hiện tạo Trigger này trong Database QLHTK, các bước thực hiện như sau:
Bước 1: Khởi động SQL Server 2008
Bước 2: Tìm tới bảng cần tạo Trigger trong Database, nhấp phải chuột vào mục Trigger chọn New Trigger…
165
Bước 3: Một màn hình New Query mới xuất hiện, xóa đi những comment và câu lệnh thừa chúng ta sẽ được nội dụng Trigger mà chương trình đã tạo sẵn như hình dưới đây:
166
- Sau từ khóa CREATE TRIGGER chúng ta thay bằng tên của Trigger: [dbo].[DmDtTriggerLog]
- Sau từ khóa ON chúng ta thay bằng tên bảng chứa Trigger: [dbo].[DmDt]
- Sau từ khóa AFTER chúng ta thay bằng các biến cố sảy ra khi thực hiện Trigger đó là INSERT, UPDATE
- Cuối cùng trong vòng BEGIN… END là nội dụng câu lệnh T-SQL được thực thi khi Trigger hoạt động.
Kết quả cuối cùng như hình dưới đây:
Bước 4: Hãy nhấn phím F5 hoặc nhấp chọn nút Execute trên thanh công cụ để thực thi Trigger.
Bây giờ hãy xem hoạt động của Trigger mà chúng ta vừa tạo, hãy mở dữ liệu của bảng DmDt sau đó chỉnh sửa thông tin của một bản
167
ghi bạn sẽ thấy chương trình tự động cập nhật thời gian chỉnh sửa vào cột ModifiedAt, điều tương tự cũng sảy ra khi bạn thêm một bản ghi mới vào bảng này.
Khi có nhu cầu sửa lại nội dung Trigger vừa tạo hãy nhấp phải chuột vào Trigger đó trong cửa sổ Object Explorer chọn Modified.
Một cửa số New Query xuất hiện hãy thay từ khóa CREATE TRIGGER bằng ALTER TRIGGER sau đó thực hiện những thay đổi cần thiết và thực thi lại Trigger (nhấn phím F5 hoặc nhấp chọn nút Execute trên thanh công cụ).
Lưu ý: Ðôi Khi ta chỉ muốn trigger thực sự hoạt động khi một hay vài column nào đó được Update chứ không phải bất kỳ column nào.
168
Khi đó ta có thể dùng hàm Update(Column_Name) để kiểm tra xem column nào đó có bị update hay không.
Ví dụ: Trong bảng DmDt trường Ma_Dt là trường khóa xác định bản ghi duy nhất, dữ liệu của trường này cũng xuất hiện trong bảng CT, như vậy để toàn vẹn dữ liệu khi người dùng sửa mã trong bảng DMDT cũng đồng thời phải sửa Ma_Dt tương ứng trong bảng CT. Công việc này có thể làm thủ công nhưng như thế sẽ rất khó thực hiện với những Database nhiều dữ liệu. Chúng ta có thể viết một Trigger thực hiện công việc này một cách tự động. Nội dung như sau:
CREATE TRIGGER [dbo].[DmDtTriggerUpdateMa_Dt]
ON [dbo].[DMDT]
AFTER UPDATE
AS
BEGIN
IF UPDATE(Ma_Dt)
BEGIN
DECLARE @_Ma_Dt_Old NCHAR(16),
@_Ma_Dt_New NCHAR(16)
SET @_Ma_Dt_New = (SELECT Ma_Dt FROM INSERTED)
SET @_Ma_Dt_Old = (SELECT Ma_Dt FROM DELETED)
UPDATE CT SET Ma_Dt = @_Ma_Dt_New
WHERE Ma_Dt = @_Ma_Dt_Old
END
END
169
Để thấy được kết quả bạn hãy thử sửa một mã đối tượng bất kỳ trong bảng DMDT sẽ thấy sự thay đổi tương ứng trong bảng CT.
5.3. Bài tập thực hành
- Hãy thêm trường ModifiedAt vào tất cả các bảng trong Database QLHTK sau đó viết Trigger để lưu lại thời gian cập nhật vào trường này.
- Hãy viết Trigger đổi mã cho tất cả các danh mục.