2011-07-29 10 views
6

चलो हम कहते हैं कि मैं इस तरह एक प्रश्न है:क्या स्ट्रिंग के रूप में टेबल नाम निर्दिष्ट करने का कोई तरीका है?

SELECT * FROM 
(
    SELECT * FROM 
    (
    SELECT * FROM DB.dbo.Table 
) 
    INNER JOIN DB.dbo.Table ON ... 

मैं मैन्युअल स्ट्रिंग हर जगह बदल कर इस क्वेरी चला रहा हूँ अलग तालिकाओं के साथ कई बार। मैं घोषित करने की कोशिश की है:

DECLARE @tablename AS VARCHAR(255) 
SET @tablename = 'DB.dbo.Table' 

लेकिन इस रूप में यह मुझे कह रही है कि मैं एक मेज चर के रूप में @tablename घोषित करने के लिए इससे पहले कि मैं उपयोग कर सकते हैं की जरूरत है एक त्रुटि फेंकता है काम करने के लिए प्रतीत नहीं होता। मैं अपने टेबल नाम को templatize कैसे कर सकता हूं और यदि यह संभव है, तो इंटेलिसेंस अभी भी काम करेगा?

उत्तर

7

आप इस तरह की एक EXEC बयान में लपेट कर सकते हैं:

declare @my_tablename nvarchar(100) = 'mytable'; 
exec(' 
SELECT * FROM 
(
    SELECT * FROM 
    (
    SELECT * FROM ' + @my_tablename + ' 
) 
    INNER JOIN ' + @my_tablename + ' ON ...' 
); 

लेकिन नहीं, IntelliSense कि परिदृश्य में काम नहीं करेगा।

यदि आप जानते हैं कि आपका आउटपुट अग्रिम जैसा दिखता है, तो आप परिणाम रखने के लिए एक temp तालिका घोषित कर सकते हैं, और फिर आप EXEC के बिना उस तक पहुंच सकते हैं। आप temp टेबल पर intellisense होगा।

उदाहरण के लिए:

--this must match whatever your SELECT is going to return 
    CREATE TABLE #results(
    FIELD1 INT 
    ,FIELD2 NVARCHAR(100) 
    ,FIELD3 BIT 
    ); 

EXEC(' 
    INSERT INTO #results(field1,field2,field3) 
    SELECT FIELD1,FIELD2,FIELD3 FROM ' + @my_tablename 
); 

select * from #results --you will have intellisense on #results 
3

आप गतिशील एसक्यूएल का उपयोग करें। सुनिश्चित नहीं हैं कि तुम क्यों इतने सारे नेस्टेड का चयन करता है की जरूरत है, लेकिन यह होगा कुछ की तरह:

DECLARE @sql NVARCHAR(MAX) = N'SELECT ... FROM ' + @tablename + '...'; 
EXEC sp_executeSQL @sql; 

हालांकि एसक्यूएल इंजेक्शन के लिए सचेत रहें। और नहीं, IntelliSense में ऑब्जेक्ट नामों के लिए स्ट्रिंग को पार्स करने की कोई क्षमता नहीं है (या यहां तक ​​कि यह जानने के लिए कि ऑब्जेक्ट का नाम क्या होगा) संपादित करने के लिए।

+0

+1। निर्भरता इंजेक्शन का उल्लेख करने के लिए धन्यवाद। लिंक के लिए –

4

नहीं। जैसा कि आप स्ट्रिंग के रूप में अपने सी # प्रोग्राम में फ़ंक्शन नाम निर्दिष्ट नहीं कर सकते हैं। टी-एसक्यूएल संकलन एक सटीक पहुंच योजना के साथ आना चाहिए, जिसका अर्थ है कि कौन से इंडेक्स खोलने और क्वेरी को संतुष्ट करने के लिए उपयोग करते हैं। एक 'स्ट्रिंग' के लिए योजना के साथ आना असंभव होगा, जैसे सी # में एक विधि के रूप में 'स्ट्रिंग' को आमंत्रित करने के लिए कोड उत्पन्न करना असंभव होगा।

declare @sql NVARCHAR(MAX) = N'SELECT ... FROM ' + 
    quotename(@dbname) + N'.' + quotename(@schema) + N'.' + quotename(@table) + 
    N' WHERE ...'; 
exec sp_executesql @sql; 

... बस के रूप में सी # में आप प्रतिबिंब का उपयोग गतिशील क्रम मंगलाचरण करने के लिए होगा:

समाधान गतिशील एसक्यूएल है।

अधिक जानकारी के लिए The Curse and Blessings of Dynamic SQL देखें।

पीएस। @tablename के घटकों में विभाजित और QUOTENAME का उपयोग एक पूर्ण अनिवार्य है, यह एसक्यूएल इंजेक्शन agaisnt गार्ड करता है। आपके लिए विभाजन करने के लिए PARSENAME का उपयोग करें।

+0

+1, डायनामिक एसक्यूएल से निपटने के दौरान यह हमेशा पहली जगह है – Lamak

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

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