Sử dụng một biến bảng hoặc một bảng tạm thời.
Như đã đề cập trước đây, một con trỏ là phương sách cuối cùng. Chủ yếu là vì nó sử dụng nhiều tài nguyên, các vấn đề khóa và có thể là một dấu hiệu bạn không hiểu cách sử dụng SQL đúng cách.
Lưu ý bên lề: Tôi đã từng gặp một giải pháp sử dụng con trỏ để cập nhật các hàng trong bảng. Sau khi xem xét kỹ lưỡng, hóa ra toàn bộ điều có thể được thay thế bằng một lệnh CẬP NHẬT duy nhất. Tuy nhiên, trong trường hợp này, khi một thủ tục được lưu trữ sẽ được thực thi, một lệnh SQL sẽ không hoạt động.
Tạo một biến bảng như thế này (nếu bạn đang làm việc với nhiều dữ liệu hoặc thiếu bộ nhớ, thay vào đó hãy sử dụng bảng tạm thời ):
DECLARE @menus AS TABLE (
id INT IDENTITY(1,1),
parent NVARCHAR(128),
child NVARCHAR(128));
Điều id
quan trọng.
Thay thế parent
và child
bằng một số dữ liệu tốt, ví dụ: số nhận dạng có liên quan hoặc toàn bộ bộ dữ liệu sẽ được vận hành.
Chèn dữ liệu vào bảng, vd:
INSERT INTO @menus (parent, child)
VALUES ('Some name', 'Child name');
...
INSERT INTO @menus (parent,child)
VALUES ('Some other name', 'Some other child name');
Khai báo một số biến:
DECLARE @id INT = 1;
DECLARE @parentName NVARCHAR(128);
DECLARE @childName NVARCHAR(128);
Và cuối cùng, tạo một vòng lặp while trên dữ liệu trong bảng:
WHILE @id IS NOT NULL
BEGIN
SELECT @parentName = parent,
@childName = child
FROM @menus WHERE id = @id;
EXEC myProcedure @parent=@parentName, @child=@childName;
SELECT @id = MIN(id) FROM @menus WHERE id > @id;
END
Lựa chọn đầu tiên lấy dữ liệu từ bảng tạm thời. Lựa chọn thứ hai cập nhật @id. MIN
trả về null nếu không có hàng nào được chọn.
Một cách tiếp cận khác là lặp trong khi bảng có các hàng SELECT TOP 1
và xóa hàng đã chọn khỏi bảng tạm thời:
WHILE EXISTS(SELECT 1 FROM @menuIDs)
BEGIN
SELECT TOP 1 @menuID = menuID FROM @menuIDs;
EXEC myProcedure @menuID=@menuID;
DELETE FROM @menuIDs WHERE menuID = @menuID;
END;