एक टेबल चर या एक अस्थायी तालिका का उपयोग करें।
जैसा कि पहले उल्लेख किया गया है, एक कर्सर एक अंतिम उपाय है। ज्यादातर इसलिए कि यह बहुत सारे संसाधनों, मुद्दों के ताले का उपयोग करता है और एक संकेत हो सकता है कि आप समझ नहीं पा रहे हैं कि एसक्यूएल का सही उपयोग कैसे करें।
साइड नोट: मैं एक बार एक समाधान में आया था जो एक तालिका में पंक्तियों को अपडेट करने के लिए कर्सर का उपयोग करता था। कुछ जांच के बाद, यह पूरी बात एक एकल आदेश के साथ प्रतिस्थापित किया जा सकता है। हालाँकि, इस स्थिति में, जहाँ एक संग्रहीत कार्यविधि निष्पादित की जानी चाहिए, एक एकल 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यदि कोई पंक्तियों का चयन नहीं किया गया है तो अशक्त है।
एक वैकल्पिक दृष्टिकोण लूप है जबकि तालिका में पंक्तियाँ हैं, 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;