UserDefinedFunctions - UDFs Nguồn : forum.t3h.vn I Khái quát về hàm do người dùng định nghĩa I.1 Hàm do người dùng định nghĩa là gì? Hàm do người dùng định nghĩa (user definedfunctions - UDFs) là một đối tượng mới được bổ sung của phiên bản SQL Server 2000. Trước hết, bạn cần biết rằng UDFs mang đầy đủ các ý nghĩa và tính chất của một hàm như đa số các ngôn ngữ lập trình khác, có nghĩa là một UDFs là một chương trình con đảm trách một xử lý nào đó với đặc tính là sẽ nhận các tham số đầu vào và trả về một giá trị kết quả xử lý tính toán được dựa trên các tham số đầu vào đã nhận. Không chỉ UDFs mà tất cả các hàm nói chung (Các phiên bản SQL Server trước đây cung cấp các hàm được cài đặt sẵn như getdate(), object_name(),… ) có thể phân ra thành hai nhóm : hàm xác định (deterministic) và hàm không xác định (non-deterministic). Các hàm xác định sẽ luôn luôn trả về cùng giá trị nếu giá trị các tham số được cung cấp (truyền vào) là như nhau. Các hàm không xác định có thể tạo ra các kết quả khác biệt tại mỗi thời điểm chúng được gọi thực hiện, ngay cả khi giá trị các tham số được cung cấp vẫn không thay đổi. Trong một số tàiliệu bạn thấy có xuất hiện thuật ngữ “scalar functions – các hàm vô hướng” dùng để chỉ các hàm trả về một giá trị, tương phản với nó là các hàm trả về một table. Hàm getdate() là một ví dụ điển hình cho cả hai : hàm vô hướng (scalar) và hàm không xác định (non-deterministic). Nếu bạn gọi thực hiện nó hai lần với cùng một dòng lệnh gọi, bạn sẽ nhận được hai kết quả khác nhau và chỉ có duy nhất một giá trị cho mỗi lần gọi. Như chúng tôi đã trình bày, UDFs mang đầy đủ các tính chất của một hàm, ngoài ra, bạn cũng có thể hình dung UDFs là sự kết hợp của hai đối tượng View và Stored Procedure. Hơn thế nữa, nó còn có những tính năng sử dụng mà View và Stored Procedure không có được, hay nói cách khác nó khắc phục một số các hạn chế của View và Stored Procedure. Ví dụ : Stored Procedure không thể là một phần của câu lệnh SELECT nhưng UDFs , View không hỗ trợ sự đệ quy trong khi với UDFs thì bạn có thể làm được điều này. II Làm việc với UDFs Trong phần này chúng tôi sẽ hướng dẫn các bạn cách thức: Tạo UDFs . Thay đổi tên của UDFs và nội dung các câu lệnh chứa bên trong nó. Xem (view), xoá (drop) UDFs. II.1 Tạo mới UDFs Giống như các đối tượng khác trong Microsoft SQL Server mà chúng tôi đã trình bày trước đây ở các chương trước, các bạn có hai (2) cách để có thể tạo mới một UDFs: sử dụng các câu lệnh T-SQL hoặc dùng tiện ích Enterprise Manager. II.1.1 Sử dụng câu lệnh T-SQL Bạn có thể câu lệnh CREATE FUNCTION để tạo một UDFs bằng cách sử dụng tiện ích SQL Query Analyzer hoặc sử dụng công cụ dạng dấu nhắc lệnh (command-prompt) điển hình như công cụ osql. Cú pháp: CREATE FUNCTION [Tên_FUNCTION] (Khai báo các tham số ) RETURNS Kiểu_dữ Liệu_trả_về AS BEGIN -Các câu lệnh bên trong FUNCTION- RETURN END Mệnh đề CREATE FUNCTION Việc tạo UDFs bắt đầu với mệnh đề CREATE FUNCTION theo sau làtên của UDFs. Ngay sau tên của UDFs là phần khai báo các tham số của UDFs. Chú ý là các tham số phải tuân thủ quy tắc của một định danh và phải bắt đầu bằng ký hiệu @. Về nguyên tắc, một UDFs có thể không có tham số. Ví dụ : UDFs không có tham số CREATE FUNCTION [Test_Func] () Ví dụ : UDFs có tham số CREATE FUNCTION [Chuan_Ho_Ten] (@ChuoiHoTen varchar(50)) Mệnh đề RETURNS Dùng để thiết lập kiểu dữ liệu trả về của UDFs. Có hai cách thiết lập chính : Trả về giá trị kiểu vô hướng. Khi chỉ định kiểu này, UDFs sẽ trả về giá trị kết quả đơn lẻ như là: một chuỗi , một giá trị logic, hoặc một giá trị kiểu số. Trả về một table. Trên thực tế bạn có thể chỉ định trả về hai loại table: o inline table : Với loại này, bạn chỉ có thể thực hiện bên trong nó câu lệnh SELECT rõ ràng không quá phức tạp. UDFs loại này thực chất được dùng để thay thế cho các đối tượng VIEW, bởi nó khắc phục được nhược điểm không có tham số của VIEW. Bạn có thể hình dung một UDFs loại inline table giống như là một VIEW có tham số. Ví dụ : create view V_DSHangHoa as Select * from DM_HANG_HOA where MaLoai_HH='TiVi' go Ví dụ : Việc tạo view ở ví dụ trên thật khó làm cho ta thoả mãn bởi trong trường hợp ta muốn danh sách gồm các mặt hàng không phải là loại TiVi thì sao? Bạn cũng đã biết là VIEW không hỗ trợ tham số. Để giải quyết vấn đề này, bạn có thể tạo một UDFs với tham số cho phép truyền vào giá trị loại hàng hoá. CREATE FUNCTION F_DSHangHoa(@LoaiHH varchar(50)) RETURNS Table AS Return (Select * from DM_HANG_HOA where MaLoai_HH=@LoaiHH) Go Chú ý : Khi sử dụng UDFs loại inline table bạn cần quan tâm đến các quy tắc sau : Mệnh đề RETURNS chứa duy nhất từ khoá table. Bạn không phải định nghĩa kiểu của biến trả về, bởi vì nó là tập được định dạng bởi tập kết quả truy vấn của câu lệnh SELECT trong mệnh đề RETURN. Không có phần thân của hàm với việc bắt đầu bởi BEGIN và kết thúc bởi END. Mệnh đề RETURN chứa một câu lệnh SELECT đơn giản nằm trong cặp dấu ngoặc đơn. Câu lệnh SELECT được sử dụng trong hàm có các hạn chế giống như câu lệnh SELECT được sử dụng trong đối tượng VIEW. o Multistatement table : Khi bạn chỉ định kiểu này, UDFs trở nên rất giống các Stored Procedure. Nó cho phép thực hiện các câu lệnh SELECT phức tạp, hơn nữa nó còn cho phép thực hiện các câu lệnh logic khác như UPDATE, INSERT INTO,… Đồng thời bạn có thể thiết lập cấu trúc trong cặp dấu ngoặc đơn ngay sau câu lệnh RETURNS. Loại này sẽ luôn trả về một biến table (chỉ duy nhất một biến table). Ví dụ : CREATE FUNCTION F_DSHangHoa(@LoaiHH varchar(50),@PhanTram numeric) RETURNS @DSHangHoa Table ( Ma_HH varchar(50), Ten_HH varchar(50), DonGiaKhuyenMai numeric ) AS Begin Insert Into @DSHangHoa(Ma_HH,Ten_HH,DonGiaKhuyenMai) Select ID_HH,Ten_HH,DonGiaHienHanh from DM_HANG_HOA where IDLoai_HH=@LoaiHH Update @DSHangHoa Set DonGiaKhuyenMai=DonGiaKhuyenMai- (DonGiaKhuyenMai*@PhanTram)/100 Return End Chú ý : Khisử dụng UDFs loại Multistatement table bạn cần quan tâm đến các hạn chế sau : Không thể gọi một stored procedure từ các câu lệnh bên trong nó. Không thể sử dụng các hàm loại không xác định được xây dựng sẵn trong SQL Server, ví dụ: Getdate, Rand, … Việc sử dụng RAISERROR và @@ERROR là hoàn toàn không hợp lệ. UDFs không thể được sử dụng để sửa đổi thông tin trên table cơ sở. Mệnh đề AS Mệnh AS được khai báo trước các câu lệnh bên trong UDFs. Khối lệnh BEGIN … END Phần thân của UDFs được bắt đầu sau từ khoá BEGIN và kết thúc bởi từ khóa END. Chú ý rằng khối lệnh này không sử dụng cho trường hợp UDFs loại inline table. . User Defined Functions - UDFs Nguồn : forum.t3h.vn I Khái quát về hàm do người dùng. I.1 Hàm do người dùng định nghĩa là gì? Hàm do người dùng định nghĩa (user defined functions - UDFs) là một đối tượng mới được bổ sung của phiên bản SQL