Giao Trinh SQL

169
1 SQL SERVER 2008 Tác giả: Ks Hoàng Anh Quang

Transcript of Giao Trinh SQL

Page 1: Giao Trinh SQL

1

SQL SERVER 2008

Tác giả: Ks Hoàng Anh Quang

Page 2: Giao Trinh SQL

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

Page 3: Giao Trinh SQL

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

Page 4: Giao Trinh SQL

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

Page 5: Giao Trinh SQL

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.

Page 6: Giao Trinh SQL

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.

Page 7: Giao Trinh SQL

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

Page 8: Giao Trinh SQL

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ý

Page 9: Giao Trinh SQL

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

Page 10: Giao Trinh SQL

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

Page 11: Giao Trinh SQL

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.

Page 12: Giao Trinh SQL

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

Page 13: Giao Trinh SQL

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

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

Page 14: Giao Trinh SQL

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:

Page 15: Giao Trinh SQL

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ả

Page 16: Giao Trinh SQL

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’

Page 17: Giao Trinh SQL

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.

Page 18: Giao Trinh SQL

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ả:

Page 19: Giao Trinh SQL

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'

Page 20: Giao Trinh SQL

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]

Page 21: Giao Trinh SQL

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

Page 22: Giao Trinh SQL

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

Page 23: Giao Trinh SQL

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

Page 24: Giao Trinh SQL

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

Page 25: Giao Trinh SQL

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

Page 26: Giao Trinh SQL

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ả

Page 27: Giao Trinh SQL

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.

Page 28: Giao Trinh SQL

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')

Page 29: Giao Trinh SQL

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

Page 30: Giao Trinh SQL

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

Page 31: Giao Trinh SQL

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

Page 32: Giao Trinh SQL

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ả:

Page 33: Giao Trinh SQL

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,

Page 34: Giao Trinh SQL

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

Page 35: Giao Trinh SQL

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

Page 36: Giao Trinh SQL

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

Page 37: Giao Trinh SQL

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

Page 38: Giao Trinh SQL

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,

Page 39: Giao Trinh SQL

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ả:

Page 40: Giao Trinh SQL

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

Page 41: Giao Trinh SQL

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

Page 42: Giao Trinh SQL

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’

)

Page 43: Giao Trinh SQL

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>,

Page 44: Giao Trinh SQL

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

Page 45: Giao Trinh SQL

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

Page 46: Giao Trinh SQL

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.

Page 47: Giao Trinh SQL

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.

Page 48: Giao Trinh SQL

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

Page 49: Giao Trinh SQL

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:

Page 50: Giao Trinh SQL

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

Page 51: Giao Trinh SQL

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.

Page 52: Giao Trinh SQL

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.

Page 53: Giao Trinh SQL

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.

Page 54: Giao Trinh SQL

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…

Page 55: Giao Trinh SQL

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

Page 56: Giao Trinh SQL

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

Page 57: Giao Trinh SQL

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.

Page 58: Giao Trinh SQL

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.

Page 59: Giao Trinh SQL

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.

Page 60: Giao Trinh SQL

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

Page 61: Giao Trinh SQL

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

Page 62: Giao Trinh SQL

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

Page 63: Giao Trinh SQL

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

Page 64: Giao Trinh SQL

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

Page 65: Giao Trinh SQL

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.

Page 66: Giao Trinh SQL

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.

Page 67: Giao Trinh SQL

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…

Page 68: Giao Trinh SQL

68

Bước 2: Hộp thoại tạo bảng xuất hiện như hình dưới đây:

Page 69: Giao Trinh SQL

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.

Page 70: Giao Trinh SQL

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.

Page 71: Giao Trinh SQL

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…

Page 72: Giao Trinh SQL

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:

Page 73: Giao Trinh SQL

73

Nhấp chuột vào nút (…) để chọn đường dẫn mới

Page 74: Giao Trinh SQL

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.

Page 75: Giao Trinh SQL

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:

Page 76: Giao Trinh SQL

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

Page 77: Giao Trinh SQL

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

Page 78: Giao Trinh SQL

78

Bước 3: Hộp thoại Delete Object xuất hiện nhấp Ok để thực hiện xóa.

Page 79: Giao Trinh SQL

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…

Page 80: Giao Trinh SQL

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

Page 81: Giao Trinh SQL

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.

Page 82: Giao Trinh SQL

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.

Page 83: Giao Trinh SQL

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.

Page 84: Giao Trinh SQL

84

Bước 5: Tích chọn Tab Options trong mục Select a page

Page 85: Giao Trinh SQL

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…

Page 86: Giao Trinh SQL

86

Bước 3: Hộp thoại Detach Database xuất hiện nhấp Ok để thực hiện Detach

Page 87: Giao Trinh SQL

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…

Page 88: Giao Trinh SQL

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.

Page 89: Giao Trinh SQL

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

Page 90: Giao Trinh SQL

90

Nhấp Ok để thực hiện Attach.

Page 91: Giao Trinh SQL

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>

Page 92: Giao Trinh SQL

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)

Page 93: Giao Trinh SQL

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ố

Page 94: Giao Trinh SQL

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

Page 95: Giao Trinh SQL

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

Page 96: Giao Trinh SQL

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

Page 97: Giao Trinh SQL

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

Page 98: Giao Trinh SQL

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

Page 99: Giao Trinh SQL

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ị

Page 100: Giao Trinh SQL

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 %

Page 101: Giao Trinh SQL

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

Page 102: Giao Trinh SQL

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

Page 103: Giao Trinh SQL

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

Page 104: Giao Trinh SQL

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

Page 105: Giao Trinh SQL

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 ]

[

Page 106: Giao Trinh SQL

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

Page 107: Giao Trinh SQL

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

Page 108: Giao Trinh SQL

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'

Page 109: Giao Trinh SQL

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ó

Page 110: Giao Trinh SQL

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

Page 111: Giao Trinh SQL

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

Page 112: Giao Trinh SQL

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

Page 113: Giao Trinh 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.

Page 114: Giao Trinh SQL

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

Page 115: Giao Trinh SQL

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

Page 116: Giao Trinh SQL

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

Page 117: Giao Trinh SQL

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.

Page 118: Giao Trinh SQL

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

Page 119: Giao Trinh SQL

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:

Page 120: Giao Trinh SQL

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

Page 121: Giao Trinh SQL

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ụ.

Page 122: Giao Trinh SQL

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.

Page 123: Giao Trinh SQL

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.

Page 124: Giao Trinh SQL

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.

Page 125: Giao Trinh SQL

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

Page 126: Giao Trinh SQL

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.

Page 127: Giao Trinh SQL

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.

Page 128: Giao Trinh SQL

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:

Page 129: Giao Trinh SQL

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'

Page 130: Giao Trinh SQL

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

Page 131: Giao Trinh SQL

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ừ

Page 132: Giao Trinh SQL

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á

Page 133: Giao Trinh SQL

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

Page 134: Giao Trinh SQL

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

Page 135: Giao Trinh SQL

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

Page 136: Giao Trinh SQL

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…

Page 137: Giao Trinh SQL

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.

Page 138: Giao Trinh SQL

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.

Page 139: Giao Trinh SQL

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.

Page 140: Giao Trinh SQL

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.

Page 141: Giao Trinh SQL

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

Page 142: Giao Trinh SQL

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ụ

Page 143: Giao Trinh SQL

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

Page 144: Giao Trinh SQL

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.

Page 145: Giao Trinh SQL

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.

Page 146: Giao Trinh SQL

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

Page 147: Giao Trinh SQL

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

Page 148: Giao Trinh SQL

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

Page 149: Giao Trinh SQL

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:

Page 150: Giao Trinh SQL

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

Page 151: Giao Trinh SQL

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:

Page 152: Giao Trinh SQL

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:

Page 153: Giao Trinh SQL

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

Page 154: Giao Trinh SQL

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

Page 155: Giao Trinh SQL

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ề

Page 156: Giao Trinh SQL

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

Page 157: Giao Trinh SQL

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

Page 158: Giao Trinh SQL

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

Page 159: Giao Trinh SQL

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:

Page 160: Giao Trinh SQL

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:

Page 161: Giao Trinh SQL

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

Page 162: Giao Trinh SQL

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:

-- =============================================

Page 163: Giao Trinh SQL

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.

Page 164: Giao Trinh SQL

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…

Page 165: Giao Trinh SQL

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:

Page 166: Giao Trinh SQL

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

Page 167: Giao Trinh SQL

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.

Page 168: Giao Trinh SQL

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

Page 169: Giao Trinh SQL

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.