2014-12-19 7 views
6

मैं एक प्रश्न है कि पढ़ता से लौटे स्ट्रिंग है:Sql सर्वर धुरी क्वेरी में चर का उपयोग कर

+----------------------+  
| returnquerystring | 
+----------------------+ 
| exam1,exam2,exam3 | 
+----------------------+ 

मैं उपयोग कर रहा हूँ इस एक धुरी क्वेरी में स्तंभ नाम के रूप में स्ट्रिंग लौट आए।

select * from (select score,exam from table1) x 
pivot (max(score) for exam in (exam1,exam2,exam3) 

इस क्वेरी मुझे

+-------------+-----------+-----------+ 
| exam1 | exam2 | exam3 | 
+-------------+-----------+-----------+ 
|  10  |  20 |  30 | 
+-------------+-----------+-----------+ 

दे रही है हालांकि मैं नहीं किया है बयान कुछ भी लेकिन exam1, exam2, exam3 की कड़ी कोडित मूल्यों का उपयोग करने के लिए "में" धुरी प्राप्त करने में सक्षम हो गया काम करता है। उदाहरण के लिए मैंने एसएसएमएस का उपयोग किया है और एक क्वेरी बनाई है जो सफलतापूर्वक परीक्षा 1, परीक्षा 2, परीक्षा 3 को @ var1 में रखती है। हालांकि परीक्षा 1, परीक्षा 2, परीक्षा 3 के स्थान पर उपयोग किए जाने पर @ var1 फेंकता और त्रुटि होगी।

declare @var1 varchar(100) 
select @var1 = value from table 
select * from (select score,exam from table1) x 
pivot (max(score) for exam in (@var1) 

Incorrect syntax near '@var1'. 

यह सत्यापित करने के लिए कि मैं इसे सही तरीके से कर रहा हूं मैंने यह किया और यह काम किया।

declare @var1 int 
select top 1 @var1 = id from name 
select * from name where id = @var1 

यह कोई त्रुटि के साथ नाम की मेज पर आईडी 1 के लिए डेटा पंक्ति प्रदान की है।

मैंने अपने प्रयोगों में देखा है कि (परीक्षा 1, परीक्षा 2, परीक्षा 3) उद्धरण के साथ (परीक्षा 1, परीक्षा 2, परीक्षा 3 ') नहीं हो सकता है।

मैं कोल्डफ्यूजन CFSCRIPT का उपयोग कर रहा हूं और ऐसा लगता है कि एकल उद्धरण क्वेरी में शामिल हो रहे हैं इसलिए मैंने बिना किसी सफलता के उन्हें हटाने के लिए कोल्डफ्यूजन फ़ंक्शंस के साथ विभिन्न परीक्षणों की कोशिश की।

तो मैंने @ var1 के आस-पास SQL ​​सर्वर फ़ंक्शन 'प्रतिस्थापन' का उपयोग करने का प्रयास किया और यह प्रतिस्थापन पर वाक्यविन्यास के बारे में एक त्रुटि फेंकता है।

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

मैं एसक्यूएल सर्वर 8 और SSMS 11.

यह कैसे काम करने के लिए पर कोई भी विचार का उपयोग कर रहा हूँ?

examColumns = exam1,exam2,exam3 

public any function qryExamScores(string examColumns) { 
    thisQry = new Query(); 
    thisQry.setName("returnqry"); 
    thisQry.setDatasource(application.datasource); 
thisQry.addParam(name="columnNames",value=arguments.examColumns,cfsqltype="cf_sql_varchar"); 
    result = thisQry.execute(sql=" 
     select * from 
     (select id,score,exam 
     from table 
     where value1 = 'XXXXX' 
     and value2 = '11111') x 
     pivot 
     (
      max(score) for exam in (:columnNames) 
     ) p 

    "); 
    returnqry = result.getResult(); 
    return returnqry; 
} 
+1

FYI करें - अगर आप एकल उद्धरण की जरूरत है प्रदान किया जाने वाला "जैसा है" ColdFusion से आप समारोह 'preservesinglequotes()' का उपयोग करने की आवश्यकता होगी - अन्यथा सीएफ helpully संभालने वे के लिए एक चरित्र चर का हिस्सा हैं एकल उद्धरण निकल जाता है डालें या अपडेट करें। –

+0

मेरा मानना ​​है कि गतिशील एसक्यूएल की आवश्यकता होगी; हालांकि तालिका में केवल एक पंक्ति होती है? आपके सत्यापन में आपने शीर्ष 1 किया था, लेकिन आपके चयन में आपने नहीं किया था। मुझे लगता है कि कई पंक्तियां वापस आ सकती हैं और "इन" इसे संभाल नहीं सकती है। – xQbert

+0

मार्क यह प्रतीत होता है कि कोल्डफ्यूजन एकल उद्धरण डाल रहा है और मैं उन्हें नहीं चाहता हूं। यह सीएफएससीआरआईपीटी है इसलिए मैं परीक्षा 1, परीक्षा 2, परीक्षा 3 को एक परम वर्कर के रूप में पास कर रहा हूं: parametervalue। मुझे एक त्रुटि मिलती है जो प्रतीत होता है कि उद्धरण हैं लेकिन जब मैं फ़ंक्शन में आने वाली स्ट्रिंग आउटपुट करता हूं तो कोई नहीं होता है। यदि आपके पास कोल्डफ्यूजन का उपयोग करने का कोई तरीका है तो मैं सभी कान हूं। – dutchlab

उत्तर

3

आप Dynamic SQL उपयोग करने के लिए अंदर Pivot

declare @var1 varchar(100)='',@sql nvarchar(max) 
select top 1 @var1 = value from table 

set @sql = 'select * from (select score,exam from table1) x 
pivot (max(score) for exam in (['[email protected]+'])) piv' 

exec sp_executesql @sql 

चर (@ var1) के मूल्य का उपयोग करने के लिए आप धुरी कॉलम इस का उपयोग में एक से अधिक मूल्य करना चाहते हैं की जरूरत है।

SELECT @var1 += '[' + Isnull(CONVERT(VARCHAR(50), value), '') + '],' 
FROM table 

SELECT @var1 = LEFT(@var1, Len(@var) - 1) 

SET @sql = 'select * from (select score,exam from table1) x 
      pivot (max(score) for exam in (' + @var1 + ')) piv' 

EXEC Sp_executesql @sql 
2

के रूप में एक परम varchar के रूप में exam1, exam2, exam3 गुजर: parametervalue

Queryparam (या चर बाँध) केवल शाब्दिक पर इस्तेमाल किया जा सकता है। चूंकि "परीक्षा 1, परीक्षा 2, परीक्षा 3" का उपयोग इस विशिष्ट क्वेरी में कॉलम नाम के रूप में किया जा रहा है, इसलिए आप उन्हें क्वेरीपरम लागू नहीं कर सकते हैं। जब आप ऐसा करते हैं, तो आप डेटाबेस को बता रहे हैं कि वे मान सरल तार हैं। इससे त्रुटि उत्पन्न होती है क्योंकि pivot ऑब्जेक्ट नामों की अपेक्षा करता है, स्ट्रिंग नहीं।

क्वेरीपरम को हटाएं और क्वेरी अपेक्षित के रूप में काम करेगी।हालांकि, जाहिर है कि एसक्यूएल इंजेक्शन में आपके डेटाबेस का खुलासा हो सकता है (columnNames के स्रोत के आधार पर)। यह किसी भी गतिशील एसक्यूएल (exec, sp_executesql, ...) का उपयोग करने पर लागू होता है। इसलिए इस दृष्टिकोण को लागू करने से पहले इनपुट को पूरी तरह से सत्यापित करना सुनिश्चित करें।

... 
// build pivot statement with dynamic column names 
columnNames = "exam1,exam2,exam3"; 
sqlString = "SELECT * 
      FROM (
        SELECT score,exam 
        FROM table1 
       ) x 
      PIVOT 
      ( 
       MAX(score) FOR exam IN ("& columnNames &") 
      ) 
      AS pvt "; 
result = qry.execute(sql=sqlString).getResult(); 
writeDump(result); 

संपादित करें:

इसके अलावा, आप शायद कोष्ठक में स्तंभ नाम संलग्न वाक्यविन्यास त्रुटियों से बचने के लिए यदि मान रिक्त स्थान, या स्तंभ नाम के लिए अन्य अमान्य वर्ण शामिल करना चाहिए।

"[exam1],[exam2],[exam3]"; 
+0

लेघ, जानकारी के लिए धन्यवाद। मुझे संदेह था कि क्वेरीपरम मुद्दा था और इसे हटाने के बिना इसे चारों ओर दूर करना चाहता था। मैंने सफलतापूर्वक गतिशील एसक्यूएल विधि का उपयोग किया है और पूरी तरह से एक क्वेरी के रूप में पारित किया है। मैं यह देखने के लिए समीक्षा करूंगा कि सुरक्षा जोखिम से कम कौन सा कारण बनता है। तो अब इस पोस्ट के लिए केवल एक सही जवाब चुनने की दुविधा। डेटाबेस में संग्रहीत प्रक्रिया बनाने के लिए एक स्पष्ट समाधान है, लेकिन जब आप डेटाबेस के लिए कुंजी के बिना ठेकेदार होते हैं तो आपको आसपास के काम मिलना पड़ता है। – dutchlab

+0

(संपादित करें) ठीक है, एक संग्रहित प्रो अभी भी जोखिम होगी क्योंकि इसे भी गतिशील एसक्यूएल की आवश्यकता होगी। दुर्भाग्य से, मुझे नहीं लगता कि आप किसी भी विधि के साथ 'पिवट' को "पैरामीटर" कर सकते हैं। तो यह छः दर्जनों में से एक छः दर्जन हो सकता है। स्पष्ट रूप से, गतिशील एसक्यूएल हमेशा जोखिम भरा होता है। तो अंधेरे से किसी भी एसक्यूएल स्ट्रिंग के निष्पादन की अनुमति न दें, और * * बहुत * :) बीटीडब्ल्यू को सत्यापित करना सुनिश्चित करें, दूसरा उत्तर पूरी तरह मान्य है। इसलिए जो भी उत्तर यहां सबसे अच्छा अनुकूल है उसे चुनने के लिए स्वतंत्र महसूस करें। मैं केवल सीएफ परिप्रेक्ष्य से अभिलेखागार में एक स्पष्टीकरण जोड़ना चाहता था। – Leigh

संबंधित मुद्दे