Chương 3. Lập trình với cơ sở dữ liệu

Khi nào cần sử dụng cursor? Khi nào chúng ta cần sử dụng kiểu dữ liệu cursor trong Transaction-SQL để giải quyết các vấn đề:  SQL Server là một hệ quản trị CSDL quan hệ (Relational Database Management System) do đó chúng ta nên chọn giải pháp làm việc trên các bộ mẩu tin.  Khi cần giải quyết vấn đề cập nhật dữ liệu thì luôn ưu tiên chọn các hướng giải quyết trên bộ mẩu tin bởi vì khi đó làm cho các bộ xử lý được nhanh hơn.  Sau cùng là hướng giải quyết theo kiểu cursor là giải pháp sau cùng nhất để chọn lựa khi không còn giải pháp nào tốt hơn

pdf50 trang | Chia sẻ: vutrong32 | Ngày: 19/10/2018 | Lượt xem: 133 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Chương 3. Lập trình với cơ sở dữ liệu, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
10/03/2015 1 CHƢƠNG 3. LẬP TRÌNH VỚI CƠ SỞ DỮ LIỆU TRƢỜNG CAO ĐẲNG CÔNG NGHỆ THÔNG TIN THÀNH PHỐ HỒ CHÍ MINH GV: Lê Thị Minh Nguyện Email: leminhnguyen@itc.edu.vn NỘI DUNG 2  Biến cục bộ  Biến hệ thống  Các câu lệnh truy vấn dữ liệu  Các hàm thường dùng  Cấu trúc điều khiển  Cấu trúc lặp  Biến kiểu dữ liệu cursor 10/03/2015 2 1.Biến cục bộ 3 Biến cục bộ: dùng để lưu trữ các giá trị tạm thời trong quá trình tính toán các xử lý bởi sau khi thoát khỏi chương trình hoặc tắt máy thì giá trị các biến này không còn trong bộ nhớ nữa.  Cú pháp: DECLARE @Tên_biến kiểu_dữ_liệu[,]  Ví dụ: DECLARE @ten_ncc varchar(50), @ngayxh DATETIME Gán giá trị cho biến:  Dùng SET hoặc SELECT cùng với phép gán (= ) 1.Biến cục bộ Ví dụ 1: để gán giá trị ngày 25/3/2002 vào biến ngày xuất hàng DECLARE @ngayxh DATETIME SET @ngayxh = „25-3-2014‟ Ví dụ 2: DECLARE @TongSLDat int SELECT @TongSLDat = SUM(SLDAT) FROM CTDH Ví dụ 3: DECLARE @MinSLDat int, @MaxSLDat int SELECT @MinSLDat = MIN(SLDAT), @MaxSLDat = MAX(SLDAT), FROM CTDH 10/03/2015 3 1.Biến cục bộ Xem giá trị hiện hành của biến Cú pháp: PRINT @Tên_biến | Biểu_thức_chuỗi Ví dụ: DECLARE @MinSLDat int, @MaxSLDat int SELECT @MinSLDat = MIN(SLDAT), @MaxSLDat = MAX(SLDAT), FROM CTHDON PRINT „Số lượng đặt thấp nhất là:‟ PRINT @MinSLDat PRINT „Số lượng đặt cao nhất là:‟ PRINT @MaxSLDat 5 Phạm vi hoạt động của biến  Trong Transaction-SQL phạm vi hoạt động của biến chỉ nằm trong một thủ tục nội tại (stored procedure) hoặc một lô (batch) chứa các câu lệnh mà biến đã được khai báo bên trong đó.  Lô được xem như một nhóm tập hợp của một hoặc nhiều câu lệnh Transaction-SQL sẽ được biên dịch đồng thời cùng lúc tại SQL Server.  Một từ khoá GO chỉ định kết thúc 1 lô 6 1.Biến cục bộ 10/03/2015 4 Do các câu lệnh trong một lô được biên dịch tại SQL Server vì thế khi có ít nhất 1 lệnh bên trong lô có lỗi về cú pháp lúc biên dịch thì hệ thống sẽ không có lệnh nào được thực thi bên trong lô đó. Ví dụ: SELECT * FROM NHACC ORDER BY TenNhaCC INSERT INTO NHACC („C01‟, „Nguyen Van A‟, ‟87 Ly Tu Trong‟,„0903.123456‟) SELECT * FROM VATTU ORDER BY Tenvtu DESC GO 7 (thiếu từ khoá VALUES) thì các lệnh SELECT bên trong lô này không được thực hiện. 1.Biến cục bộ Đối với các lỗi khi thực hiện (run-time) bên trong 1 lô nếu trường hợp các lỗi vi phạm ràng buộc toàn vẹn dữ liệu thì hệ thống SQL Server chỉ ngưng lại câu lệnh gây lỗi và thực hiện tiếp các lệnh bên trong lô đó. Ví dụ: SELECT * FROM NHACC ORDER BY TenNhaCC INSERT INTO NHACC VALUES („C01‟, „Nguyen Van A‟, ‟87 Ly Tu Trong‟,„0903.123456‟) SELECT * FROM VATTU ORDER BY Tenvtu DESC GO (mặc dù vi phạm ràng buộc toàn vẹn trong INSERT (giả sử trùng khoá chính ở cột MaNCC) nhưng các lệnh SELECT bên trong lô này vẫn được thực hiện bình thường. 1.Biến cục bộ 10/03/2015 5 Ví dụ: DECLARE @NgayDH datetime SELECT @NgayDH = MAX(NGAYDH) FROM DONDH GO PRINT “ngay dat hang gan nhat: ” + convert(char(12), @ngaydh) GO HT sẽ báo lỗi vì có thêm từ khoá GO ở giữa 2 lệnh SELECT và PRINT. Bởi vì khi đó các lệnh này được chia làm 2 lô và lô thứ hai sẽ không hiểu biến @ngaydh đã được khai báo trong lô thứ 1. 1.Biến cục bộ 2.Biến hệ thống Các biến hệ thống trong SQL Server luôn bắt đầu bằng 2 chữ @@. Giá trị mà chúng ta đang lưu trữ do hệ thống SQL cung cấp. Người lập trình không can thiệp trực tiếp để gán giá trị vào các biến hệ thống. 10 10/03/2015 6 Tên biến kiểu trả về Dùng để trả về connections số nguyên Tổng số các kết nối vào SQL Server từ khi nó được khởi động Error số nguyên số mã lỗi của câu lệnh thực hiện gần nhất. Khi một lệnh thực hiện thành công thì biến này có giá trị là 0 Language chuỗi Tên ngôn ngữ mà hệ thống SQL đag sử dụng. Mặc định là US_English RowCount số nguyên Tổng số mẩu tin được tác động vào câu lệnh truy vấn gần nhất ServerName chuỗi Tên của máy tính cục bộ được cài đặt trong SQL Server ServiceName chuỗi Tên dịch vụ kèm theo bên dưới SQL Server Fetch_Status số nguyên Trạng thái của việc đọc dữ liệu trong bảng theo cơ chế dòng mẩu tin (cursor). Khi dữ liệu đọc mẩu tin thành công thì biến này có giá trị là 0 Version chuỗi Phiên bản, ngày của phẩm SQL Server và loại CPU 2.Biến hệ thống Ví dụ: SELECT * FROM NHACC SELECT @@ROWCOUNT (Trả về tổng số mẩu tin đang hiện có trong bảng NHACC ) Ví dụ: UPDATE SANPHAM SET PHATRAM = PHANTRAM + 5 WHERE MAVTU like “TV%” SELECT @@ROWCOUNT (Trả về tổng số mẩu tin có MAVTU bắt đầu bằng chữ “TV” trong bảng VATTU) 12 2.Biến hệ thống 10/03/2015 7 3.Các câu lệnh truy vấn dữ liệu Truy vấn cơ bản Truy vấn lồng Hàm kết hợp Gom nhóm Điều kiện trên nhóm Cập nhật dữ liệu 13 3.1.Truy vấn cơ bản Gồm 3 mệnh đề  • Tên các cột cần được hiển thị trong kết quả truy vấn  • Tên các bảng liên quan đến câu truy vấn  • Biểu thức boolean xác định dòng nào sẽ được rút trích • Nối các biểu thức: AND, OR, và NOT • Phép toán:  ,  ,  ,  ,  , , LIKE và BETWEEN 14 SELECT FROM WHERE 10/03/2015 8 Ví dụ 15 SELECT * FROM NHANVIEN WHERE PHG=5 Lấy tất cả các cột của quan hệ kết quả SELECT MANV, HONV, TENLOT + TENNV as HOTEN FROM NHANVIEN WHERE PHG=5 AND PHAI=„Nam‟ SELECT MANV, LUONG*1.1 AS „LUONG10%‟ FROM NHANVIEN WHERE PHG=5 AND PHAI=„Nam‟ Mở rộng Tên bí danh Ví dụ 16 Loại bỏ các dòng trùng nhau - Tốn chi phí - Người dùng muốn thấy LUONG 30000 25000 25000 38000 LUONG 30000 25000 38000 SELECT LUONG FROM NHANVIEN WHERE PHG=5 AND PHAI=„Nam‟ SELECT DISTINCT LUONG FROM NHANVIEN WHERE PHG=5 AND PHAI=„Nam‟ 10/03/2015 9 Ví dụ 17 SELECT MANV, TENNV FROM NHANVIEN WHERE LUONG>=20000 AND LUONG<=30000 BETWEEN SELECT MANV, TENNV FROM NHANVIEN WHERE LUONG BETWEEN 20000 AND 30000 NOT BETWEEN SELECT MANV, TENNV FROM NHANVIEN WHERE LUONG NOT BETWEEN 20000 AND 30000 Ví dụ 18 IN SELECT MANV, TENNV FROM NHANVIEN WHERE PHG = 4 OR PHG=5 SELECT MANV, TENNV FROM NHANVIEN WHERE PHG IN (4,5) NOT IN SELECT MANV, TENNV FROM NHANVIEN WHERE PHG NOT IN (4,5) 10/03/2015 10 Ví dụ 19 SELECT MANV, TENNV FROM NHANVIEN WHERE DCHI LIKE „Nguyen _ _ _ _‟ LIKE SELECT MANV, TENNV FROM NHANVIEN WHERE DCHI LIKE „Nguyen %‟ Chuỗi bất kỳ Ký tự bất kỳ NOT LIKE SELECT MANV, TENNV FROM NHANVIEN WHERE HONV NOT LIKE „Nguyen‟ Ví dụ 20 NULL SELECT MANV, TENNV FROM NHANVIEN WHERE MA_NQL IS NULL SELECT MANV, TENNV FROM NHANVIEN WHERE MA_NQL IS NOT NULL 10/03/2015 11 Ví dụ Dùng để hiển thị kết quả câu truy vấn theo một thứ tự nào đó Cú pháp  ASC: tăng (mặc định)  DESC: giảm 21 SELECT FROM WHERE ORDER BY Ví dụ 22 SELECT MA_NVIEN, SODA FROM PHANCONG ORDER BY MA_NVIEN DESC, SODA SODA 10 30 999887777 999887777 MA_NVIEN 10 30 987987987 987654321 987987987 10 20 987654321 30 987654321 10/03/2015 12 3.2.Truy vấn lồng Chỉ một câu lệnh truy vấn lựa chọn (SELECT) được lồng vào các câu lệnh truy vấn khác nhằm thực hiện các truy vấn tính toán phức tạp. Khi sử dụng đến truy vấn lống chúng ta cần lưu tâm đến một vài yếu tố sau:  Cần mở và đóng ngoặc đơn cho câu lệnh truy vấn con.  Chúng ta chỉ được phép tham chiếu đến tên một cột hoặc một biểu thức sẽ trả về giá trị trong truy vấn con.  Kết quả truy vấn con có thể trả về là một giá trị đơn lẻ hoặc một danh sách các giá trị.  Cấp độ lồng nhau của các truy vấn con bên trong SQL Server là không giới hạn. 23 Mệnh đề WHERE của câu truy vấn cha   So sánh tập hợp thường đi cùng với một số toán tử • = ,, >=, • IN, NOT IN • ALL • ANY hoặc SOME  Kiểm tra sự tồn tại • EXISTS • NOT EXISTS 24 3.2.Truy vấn lồng 10/03/2015 13  Truy vấn con trả về một giá trị đơn: là truy vấn mà kết qủa trả về của nó luôn đảm bảo chỉ là một giá trị đơn.  Ví dụ: để biết được danh sách các đơn đặt hàng gần đây nhất. SELECT MAX(NGAYDH) FROM DONDH Kết quả trả về: 2015-01-25 00:00:00 SELECT * FROM DONDH WHERE NGAYDH = “2015-01-25”  Kết hợp 2 câu truy vấn trên SELECT * FROM DONDH WHERE NGAYDH = (SELECT MAX(NGAYDH) FROM DONDH) 25 3.2.Truy vấn lồng  Truy vấn con trả về danh sách các giá trị: trả về của nó là danh sách các giá trị hay còn gọi là một tập hợp các phần tử. Toán tử IN sẽ được sử dụng để so sánh truy vấn con dạng này  Ví dụ 1: để biết nhà cung cấp nào mà công ty đã đặt hàng trong tháng 01/2015. SELECT MaNCC FROM DONDH WHERE Convert(char(7), NgayDH, 21) = “2015-07”  Kết quả trả về MaNCC C03 C01 26 3.2.Truy vấn lồng SELECT TenNCC, DienThoai FROM NHACC WHERE MaNCC IN(“C01”, “C03”) 10/03/2015 14 Đâu đảm bảo rằng trong tháng 01/2002 công ty chỉ đặt hàng cho 2 nhà cung cấp C01 và C03. Do đó để luôn luôn có được danh sách họ tên các nhà cung cấp mà công ty đã đặt trong tháng 01-2002 chúng ta thực hiện truy vấn con sau: 27 SELECT TenNCC, DienThoai FROM NHACC WHERE MaNCC IN(SELECT MaNCC FROM DONDH WHERE Covert(char(7), NgayDH, 21) = “2015-01”) 3.2.Truy vấn lồng Có 2 loại truy vấn lồng  Lồng phân cấp • Mệnh đề WHERE của truy vấn con không tham chiếu đến thuộc tính của các quan hệ trong mệnh đề FROM ở truy vấn cha • Khi thực hiện, câu truy vấn con sẽ được thực hiện trước  Lồng tương quan • Mệnh đề WHERE của truy vấn con tham chiếu ít nhất một thuộc tính của các quan hệ trong mệnh đề FROM ở truy vấn cha • Khi thực hiện, câu truy vấn con sẽ được thực hiện nhiều lần, mỗi lần tương ứng với một bộ của truy vấn cha 28 3.2.Truy vấn lồng 10/03/2015 15 SELECT TenNCC, DienThoai FROM NHACC WHERE MaNCC IN (SELECT MaNCC FROM DONDH WHERE Convert(char(7), NgayDH, 21) = “2015-01”) 29 3.2.Truy vấn lồng Lồng phân cấp SELECT TenNCC, DienThoai FROM NHACC WHERE EXISTS (SELECT * FROM DONDH WHERE Covert(char(7), NgayDH, 21) = “2007-01” AND NHACC.MaNCC = DONDH.MaNCC) 30 Lồng tương quan 3.2.Truy vấn lồng 10/03/2015 16 Ví dụ  Ví dụ 2: Danh sách các nhà cung cấp nào mà công ty chưa bao giờ đặt hàng: SELECT TenNhaCC, DienThoai FROM NHACC WHERE MaNCC NOT IN (SELECT Distinct MaNCC FROM DONDH)  Hoặc SELECT TenNhaCC, DienThoai FROM NHACC WHERE MaNCC ALL (SELECT Distinct MaNCC FROM DONDH) 31 Lưu ý: IN tương đương =ANY NOT IN tương đượng ALL Ví dụ  Tìm những nhân viên không có thân nhân nào 32 SELECT * FROM NHANVIEN WHERE MANV NOT IN ( SELECT MA_NVIEN FROM THANNHAN ) SELECT * FROM NHANVIEN WHERE NOT EXISTS ( SELECT * FROM THANNHAN WHERE MANV=MA_NVIEN) Lồng phân cấp Lồng tƣơng quan 10/03/2015 17 3.3.Hàm kết hợp COUNT  COUNT(*) đếm số dòng  COUNT() đếm số giá trị khác NULL của thuộc tính  COUNT(DISTINCT ) đếm số giá trị khác nhau và khác NULL của thuộc tính MIN MAX SUM AVG Các hàm kết hợp được đặt ở mệnh đề SELECT 33 34 Ví dụ 10/03/2015 18 Ví dụ Tìm tổng lương, lương cao nhất, lương thấp nhất và lương trung bình của các nhân viên Cho biết số lượng nhân viên của phòng „Nghiên cứu‟ 35 SELECT SUM(LUONG), MAX(LUONG), MIN(LUONG), AVG(LUONG) FROM NHANVIEN SELECT COUNT(*) AS SL_NV FROM NHANVIEN, PHONGBAN WHERE PHG=MAPHG AND TENPHG=‘Nghiên cứu’ 3.4.Gom nhóm Cú pháp Sau khi gom nhóm  Mỗi nhóm các bộ sẽ có cùng giá trị tại các thuộc tính gom nhóm 36 SELECT FROM WHERE GROUP BY 10/03/2015 19 Ví dụ Cho biết số lượng nhân viên của từng phòng ban 37 SELECT PHG, COUNT(*) AS SL_NV FROM NHANVIEN GROUP BY PHG SELECT TENPHG, COUNT(*) AS SL_NV FROM NHANVIEN, PHONGBAN WHERE PHG=MAPHG GROUP BY TENPHG Ví dụ Với mỗi nhân viên cho biết mã số, họ tên, số lượng đề án và tổng thời gian mà họ tham gia 38 SELECT MA_NVIEN, COUNT(*) AS SL_DA, SUM(THOIGIAN) AS TONG_TG FROM PHANCONG GROUP BY MA_NVIEN SELECT MA_NVIEN ,HONV, TENNV, COUNT(*) AS SL_DA, SUM(THOIGIAN) AS TONG_TG FROM PHANCONG, NHANVIEN WHERE MA_NVIEN=MANV GROUP BY MA_NVIEN, HONV, TENNV 10/03/2015 20 3.5.Điều kiện trên nhóm Cú pháp Cho biết những nhân viên tham gia từ 2 đề án trở lên 39 SELECT FROM WHERE GROUP BY HAVING SELECT MA_NVIEN, COUNT(*) as SLDA FROM PHANCONG GROUP BY MA_NVIEN HAVING COUNT(*) >= 2 Ví dụ Cho biết những phòng ban (TENPHG) có lương trung bình của các nhân viên lớn lơn 20000 40 SELECT PHG, AVG(LUONG) AS LUONG_TB FROM NHANVIEN GROUP BY PHG HAVING AVG(LUONG) > 20000 SELECT TENPHG, AVG(LUONG) AS LUONG_TB FROM NHANVIEN, PHONGBAN WHERE PHG=MAPHG GROUP BY TENPHG HAVING AVG(LUONG) > 20000 40 10/03/2015 21 Ví dụ Tìm những phòng ban có lương trung bình cao nhất 41 SELECT PHG, AVG(LUONG) AS LUONG_TB FROM NHANVIEN GROUP BY PHG HAVING MAX(AVG(LUONG)) SELECT PHG, AVG(LUONG) AS LUONG_TB FROM NHANVIEN GROUP BY PHG HAVING AVG(LUONG) >= ALL ( SELECT AVG(LUONG) FROM NHANVIEN GROUP BY PHG) Kết luận 42 SELECT FROM [WHERE ] [GROUP BY ] [HAVING ] [ORDER BY ] 10/03/2015 22 3.6.Cập nhật dữ liệu Thêm (insert) Xóa (delete) Sửa (update) 43 3.6.1.Thêm (insert) Dùng để thêm 1 hay nhiều dòng vào bảng Để thêm dữ liệu  Tên quan hệ  Danh sách các thuộc tính cần thêm dữ liệu  Danh sách các giá trị tương ứng Cú pháp (thêm 1 dòng) 44 INSERT INTO () VALUES () 10/03/2015 23 Ví dụ 45 INSERT INTO NHANVIEN(HONV, TENLOT, TENNV, MANV) VALUES („Le‟, „Van‟, „Tuyen‟, „635635635‟) INSERT INTO NHANVIEN VALUES („Le‟, „Van‟, „Tuyen‟, „635635635‟, ‟12/30/1952‟, ‟98 HV‟, „Nam‟, „37000‟, 4) INSERT INTO NHANVIEN(HONV, TENLOT, TENNV, MANV, DCHI) VALUES („Le‟, „Van‟, „Tuyen‟, „635635635‟, NULL) Nhận xét  Thứ tự các giá trị phải trùng với thứ tự các cột  Có thể thêm giá trị NULL ở những thuộc tính không là khóa chính và NOT NULL  Câu lệnh INSERT sẽ gặp lỗi nếu vi phạm RBTV • Khóa chính • Tham chiếu • NOT NULL - các thuộc tính có ràng buộc NOT NULL bắt buộc phải có giá trị 46 3.6.1.Thêm (insert) 10/03/2015 24 Cú pháp (thêm nhiều dòng) 47 INSERT INTO () 3.6.1.Thêm (insert) Ví dụ 48 CREATE TABLE THONGKE_PB ( TENPHG VARCHAR(20), SL_NV INT, LUONG_TC INT ) INSERT INTO THONGKE_PB(TENPHG, SL_NV, LUONG_TC) SELECT TENPHG, COUNT(MANV), SUM(LUONG) FROM NHANVIEN, PHONGBAN WHERE PHG=MAPHG GROUP BY TENPHG 10/03/2015 25 Dùng để xóa các dòng của bảng Cú pháp: Ví dụ: 49 DELETE FROM [WHERE ] DELETE FROM NHANVIEN WHERE MANV=„345345345‟ DELETE FROM NHANVIEN 3.6.2.Xóa (delete) Ví dụ Xóa đi những nhân viên ở phòng „Nghien cuu‟ 50 DELETE FROM NHANVIEN WHERE PHG IN ( SELECT MAPHG FROM PHONGBAN WHERE TENPHG=„Nghien cuu‟) 10/03/2015 26 Nhận xét  Số lượng số dòng bị xóa phụ thuộc vào điều kiện ở mệnh đề WHERE  Nếu không chỉ định điều kiện ở mệnh đề WHERE, tất cả các dòng trong bảng sẽ bị xóa  Lệnh DELETE có thể gây ra vi phạm RB tham chiếu • Không cho xóa • Xóa luôn những dòng có giá trị đang tham chiếu đến – CASCADE • Đặt NULL cho những giá trị tham chiếu 51 3.6.2.Xóa (delete) 3.6.3. Sửa (update) Dùng để thay đổi giá trị của thuộc tính cho các dòng của bảng Cú pháp: 52 UPDATE SET =, =, [WHERE ] 10/03/2015 27 Ví dụ 53 UPDATE NHANVIEN SET NGSINH=‟08/12/1965‟ WHERE MANV=„333445555‟ UPDATE NHANVIEN SET LUONG=LUONG*1.1 Nhận xét  Những dòng thỏa điều kiện tại mệnh đề WHERE sẽ được cập nhật giá trị mới  Nếu không chỉ định điều kiện ở mệnh đề WHERE, tất cả các dòng trong bảng sẽ bị cập nhật  Lệnh UPDATE có thể gây ra vi phạm RB tham chiếu • Không cho sửa • Sửa luôn những dòng có giá trị đang tham chiếu đến – CASCADE 54 3.6.3. Sửa (update) 10/03/2015 28 4.Các làm thường dùng Các hàm chuyển đổi kiểu dữ liệu Các hàm về ngày 55 4.1.Các hàm chuyển đổi kiểu dữ liệu Hàm CAST: chuyển đổi một biểu thức nào đó sang một kiểu dữ liệu mong muốn. Cú pháp: CAST(Biểu_thức AS kiểu_dữ_liệu) Ví dụ: SELECT MaVTU, TenVT, TyLe = CAST(PHANTRAM AS VARCHAR(3)) + ‘%’ FROM VATTU 56 10/03/2015 29 Hàm CONVERT: chuyển đổi một biểu thức nào đó sang một kiểu dữ liệu bất kỳ mong muốn nhưng có thể theo một định dạng nào đó. Cú pháp: CONVERT (Kiểu_dữ_liệu, Biểu_thức[, định_dạng]) Ví dụ: SELECT SoHD, CONVERT(char(10),NgayHD, 103) AS NGAYHD FROM DONDH 57 4.1.Các hàm chuyển đổi kiểu dữ liệu 58 Bảng chuyển mô tả viết tắt của đơn vị STT Định dạng năm (yyyy) Hiển thị dữ liệu 1 101 Mm/dd/yy 2 102 yy.mm.dd 3 103 Dd/mm/yy 4 104 dd.mm.yy 5 105 dd-mm-yy 6 106 Dd mon yy 7 107 Mon dd, yy 8 108 Hh:mm:ss 9 109 Mon dd yyyy hh:mm:ss 10 110 mm-dd-yy 11 111 Yy/mm/dd 12 112 Yymmdd 13 113 Dd mon yyyy hh:mm:ss 14 114 Hh:mm:ss:mmm 15 21 hoặc 121 Yyyy-mm-dd hh:mi:ss.mmm 16 20 hoặc 120 Yyyy-mm-dd hh:mi:ss 58 58 10/03/2015 30 Hàm STR: chuyển đổi kiểu dữ liệu số sang kiểu dữ liệu chuỗi. Phải đảm bảo đủ khoảng trắng để chứa các ký số khi chuyển sang kiểu dữ liệu chuỗi. Cú pháp: STR(Số_thực, Số_ký_tự[, Số_lẻ]) Ví dụ: SELECT TenVT, SLNhap = STR(SLNhap, 5) + „ ‟ + DVTinh FROM VATTU, CTPNHAP WHERE VATTU.MaVT = CTPNHAP.MaVT 59 4.1.Các hàm chuyển đổi kiểu dữ liệu  Hàm ASCII: ASCII(string) Hàm trả về mã ASCII của ký tự đầu tiên bên trái của chuỗi đối số  Hàm CHAR: CHAR(ascii_code) Hàm trả về ký tự có mã ASCII tương ứng với đối số  Hàm CHARINDEX: CHARINDEX(string1,string2[,start]) Hàm trả về vị trí đầu tiên tính từ vị trí start tại đó chuỗi string1 xuất hiện trong chuỗi string2.  Hàm LEFT: LEFT(string,number) Hàm trích ra number ký tự từ chuỗi string tính từ phía bên trái 60 4.1.Các hàm chuyển đổi kiểu dữ liệu 10/03/2015 31 4.2.Các hàm trên dữ liệu kiểu chuỗi  Hàm LEN: LEN(string) Hàm trả về độ dài của chuỗi string  Hàm LOWER : LOWER(string) Hàm có chức năng chuyển chuỗi string thành chữ thường, kết quả được trả về cho hàm  Hàm UPPER: UPPER(string) Chuyển chuỗi string thành chữ hoa  Hàm LTRIM: LTRIM(string) Cắt bỏ các khoảng trắng thừa bên trái chuỗi string  Hàm NCHAR: NCHAR(code_number) Hàm trả về ký tự UNICODE có mã được chỉ định 61  Hàm REPLACE: REPLACE(string1,string2,string3) Hàm trả về một chuỗi có được bằng cách thay thế các chuỗi string2 trong chuỗi string1 bởi chuỗi string3.  Hàm REVERSE: REVERSE(string) Hàm trả về chuỗi đảo ngược của chuỗi string.  Hàm RIGHT: RIGHT(string, number) Hàm trích ra number ký tự từ chuỗi string tính từ phía bên phải.  Hàm RTRIM: RTRIM(string) Cắt bỏ các khoảng trắng thừa bên phải của chuỗi string. 62 4.2.Các hàm trên dữ liệu kiểu chuỗi 10/03/2015 32  Hàm SPACE: SPACE(number) Hàm trả về một chuỗi với number khoảng trắng.  Hàm SUBSTRING: SUBSTRING(string, m, n) Trích ra từ n ký tự từ chuỗi string bắt đầu từ ký tự thứ m.  Hàm UNICODE : UNICODE(UnicodeString) Hàm trả về mã UNICODE của ký tự đầu tiên bên trái của chuỗi UnicodeString. 63 4.2.Các hàm trên dữ liệu kiểu chuỗi 4.4.Các hàm về ngày  DATEDIFF: trả về 1 số nguyên khoảng cách của hai ngày theo một đơn vị thời gian bất kỳ DATEDIFF(don_vi, ngay1, ngay2)  Đơn vị • DW: trả về ngày trong tuần • DD: trả về ngày • MM: trả về tháng • QQ: trả về quý • YYYY: trả về năm  Ví dụ: SELECT MADH, SONGAY = DATEDIFF(DD,NGAYDH,NGAYGH) FROM DONDH 64 10/03/2015 33  DATENAME: trả về một chuỗi thời gian đại diện của 1 ngày chỉ định theo một đơn vị thời gian bất kỳ DATENAME(Don_vi, ngay)  Ví dụ: SELECT MADH, THU = DATENAME(DW, NGAYDH) FROM DONDH 65 4.4.Các hàm về ngày  GETDATE: trả về ngày giờ hiện hành của hệ thống GETDATE()  DATEPART: trả về 1 số nguyên chỉ định thời gian đại diện của 1 ngày theo một đơn vị thời gian bất kỳ DATEPART(Don_vi, ngày)  Ví dụ: SELECT SODH, THANG = DATEPART(MM, NGAYDH) FROM DONDH 66 4.4.Các hàm về ngày 10/03/2015 34 Cấu trúc Case Cấu trúc IF 67 5.Cấu trúc điều khiển 5.1. Cấu trúc Case  Cho phép kiểm tra điều kiện và xuất thông tin theo từng trường hợp  Cú pháp: 68 CASE WHEN THEN WHEN THEN [ELSE ] END 10/03/2015 35 Ví dụ 1: Cho biết họ tên các nhân viên đã đến tuổi về hưu (nam 60 tuổi, nữ 55 tuổi) 69 SELECT HONV, TENNV FROM NHANVIEN WHERE YEAR(GETDATE()) – YEAR(NGSINH) >= ( CASE PHAI WHEN 'Nam' THEN 60 WHEN 'Nu' THEN 55 END ) 5.1. Cấu trúc Case Ví dụ 2: hiển thị danh sách các sản phẩm có trong bảng SANPHAM theo từng loại hàng SELECT MAVTU, TenVTU, Loai = CASE LEFT(MAVTU,2) When “DD” THEN “Đầu DVD” When “VD” THEN “Đầu VCD” When “TV” THEN “Tivi” When “TL” THEN “Tủ lạnh” When “LO” THEN “Loa thùng” ELSE “chưa phân loại” End, DVTinh FROM VATTU 70 5.1. Cấu trúc Case 10/03/2015 36 Ví dụ 3: Giảm giá bán hàng trong tháng 2-2007 theo quy tắc sau: Nếu số lượng hàng <= 2 thì không giảm giá, Nếu số lượng hàng từ 3 đến 10 thì giảm 10%, Nếu số lượng hàng > 10 thì giảm 20%. UPDATE CTPXUAT SET DGXuat = CASE WHEN SLXUAT <=2 THEN DGXuat WHEN SLXUAT BETWEEN 3 AND 10 THEN DGXuat * 0.9 ELSE DGXuat*0.8 END FROM CTPXUAT, PXUAT WHERE CTPXUAT.SoPX = PXUAT.SoPX AND Convert(char(7), NgayXuat, 21) = “2007-02” 71 5.1. Cấu trúc Case 5.2. Cấu trúc IF Cú pháp IF Biểu_thức_luận_lý Câu_lệnh1|khối_lệnh1 ELSE Câu_lệnh2|khối_lệnh2 72 10/03/2015 37 Ví dụ: Cho biết vật tư nào đã bán ra với số lượng nhiều hơn 4 không? Nếu có thì hiển thị danh sách đó ra, ngược lại thì thông báo chưa bán vật tư nào nhiều hơn 4 IF (SELECT COUNT(*) FROM CTPXUAT WHERE SLXUAT>4)>0 BEGIN Print “Danh sách các hàng hoá bán ra với số lượng lớn hơn 4” SELECT CTPXUAT.MAVT, TENVT, SLXUAT FROM CTPXUAT, VATTU WHERE CTPXUAT.MaVT = VATTU.MaVT AND SLXUAT>4 END ELSE Print “chưa bán hàng nào với số lượng lớn hơn 4” 73 5.2. Cấu trúc IF Cú pháp: 74 WHILE Biểu_thức_luận_lý BEGIN Các_lệnh_lặp END 6.Cấu trúc lặp 10/03/2015 38 Ví dụ 1: Để in ra 10 số nguyên dương bắt đầu từ 100. DECLARE @Songuyen INT SET @Songuyen = 100 WHILE (@Songuyen < 110) BEGIN Print “Số nguyên: ” + convert(char(3), @songuyen) SET @Songuyen = @Songuyen +1 END 75 6.Cấu trúc lặp WHILE Biểu_thức_luận_lý BEGIN Các_lệnh_nhóm_lặp_1 [IF Biểu_thức_lặp_Tiếp CONTINUE ] [IF Biểu_thức_thoát BREAK ] Các_lệnh_nhóm_lặp_2 END Các_lệnh_khác 76 6.Cấu trúc lặp 10/03/2015 39  Từ khoá BREAK lồng vào cấu trúc WHILE để có thể kết thúc việc lặp của các lệnh bên trong vòng lặp DECLARE @Songuyen int SET @Songuyen = 100 WHILE (@Songuyen < 110) BEGIN Print „So nguyen: ‟ + Convert(char(3), @songuyen) IF @Songuyen = 105 Break SET @Songuyen = @Songuyen +1 END 77 6.Cấu trúc lặp Thực hiện giống ví dụ trước, nhưng muốn in sót số nguyên 105. Chúng ta sử dụng cấu trúc lặp WHILE như sau: DECLARE @Songuyen int SET @Songuyen = 99 WHILE (@Songuyen < 110) BEGIN SET @Songuyen = @Songuyen + 1 IF @Songuyen = 105 CONTINUE Print ‘Số nguyên: ’ + Convert(char(3), @songuyen) END 78 6.Cấu trúc lặp 10/03/2015 40 7.Kiểu dữ liệu cursor Giới thiệu Các bước sử dụng kiểu dữ liệu cursor Ví dụ 79 7.1.Giới thiệu  CSDL quan hệ thường làm việc trên dữ liệu của nhiều dòng mẩu tin – còn gọi là các bộ mẩu tin. Lệnh SELECT kết quả luôn trả về nhiều mẩu tin hơn là một mẩu tin.  Tuy nhiên trong thực tế, có những trường hợp cần xử lý vấn đề trên một mẩu tin hoặc trên nhiều mẩu tin cùng thời gian với hình thức tính toán khác nhau. Để đáp ứng được yêu cầu này SQL Server tạo ra một kiểu dữ liệu đó chính là kiểu cursor. 80 10/03/2015 41 7.2.Các bước sử dụng kiểu cursor Biến kiểu cursor: định nghĩa biến kiểu cursor bằng lệnh DECLARE. Mở Cursor : sử dụng lệnh OPEN để mở ra cursor đã định nghĩa trước đó. Đọc và xử lý trên từng dòng dữ liệu bên trong cursor Đóng cursor: bằng lệnh CLOSE và DEALLOCATE. 81 7.2.1. Biến kiểu cursor DECLARE Tên_cursor CURSOR [LOCAL | GLOBAL] [FORWARD_ONLY | SCROLL] [STATIC | DYNAMIC | KEYSET] [READ_ONLY | SCROLL_LOCK] FOR Câu_lệnh SELECT [FOR UPDATE [OF danh_sách_cột_n]]  Trong đó:  Tên cursor: tên của biến kiểu cursor  LOCAL | GLOBAL: phạm vi hoạt động của biến cursor.  FORWARD_ONLY: đọc dữ liệu trong cursor theo chiều đi tới duyệt từ đầu mẫu tin đầu tiên đến mẫu tin cuối cùng. 82 Cú pháp 10/03/2015 42  STATIC: đọc dữ liệu bên trong cursor tĩnh. Khi đó nếu những người dùng khác có thay đổi bên dưới dữ liệu gốc thì các thay đổi đó sẽ không được cập nhật tự động trong dữ liệu của cursor. Bởi vì khi đó dữ liệu trong cursor chính là dữ liệu của bảng tạm đã được hệ thống sao chép và lưu trữ trong CSDL tempdb của hệ thống khi định nghĩa cursor.  DYNAMIC: dùng chỉ định dữ liệu trong cursor là động. Khi đó việc cập nhật dữ liệu trong bảng cơ sở bởi những người dùng khác sẽ được cập nhật tự động trong dữ liệu cursor có kiểu là DYNAMIC. 83 7.2.1. Biến kiểu cursor  KEYSET: hoạt động giống với kiểu DYNAMIC, các thay đổi dữ liệu trên các cột không là khoá chính trong bảng cơ sở bởi những người dùng khác sẽ được cập nhật trong dữ liệu cursor. Tuy nhiên đối với mẩu tin vừa thêm mới hoặc các mẩu tin đã bị huỷ bỏ bởi những người dùng khác sẽ không được hiển thị trong dữ liệu cursor có kiểu là KEYSET.  READ_ONLY: chỉ định dữ liệu trong cursor chỉ đọc nhằm hạn chế việc sửa đổi dữ liệu bên trong cursor. Khi khai báo cursor với kiểu dữ liệu tĩnh (STATIC) thì dữ liệu trong cursor xem như chỉ đọc. 84 7.2.1. Biến kiểu cursor 10/03/2015 43  SCROLL_LOCK: chỉ định hệ thống SQL Server tự động khoá các dòng mẩu tin cần phải thay đổi giá trị hoặc huỷ bỏ bên trong bảng nhằm bảo đảm các hành động cập nhật luôn thành công.  SELECT: dùng để chỉ đến các cột bên trong bảng mà chúng ta cần đọc dữ liệu.  Danh sách các cột cập nhật: chỉ định danh sách tên các cột sẽ được phép thay đổi giá trị trong cursor. 85 7.2.1.Biến kiểu cursor Ví dụ 1: để định nghĩa một biến cursor chứa toàn bộ các dòng dữ liệu bên trong bảng MAT_HANG, các dòng dữ liệu trong cursor cho phép được cập nhật. DECLARE Cur_MAT_HANG CURSOR DYNAMIC FOR SELECT * FROM MATHANG Ví dụ 2: Định nghĩa một biến cursor chứa toàn bộ các dòng dữ liệu bên trong bảng NHACC, các dữ liệu trong cursor chỉ được phép đọc và việc đọc dữ liệu trong cursor chỉ theo một chiều đi tới. DECLARE Cur_NhaCC CURSOR FORWARD_ONLY STATIC READ_ONLY FOR SELECT * FROM NHACC 86 7.2.1. Biến kiểu cursor 10/03/2015 44 7.2.2. Mở Cursor Cú pháp: OPEN Tên_cursor Trong đó: Tên cursor: tên của biến cursor đã được định nghĩa trước đó bằng lệnh DECLARE Ví dụ: Mở các cursor đã định nghĩa ở ví dụ 1 trên. Chúng ta sử dụng lệnh OPEN như sau: OPEN cur_MAT_HANG 87 7.2.3.Đọc và xử lý dữ liệu trong cursor FETCH [Next | Prior | First | Last |Absolute n | Relative n] FROM Tên_cursor [INTO danh_sách_biến]  Trong đó:  Next, Prior, First, Last: dùng để đọc dữ liệu kế tiếp, trước, đầu, sau cùng.  Absolute: dữ liệu chính xác thứ n trong cursor. N>0 chỉ định việc đọc dữ liệu tại dòng thứ n đếm từ dòng đầu tiên, n<0 dùng chỉ định việc đọc dữ liệu tại dòng thứ n được đếm ngược từ dòng cuối trở lên.  Relative: dùng chỉ định việc đọc dữ liệu tại một dòng tương đối so với dòng dữ liệu hiện hành. N là một số nguyên có thể dương có thể âm để chỉ định theo chiều tới hoặc lui so với dòng dữ liệu hiện hành. 88 10/03/2015 45  FETCH: đọc dữ liệu trong cursor được phép di chuyển tới lui, qua lại các dòng mẩu tin bên trong cursor tuỳ thích. 89 7.2.3.Đọc và xử lý dữ liệu trong cursor 7.2.4.Đóng cursor Cú pháp: CLOSE Tên_cursor DEALLOCATE Tên_cursor Trong đó  CLOSE giải phóng các dòng dữ liệu tham chiếu bên trong cursor.  DEALLOCATE giải phóng thật sự biến cursor ra khỏi bộ nhớ 90 10/03/2015 46 7.3.Ví dụ SQL Server cung cấp một biến hệ thống @@FETCH_STATUS dùng để kiểm tra trình trạng đọc dữ liệu thành công hay thất bại. Giá trị trả về 0 khi việc đọc dữ liệu là thành công. Cho lược đồ quan hệ như sau:  MAT_HANG(MaMH, TenMH, DVT, MaNCC)  PNHAP(MaPN, NgayNhap, ThanhTien)  CTPNHAP(MaMH, MaPN, SLNhap, DonGia) 91  Đọc dữ liệu cursor của bảng MAT_HANG chỉ đọc các vật tư là Tivi  -- Khai báo biến cursor DECLARE cur_MatHang CURSOR DYNAMIC FOR SELECT * FROM MAT_HANG WHERE MaMH like „TV%‟ ORDER BY MaMH  -- Mở cursor OPEN cur_MatHang  -- Đọc dữ liệu FETCH NEXT FROM cur_MatHang WHILE @@FETCH_STATUS = 0 BEGIN -- Đọc tiếp dòng kế FETCH NEXT FROM cur_MatHang END  -- Đóng cursor CLOSE cur_MatHang DEALLOCATE cur_MatHang 92 7.3.Ví dụ 10/03/2015 47 Cập nhật dữ liệu cho cột ThanhTien trong bảng PNHAP bằng cách duyệt qua từng phiếu nhập, tính ra trị giá nhập của từng phiếu căn cứ vào số lượng nhập và đơn giá nhập của từng vật tư trong bảng CTPNHAP, sau cùng cập nhật vào cột ThanhTien.  -- Khai báo biến cursor, các biến cục bộ DECLARE @Sopn char(4), @TongTT Money DECLARE cur_Pnhap CURSOR FORWARD_ONLY FOR SELECT SOPN FROM PNHAP  -- Mở cursor OPEN cur_Pnhap 93 7.3.Ví dụ  -- Đọc dữ liệu và cập nhật giá trị FETCH NEXT FROM cur_Pnhap INTO @Sopn WHILE @@FETCH_STATUS = 0 BEGIN SELECT @Tongtt = SUM(SLNhap*dongia) FROM CTPNHAP WHERE MaPN = @SoPN Print „dang cap nhat phieu nhap: ‟ + @SoPN UPDATE PNHAP SET Thanhtien = @TongTT Where Current OF cur_Pnhap// sopn=@SOPN -- dịch con trỏ đến dòng kế tiếp FETCH NEXT FROM cur_Pnhap INTO @Sopn END  -- Đóng cursor CLOSE cur_Pnhap DEALLOCATE cur_Pnhap 94 Dịch chuyển con trỏ cur_Pnhap vào @SoPN 7.3.Ví dụ 10/03/2015 48 DECLARE @Sopn char(4), @TongTT Money DECLARE cur_Pnhap CURSOR FORWARD_ONLY FOR SELECT SOPN FROM PNHAP OPEN cur_Pnhap WHILE 0 = 0 BEGIN FETCH NEXT FROM cur_Pnhap INTO @Sopn IF @@FETCH_STATUS0 BREAK SELECT @Tongtg = SUM(SLNhap*dongia) FROM CTPNHAP WHERE MaPN = @SoPN Print „dang cap nhat phieu nhap: ‟ + @SoPN UPDATE PNHAP SET Thanhtien = @TongTT Where Current OF cur_Pnhap END CLOSE cur_Pnhap DEALLOCATE cur_Pnhap 95 Hoặc 7.3.Ví dụ DECLARE Tên_cursor CURSOR {kiểu đọc | cập nhật dữ liệu} FOR Câu lệnh SELECT --2. Mở cursor OPEN Tên_cursor --3. Đọc dữ liệu và cập nhật giá trị WHILE 0=0 Begin FETCH NEXT FROM [INTO danh_sách_biến] IF @@FETCH_STATUS 0 Break --cập nhật dữ liệu trong cursor End --4. Đóng cursor CLOSE Tên_cursor DEALLOCATE Tên_cursor 96 7.3.Ví dụ 10/03/2015 49 Khi nào cần sử dụng cursor? Khi nào chúng ta cần sử dụng kiểu dữ liệu cursor trong Transaction-SQL để giải quyết các vấn đề:  SQL Server là một hệ quản trị CSDL quan hệ (Relational Database Management System) do đó chúng ta nên chọn giải pháp làm việc trên các bộ mẩu tin.  Khi cần giải quyết vấn đề cập nhật dữ liệu thì luôn ưu tiên chọn các hướng giải quyết trên bộ mẩu tin bởi vì khi đó làm cho các bộ xử lý được nhanh hơn.  Sau cùng là hướng giải quyết theo kiểu cursor là giải pháp sau cùng nhất để chọn lựa khi không còn giải pháp nào tốt hơn 97 Kết luận 98 10/03/2015 50 TRƢỜNG CAO ĐẲNG CÔNG NGHỆ THÔNG TIN THÀNH PHỐ HỒ CHÍ MINH

Các file đính kèm theo tài liệu này:

  • pdfchuong_3_9694.pdf