ใช้ตัวแปรตารางหรือตารางชั่วคราว
ดังที่ได้กล่าวมาแล้วเคอร์เซอร์เป็นทางเลือกสุดท้าย ส่วนใหญ่เป็นเพราะใช้ทรัพยากรจำนวนมากปัญหาในการล็อคและอาจเป็นสัญญาณว่าคุณไม่เข้าใจวิธีการใช้ SQL อย่างถูกต้อง
หมายเหตุด้านข้าง: ฉันเคยเจอโซลูชันที่ใช้เคอร์เซอร์เพื่ออัปเดตแถวในตาราง หลังจากการตรวจสอบข้อเท็จจริงบางอย่างปรากฎว่าสิ่งทั้งหมดสามารถถูกแทนที่ด้วยคำสั่ง UPDATE เดียว อย่างไรก็ตามในกรณีนี้ควรดำเนินการขั้นตอนการจัดเก็บคำสั่ง SQL เดียวจะไม่ทำงาน
สร้างตัวแปรตารางเช่นนี้ (หากคุณกำลังทำงานกับข้อมูลจำนวนมากหรือมีหน่วยความจำไม่เพียงพอให้ใช้ตารางชั่วคราวแทน):
DECLARE @menus AS TABLE (
id INT IDENTITY(1,1),
parent NVARCHAR(128),
child NVARCHAR(128));
id
เป็นสิ่งสำคัญ
แทนที่parent
และchild
มีข้อมูลที่ดีเช่นตัวระบุที่เกี่ยวข้องหรือชุดข้อมูลทั้งหมดที่จะดำเนินการ
แทรกข้อมูลในตารางเช่น:
INSERT INTO @menus (parent, child)
VALUES ('Some name', 'Child name');
...
INSERT INTO @menus (parent,child)
VALUES ('Some other name', 'Some other child name');
ประกาศตัวแปรบางตัว:
DECLARE @id INT = 1;
DECLARE @parentName NVARCHAR(128);
DECLARE @childName NVARCHAR(128);
และสุดท้ายสร้างวงในขณะที่ข้อมูลในตาราง:
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
การเลือกแรกจะดึงข้อมูลจากตารางชั่วคราว ตัวเลือกที่สองจะอัพเดต @id MIN
ส่งคืนค่า null ถ้าไม่มีการเลือกแถว
อีกทางเลือกหนึ่งคือการวนซ้ำในขณะที่ตารางมีแถวSELECT TOP 1
และลบแถวที่เลือกออกจากตารางชั่วคราว:
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;