nguyenanhque.sql.function

Màu nền
Font chữ
Font size
Chiều cao dòng

5.2 Hàm do người dùng định nghĩa 

 Hàm là đối tượng cơ sở dữ liệu tương tự như thủ tục. Điểm khác biệt giữa hàm 

và thủ tục là hàm trả về một giá trị thông qua tên hàm còn thủ tục thì không. Điều này 

cho phép ta sử dụng hàm như là một thành phần của một biêu thức (chẳng hạn trong 

danh sách chọn của câu lệnh SELECT). 

 Ngoài những hàm do hệ quản trị cơ sở dữ liệu cung cấp sẵn, người sử dụng có 

thể định nghĩa thêm các hàm nhằm phục vụ cho mục đích riêng của mình.  

5.2.1 Định nghĩa và sử dụng hàm 

 Hàm được định nghĩa thông qua câu lệnh CREATE FUNCTION với cú pháp 

như sau: 

CREATE FUNCTION tên_hàm ([danh_sách_tham_số])   

RETURNS (kiểu_trả_về_của_hàm) 

AS   

BEGIN  

   các_câu_lệnh_của_hàm  

END 

Ví dụ 5.7: Câu lệnh dưới đây định nghĩa hàm tính ngày trong tuần (thứ trong tuần) của 

một giá trị kiểu ngày 

CREATE FUNCTION thu(@ngay DATETIME) 

RETURNS NVARCHAR(10) 

AS 

 BEGIN 

111   Khoa CNTT - Trường ĐHKH Huế  Giáo trình SQL 

  DECLARE @st NVARCHAR(10) 

  SELECT @st=CASE DATEPART(DW,@ngay) 

     WHEN 1 THEN 'Chu nhật' 

     WHEN 2 THEN 'Thứ hai' 

     WHEN 3 THEN 'Thứ ba' 

     WHEN 4 THEN 'Thứ tư' 

     WHEN 5 THEN 'Thứ năm' 

     WHEN 6 THEN 'Thứ sáu' 

     ELSE 'Thứ bảy' 

       END   

    RETURN (@st)  /* Trị trả về của hàm */ 

 END 

 Một hàm khi đã được định nghĩa có thể được sử dụng như các hàm do hệ quản 

trị cơ sở dữ liệu cung cấp (thông thường trước tên hàm ta phải chỉ định thêm tên của 

người sở hữu hàm) 

Ví dụ 5.8: Câu lệnh SELECT dưới đây sử dụng hàm đã được định nghĩa ở ví dụ trước: 

SELECT masv,hodem,ten,dbo.thu(ngaysinh),ngaysinh 

FROM sinhvien  

WHERE malop=’C24102’ 

có kết quả là: 

5.2.2 Hàm với giá trị trả về là “dữ liệu kiểu bảng” 

 Ta đã biết được chức năng cũng như sự tiện lợi của việc sử dụng các khung nhìn 

trong cơ sở dữ liệu. Tuy nhiên, nếu cần phải sử dụng các tham số trong khung nhìn 

(chẳng hạn các tham số trong mệnh đề WHERE của câu lệnh SELECT) thì ta lại không 

thể thực hiện được. Điều này phần nào đó làm giảm tính linh hoạt trong việc sử dụng 

khung nhìn. 

112   Khoa CNTT - Trường ĐHKH Huế  Giáo trình SQL 

Ví dụ 5.9: Xét khung nhìn được định nghĩa như sau: 

CREATE VIEW  sinhvien_k25 

AS 

  SELECT masv,hodem,ten,ngaysinh  

   FROM sinhvien INNER JOIN lop  

     ON sinhvien.malop=lop.malop 

 WHERE khoa=25 

với khung nhìn trên, thông qua câu lệnh: 

  SELECT * FROM sinhvien_K25 

ta có thể biết được danh sách các sinh viên khoá 25 một cách dễ dàng nhưng rõ ràng 

không thể thông qua khung nhìn này để biết được danh sách sinh viên các khoá khác 

do không thể sử dụng điều kiện có dạng KHOA = @thamso trong mệnh đề WHERE 

của câu lệnh SELECT được. 

 Nhược điểm trên của khung nhìn có thể khắc phục bằng cách sử dụng hàm với 

giá trị trả về dưới dạng bảng và được gọi là hàm nội tuyến (inline function). Việc sử 

dụng hàm loại này cung cấp khả năng như khung nhìn nhưng cho phép chúng ta sử 

dụng được các tham số và nhờ đó tính linh hoạt sẽ cao hơn. 

 Một hàm nội tuyến được định nghĩa bởi câu lệnh CREATE TABLE với cú pháp 

như sau: 

CREATE FUNCTION tên_hàm ([danh_sách_tham_số]) 

RETURNS TABLE  

AS    

   RETURN (câu_lệnh_select) 

Cú pháp của hàm nội tuyến phải tuân theo các qui tắc sau: 

•  Kiểu trả về của hàm phải được chỉ định bởi mệnh đề RETURNS TABLE. 

•  Trong phần thân của hàm chỉ có duy nhất một câu lệnh RETURN xác định 

giá trị trả về của hàm thông qua duy nhất một câu lệnh SELECT. Ngoài ra, 

không sử dụng bất kỳ câu lệnh nào khác trong phần thân của hàm. 

Ví dụ 5.10: Ta định nghĩa hàm  func_XemSV như sau: 

CREATE FUNCTION func_XemSV(@khoa SMALLINT) 

RETURNS TABLE 

AS 

113   Khoa CNTT - Trường ĐHKH Huế  Giáo trình SQL 

  RETURN(SELECT masv,hodem,ten,ngaysinh  

      FROM sinhvien INNER JOIN lop 

              ON sinhvien.malop=lop.malop   

      WHERE khoa=@khoa) 

hàm trên nhận tham số đầu vào là khóa của sinh viên cần xem và giá trị trả về của hàm 

là tập các dòng dữ liệu cho biết thông tin về các sinh viên của khoá đó. Các hàm trả về 

giá trị dưới dạng bảng được sử dụng như là các bảng hay khung nhìn trong các câu 

lệnh SQL.  

Với hàm được định nghĩa như trên, để biết danh sách các sinh viên khoá 25,  ta sử 

dụng câu lệnh như sau: 

  SELECT * FROM dbo.func_XemSV(25) 

còn câu lệnh dưới đây cho ta biết được danh sách sinh viên khoá 26 

  SELECT * FROM dbo.func_XemSV(26) 

  Đối với hàm nội tuyến, phần thân của hàm chỉ cho phép sự xuất hiện duy nhất 

của câu lệnh RETURN. Trong trường hợp cần phải sử dụng đến nhiều câu lệnh trong 

phần thân của hàm, ta sử dụng cú pháp như sau để định nghĩa hàm: 

CREATE FUNCTION tên_hàm([danh_sách_tham_số]) 

RETURNS @biến_bảng TABLE định_nghĩa_bảng 

AS  

  BEGIN  

    các_câu_lệnh_trong_thân_hàm  

    RETURN 

  END 

 Khi định nghĩa hàm dạng này cần lưu ý một số điểm sau: 

•  Cấu trúc của bảng trả về bởi hàm  được xác  định dựa vào  định nghĩa của 

bảng trong mệnh  đề RETURNS. Biến @biến_bảng trong mệnh  đề 

RETURNS có phạm vi sử dụng trong hàm và được sử dụng như là một tên 

bảng. 

•  Câu lệnh RETURN trong thân hàm không chỉ định giá trị trả về. Giá trị trả 

về của hàm chính là các dòng dữ liệu trong bảng có tên là @biếnbảng được 

định nghĩa trong mệnh đề RETURNS  

   Cũng tương tự như hàm nội tuyến, dạng hàm này cũng được sử dụng trong các 

câu lệnh SQL với vai trò như bảng hay khung nhìn. Ví dụ dưới đây minh hoạ cách sử 

dụng dạng hàm này trong SQL. 

114   Khoa CNTT - Trường ĐHKH Huế  Giáo trình SQL 

Ví dụ 5.11: Ta định nghĩa hàm func_TongSV như sau: 

CREATE FUNCTION Func_Tongsv(@khoa SMALLINT) 

RETURNS @bangthongke TABLE 

 ( 

  makhoa    NVARCHAR(5), 

  tenkhoa   NVARCHAR(50), 

  tongsosv  INT 

 ) 

AS 

 BEGIN 

  IF @khoa=0  

   INSERT INTO @bangthongke 

   SELECT khoa.makhoa,tenkhoa,COUNT(masv) 

      FROM (khoa INNER JOIN lop  

               ON khoa.makhoa=lop.makhoa)  

                          INNER JOIN sinhvien 

         on lop.malop=sinhvien.malop 

   GROUP BY khoa.makhoa,tenkhoa 

  ELSE 

   INSERT INTO @bangthongke 

   SELECT khoa.makhoa,tenkhoa,COUNT(masv) 

      FROM (khoa INNER JOIN lop  

               ON khoa.makhoa=lop.makhoa)  

                          INNER JOIN sinhvien 

         ON lop.malop=sinhvien.malop 

   WHERE khoa=@khoa 

   GROUP BY khoa.makhoa,tenkhoa 

  RETURN /*Trả kết quả về cho hàm*/ 

 END 

Với hàm được định nghĩa như trên, câu lệnh: 

  SELECT * FROM dbo.func_TongSV(25) 

Sẽ cho kết quả thống kê tổng số sinh viên khoá 25 của mỗi khoa: 

115   Khoa CNTT - Trường ĐHKH Huế  Giáo trình SQL 

Còn câu lệnh: 

  SELECT * FROM dbo.func_TongSV(0) 

Cho ta biết tổng số sinh viên hiện có (tất cả các khoá) của mỗi khoa: 

Bạn đang đọc truyện trên: Truyen2U.Pro