डायनेमिक SQL - EXEC (@SQL) बनाम EXEC SP_EXECUTESQL (@SQL)


95

SQL सर्वर का उपयोग करके संग्रहीत कार्यविधि में डायनेमिक SQL कमांड को निष्पादित करने के वास्तविक दुनिया के नियम और विपक्ष क्या हैं

EXEC (@SQL)

बनाम

EXEC SP_EXECUTESQL @SQL

?

जवाबों:


96

sp_executesqlक्वेरी योजना के पुन: उपयोग को बढ़ावा देने की अधिक संभावना है। उपयोग करते समय sp_executesql, कॉलिंग हस्ताक्षर में मापदंडों को स्पष्ट रूप से पहचाना जाता है। यह उत्कृष्ट लेख इस प्रक्रिया को बताता है

डायनामिक sql के कई पहलुओं के लिए thet उद्धृत संदर्भ Erland Sommarskog का अवश्य पढ़ा जाना चाहिए: " गतिशील SQL का अभिशाप और आशीर्वाद "।


21

SP_EXECUTESQL के बारे में बड़ी बात यह है कि यह आपको पैरामीटरयुक्त प्रश्न बनाने की अनुमति देता है जो SQL इंजेक्शन के बारे में परवाह है तो बहुत अच्छा है।


1
मुझे नहीं लगता कि आप इसके बिना एक गतिशील एसक्यूएल को छोटा कर सकते हैं ??
डीजे।

EXEC ('का चयन * FOO WHERE ID =?' से, 123) पैरामीटर प्लेसहोल्डर की जगह लेगा ""? 123 के मान के साथ और फिर क्वेरी निष्पादित करें, FOO FOO WHERE ID = 123 के लिए चयन का परिणाम लौटाएं
पीटर वॉन

1
ओह, वह सिंटैक्स केवल लिंक किए गए सर्वर के लिए उपलब्ध है।
पीटर

1
यदि sql इंजेक्शन को रोकने के लिए गतिशील रूप से क्वेरी का निर्माण किया जाए तो sp_executesql का उपयोग करने का सबसे बड़ा कारण है।
स्टीवन रोजर्स

5

Microsoft का उपयोग sp_executesql आलेख कथन के sp_executesqlबजाय का उपयोग करने की अनुशंसा करता है execute

क्योंकि यह संग्रहीत कार्यविधि पैरामीटर प्रतिस्थापन का समर्थन करती है , इसलिए sp_executesql EXECUTE से अधिक बहुमुखी है; और क्योंकि sp_executesql SQL सर्वर द्वारा पुन: उपयोग किए जाने की अधिक संभावना वाले निष्पादन योजनाएं बनाता है, तो sp_executesql EXECUTE की तुलना में अधिक कुशल है।

तो, दूर ले: बयान का उपयोग न करेंexecute । का उपयोग करें sp_executesql


7
आपका टेकअवे हमेशा नहीं खड़ा होता है। ऐसे अवसर होते हैं जब sp_executesql का उपयोग करके कोई दक्षता बोनस नहीं होता है, लेकिन आप अपने कोड को sql इंजेक्शन हमले से बचा सकते हैं। कभी-कभी आप बस sp_executesql का उपयोग नहीं कर सकते हैं जिस तरह से आप निष्पादन का उपयोग कर सकते हैं, तो ... किसी ने कहा - कोई चांदी की गोली नहीं है। मैं सहमत हूँ।
OzrenTkalcecKrznaric

हाँ, Microsoft को इसे "अधिक कुशल होने की संभावना " के रूप में रखना चाहिए । और कुछ वर्षों से उद्योग में होने के कारण, मैंने ऐसे मामले देखे हैं, जिनका sp_executesqlउपयोग करने के लिए उपयोग नहीं किया जा सकता है execute। शायद मुझे उस बिंदु को रखना चाहिए जिस पर मैं जोर देने की कोशिश कर रहा हूं: जब भी संभव हो,sp_executesql इसके बजाय का उपयोग करें । execute
गण

2

मैं हमेशा इन दिनों sp_executesql का उपयोग करता हूं, यह वास्तव में EXEC के लिए एक आवरण है जो मापदंडों और चर को संभालता है।

हालांकि बहुत बड़े डेटाबेस पर प्रश्नों को ट्यून करते समय OPTION RECOMPILE के बारे में मत भूलना, विशेष रूप से जहां आपके पास एक से अधिक डेटाबेस पर डेटा स्पेंड किया गया है और इंडेक्स स्कैन को सीमित करने के लिए एक CONSTRAINT का उपयोग कर रहे हैं।

जब तक आप विकल्प युक्ति का उपयोग करते हैं, तब तक SQL सर्वर आपकी क्वेरी के लिए "एक आकार सभी फिट बैठता है" निष्पादन योजना बनाने का प्रयास करेगा, और प्रत्येक बार चलने पर एक पूर्ण अनुक्रमणिका स्कैन चलाएगा।

यह एक खोज की तुलना में बहुत कम कुशल है, और इसका मतलब है कि यह संभावित रूप से पूरे सूचकांक को स्कैन कर रहा है जो कि सीमाओं के लिए विवश हैं जिन्हें आप क्वेरी भी नहीं कर रहे हैं: @


-2
  1. परिवर्तनशील घोषित करें
  2. इसे अपने कमांड द्वारा सेट करें और sp के उपयोग के मान जैसे डायनामिक पार्ट्स जोड़ें (यहाँ @IsMonday और @IsTuesday sp sp params हैं)
  3. आज्ञा का पालन करें

    declare  @sql varchar (100)
    set @sql ='select * from #td1'
    
    if (@IsMonday+@IsTuesday !='')
    begin
    set @sql= @sql+' where PickupDay in ('''+@IsMonday+''','''+@IsTuesday+''' )'
    end
    exec( @sql)

15
यह SQL इंजेक्शन के लिए खुला है, यदि आप "a '; DROP DATABASE DATABASE; GO।?"; " @IsMonday वैरिएबल में
एरिक ए। ब्रैंडस्टैडमेन

यदि @IMonday int है तो क्या यह sql चोट के कारण है?
विकास राणा

@VikasRana @IsMonday intगतिशील SQL में नहीं हो सकता । ध्यान दें कि @sql के रूप में घोषित किया जाता है varcharयाnvarchar
Weihui गुओ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.