Khi sử dụng hàm kiểu bảng, một câu hỏi đặt ra là làm thế nào để truyền tham số động cho hàm, trong đó tham số là giá trị của một cột trong bảng? Tình huống này xảy ra khi bạn truy vấn dữ liệu từ một bảng, với mỗi bản ghi bạn cần gọi hàm và tham số được truyền từ một hoặc vài trường nào đó của bản ghi tương ứng. Rõ ràng tham số truyền cho hàm không cố định, mà thay đổi tại mỗi bản ghi.
Ví dụ, tôi lấy hàm đã được đề cập trong bài Hàm Kiểu Bảng, hàm dbo.fnCSVStr2Table để chuyển đổi một chuỗi ký tự phân cách bằng dấu phẩy thành bảng. Nay tôi muốn áp dụng hàm này lên bảng về các model ô tô sau:
CREATE TABLE dbo.Car(Maker VARCHAR(20), ModelList VARCHAR(1000))
INSERT INTO dbo.Car(Maker, ModelList)
VALUES(''TOYOTA'', ''Camry,HighLander,Takoma,Prius,Corolla''),
(''HONDA'', ''Civic,Accord,CR-V''),
(''FORD'', ''Escape,Everest,Fusion,Edge'')
SELECT * FROM dbo.Car
Và mong muốn đầu ra như sau:
Vậy phải làm như thế nào? Cách trực quan nhất có lẽ là dùng một con trỏ (cursor) chạy qua bảng, ở mỗi vòng lặp gọi đến hàm và INSERT kết quả của hàm vào một bảng tạm; đến cuối cùng thì SELECT từ bảng tạm để trả về. Cách làm này chắc hẳn không thể tối ưu. SQL Server cung cấp toán tử APPLY để sử dụng trong trường hợp này:
SELECT c.Maker, b.ValueColumn AS Model
FROM dbo.Car c
CROSS APPLY dbo.fnCSVStr2Table(c.ModelList) b
Cơ chế hoạt động của APPLY tương tự như đoạn mô tả dùng con trỏ ở trên: SELECT từ bảng chính, với mỗi bản ghi gọi đến hàm lấy kết quả ghép chung vào kết quả trả về. Tuy nhiên cơ chế này hoàn toàn dựa vào tập (set-based) nên nhẹ nhàng hơn rất nhiều so với con trỏ. Bạn có thể hình dung APPLY với hàm tương tự như JOIN với bảng: liên kết với bảng thì dùng JOIN, liên kết với hàm thì dùng APPLY. Ở ví dụ trên tôi dùng CROSS APPLY, cư xử của nó giống như INNER JOIN. Khi cần tương tự như OUTER JOIN, bạn dùng OUTER APPLY.