एक क्वेरी स्ट्रिंग के लिए परिवर्तनीय घोषित करें


92

मैं सोच रहा था कि एमएस SQL ​​सर्वर 2005 में ऐसा करने का कोई तरीका था:

  DECLARE @theDate varchar(60)
  SET @theDate = '''2010-01-01'' AND ''2010-08-31 23:59:59'''

  SELECT    AdministratorCode, 
            SUM(Total) as theTotal, 
            SUM(WOD.Quantity) as theQty, 
            AVG(Total) as avgTotal, 
            (SELECT SUM(tblWOD.Amount)
                FROM tblWOD
                JOIN tblWO on tblWOD.OrderID = tblWO.ID
                WHERE tblWO.Approved = '1' 
                AND tblWO.AdministratorCode = tblWO.AdministratorCode
                AND tblWO.OrderDate BETWEEN @theDate
            )
 ... etc

क्या ऐसा करना संभव है?


जवाबों:


96

यह संभव है, लेकिन इसे गतिशील एसक्यूएल का उपयोग करने की आवश्यकता है।
मैं जारी रखने से पहले गतिशील SQL के शाप और आशीर्वाद पढ़ने की सलाह देता हूं ...

DECLARE @theDate varchar(60)
SET @theDate = '''2010-01-01'' AND ''2010-08-31 23:59:59'''

DECLARE @SQL VARCHAR(MAX)  
SET @SQL = 'SELECT AdministratorCode, 
                   SUM(Total) as theTotal, 
                   SUM(WOD.Quantity) as theQty, 
                   AVG(Total) as avgTotal, 
                  (SELECT SUM(tblWOD.Amount)
                     FROM tblWOD
                     JOIN tblWO on tblWOD.OrderID = tblWO.ID
                    WHERE tblWO.Approved = ''1''
                      AND tblWO.AdministratorCode = tblWO.AdministratorCode
                      AND tblWO.OrderDate BETWEEN '+ @theDate +')'

EXEC(@SQL)

डायनामिक एसक्यूएल एक एसक्यूएल स्टेटमेंट है, जिसे निष्पादित होने से पहले एक स्ट्रिंग के रूप में बनाया गया है। तो सामान्य स्ट्रिंग संघनन होता है। जब भी आप SQL सिंटैक्स में कुछ करना चाहते हैं, तो डायनेमिक SQL की आवश्यकता होती है, जैसे:

  • एक खंड में अल्पविराम से अलग सूची के मानों का प्रतिनिधित्व करने के लिए एक एकल पैरामीटर
  • मूल्य और एसक्यूएल सिंटैक्स दोनों का प्रतिनिधित्व करने के लिए एक चर (आईई: आपके द्वारा प्रदान किया गया उदाहरण)

EXEC sp_executesql आपको बाइंड / तैयार किए गए पैरामीटर का उपयोग करने की अनुमति देता है ताकि आपको SQL इंजेक्शन हमलों के लिए एकल उद्धरण / आदि से बचने के साथ खुद को परेशान न करना पड़े।


मुझे लगता है कि यह सबसे सही उत्तर है। मैं हाल ही में एसक्यूएल सर्वर 2005 का उपयोग कर रहा हूं, और ओपी की तरह क्वेरी स्ट्रिंग प्रतिस्थापन के लिए एक चर का उपयोग करना संभव नहीं है (सिंटैक्स त्रुटियों को उत्पन्न करता है)। वैरिएबल में वाक्य रचना और डेटा दोनों प्रकार शामिल नहीं हो सकते, जैसा कि @Ponies कहते हैं। डायनेमिक SQL स्ट्रिंग्स के माध्यम से SQL सर्वर में क्वेरीज़ के निर्माण के लिए जाने का तरीका है। बस अपने उद्धरण और प्रकारों के बारे में सावधान रहना याद रखें! आपके द्वारा निष्पादित स्ट्रिंग को कुछ प्रकार की आवश्यकता होती है, जैसे डेटाइम या इंट, स्ट्रिंग को बदलने के लिए परिवर्तित या कास्ट करना।
RoboBear

52
DECLARE @theDate DATETIME
SET @theDate = '2010-01-01'

फिर इस तर्क का उपयोग करने के लिए अपनी क्वेरी बदलें:

AND 
(
    tblWO.OrderDate > DATEADD(MILLISECOND, -1, @theDate) 
    AND tblWO.OrderDate < DATEADD(DAY, 1, @theDate)
)

2
डटे रहो। यदि प्रश्न स्पष्ट रूप से दो अलग-अलग तिथियों को दिखाता है तो इसका उत्तर नहीं हो सकता है। आपने इसे आख़िर @StealthRT में कैसे कोड किया? उत्तर में '2010-08-31' तारीख कहाँ है? साथ ही, यह प्रश्न स्पष्ट रूप से पूछता है कि क्या आप कोड को दूसरे सेलेक्ट स्टेटमेंट में स्थानापन्न करने के लिए DECLARE वैरिएबल का उपयोग कर सकते हैं। उचित उत्तर नीचे है।
Fandango68

2

EXEC का उपयोग करना

SQL कथन बनाने के लिए आप निम्न उदाहरण का उपयोग कर सकते हैं।

DECLARE @sqlCommand varchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = '''London'''
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = ' + @city
EXEC (@sqlCommand)

Sp_executesql का उपयोग करना

इस दृष्टिकोण का उपयोग करके आप यह सुनिश्चित कर सकते हैं कि क्वेरी में पारित किए जा रहे डेटा मान सही डेटाटाइप और अधिक उद्धरणों के एवॉइंड उपयोग हैं।

DECLARE @sqlCommand nvarchar(1000)
DECLARE @columnList varchar(75)
DECLARE @city varchar(75)
SET @columnList = 'CustomerID, ContactName, City'
SET @city = 'London'
SET @sqlCommand = 'SELECT ' + @columnList + ' FROM customers WHERE City = @city'
EXECUTE sp_executesql @sqlCommand, N'@city nvarchar(75)', @city = @city

संदर्भ


1

मैं इंगित करूंगा कि शीर्ष रेटेड उत्तर में लिंक किए गए लेख में डायनेमिक एसक्यूएल के अभिशाप और आशीर्वाद लेखक ने कहा है कि उत्तर गतिशील एसक्यूएल का उपयोग नहीं करना है। इसे देखने के लिए लगभग अंत तक स्क्रॉल करें।

लेख से: "उपयोगकर्ता-परिभाषित फ़ंक्शन या संग्रहीत प्रक्रिया के साथ सूची में तालिका को अनपैक करने के लिए सही विधि है।"

बेशक, एक बार सूची एक तालिका में होने के बाद आप एक जॉइन का उपयोग कर सकते हैं। मैं सीधे टॉप रेटेड उत्तर पर टिप्पणी नहीं कर सकता था, इसलिए मैंने इस टिप्पणी को जोड़ा।


यह प्रश्न का उत्तर प्रदान नहीं करता है। एक बार आपके पास पर्याप्त प्रतिष्ठा होने पर आप किसी भी पोस्ट पर टिप्पणी कर पाएंगे ; इसके बजाय, ऐसे उत्तर प्रदान करें जिन्हें पूछने वाले से स्पष्टीकरण की आवश्यकता न हो । - समीक्षा से
सैम एम

धन्यवाद सैम। एक बार मैं Erland Sommarskog क्या सुझाव देता हूं, इसे लागू करने के साथ मैं अपनी टिप्पणी को अपडेट कर दूंगा। जवाब के लिए श्रेय के हकदार होने के बाद से मैं उसका नाम भी बताऊंगा।
डेविड जेएन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.