2008-09-18 11 views
10

हम सभी जानते हैं कि तैयार कथन एसक्यूएल इंजेक्शन हमलों के फेंकने का सबसे अच्छा तरीका है। "IN" खंड के साथ तैयार कथन बनाने का सबसे अच्छा तरीका क्या है। क्या अनिश्चित संख्या के मूल्यों के साथ ऐसा करने का कोई आसान तरीका है? उदाहरण के लिए निम्नलिखित क्वेरी लें।एसक्यूएल पैरामीटर के साथ, एक आईएन खंड में डेटा को संभालने?

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (1,2,3) 

वर्तमान में मैं एक स्ट्रिंग बनाने के लिए अपने संभावित मूल्यों पर एक लूप का उपयोग कर रहा हूं।

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (@IDVAL_1,@IDVAL_2,@IDVAL_3) 

क्या क्वेरी पैरामीटर के मूल्य के रूप में केवल सरणी को पास करना और निम्नानुसार एक क्वेरी का उपयोग करना संभव है?

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (@IDArray) 

मामले में यह महत्वपूर्ण मैं SQL Server 2000 के साथ काम कर रहा हूँ, VB.Net

+0

एक SQLServer टैग जोड़ें – MotoWilliams

+0

एक टी-एसक्यूएल टैग भी उचित हो सकता है। –

उत्तर

1

में आप एक सरणी पारित करने के लिए चाहते हैं, तो है, आप एसक्यूएल में एक समारोह है कि में कि सरणी बदल सकते हैं की आवश्यकता होगी एक उप-चयन।

ये कार्य बहुत आम हैं, और अधिकांश घर उगाए जाने वाले सिस्टम उनका लाभ उठाते हैं।

अधिकतर वाणिज्यिक, या बल्कि पेशेवर ओआरएम चर का एक गुच्छा करके करते हैं, इसलिए यदि आपके पास यह काम है, तो मुझे लगता है कि यह मानक तरीका है।

-1

SQL सर्वर 2008 में, वे अंततः एक नई "टेबल" डेटाटाइप जोड़कर इस क्लासिक समस्या को संबोधित करने के लिए मिल गए। जाहिर है, जो आपको मानों की एक सरणी में गुजरने देता है, जिसे उप-चयन में एक आईएन कथन के रूप में पूरा करने के लिए उपयोग किया जा सकता है।

यदि आप SQL Server 2008 का उपयोग कर रहे हैं, तो आप उस पर देख सकते हैं।

+0

"यदि यह महत्वपूर्ण है तो मैं SQL Server 2000 के साथ काम कर रहा हूं" – digiguru

5

ये रहा - पहले निम्नलिखित समारोह बनाने ...

Create Function [dbo].[SeparateValues] 
(
    @data VARCHAR(MAX), 
    @delimiter VARCHAR(10) 
) 
    RETURNS @tbldata TABLE(col VARCHAR(10)) 
As 
Begin 
    DECLARE @pos INT 
    DECLARE @prevpos INT 

    SET @pos = 1 
    SET @prevpos = 0 

    WHILE @pos > 0 
     BEGIN 

     SET @pos = CHARINDEX(@delimiter, @data, @prevpos+1) 

     if @pos > 0 
     INSERT INTO @tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(@data, @prevpos+1, @[email protected])))) 

     else 

     INSERT INTO @tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(@data, @prevpos+1, len(@data)[email protected])))) 

     SET @prevpos = @pos 
    End 

    RETURN 

END 

उसके बाद निम्न का उपयोग करें ...

Declare @CommaSeparated varchar(50) 
Set @CommaSeparated = '112,112,122' 
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (select col FROM [SeparateValues](@CommaSeparated, ',')) 

मुझे लगता है कि एसक्यूएल सर्वर 2008 तालिका कार्यों की अनुमति देगा।

अद्यतन

आप निम्न सिंटैक्स का उपयोग कुछ अतिरिक्त प्रदर्शन निचोड़ देंगे ...

SELECT ID,Column1,Column2 FROM MyTable 
Cross Apply [SeparateValues](@CommaSeparated, ',') s 
Where MyTable.id = s.col 

क्योंकि पिछले वाक्य रचना एक अतिरिक्त "क्रमबद्ध करें" आदेश का उपयोग कर चलाते हैं "करने के लिए SQL सर्वर का कारण बनता है "खंड में। इसके अलावा - मेरी राय में यह अच्छा लगता है: डी!

+0

यह समाधान हल करता है, क्योंकि आपको इच्छित किसी भी अलग मूल्य की सूचियों से तालिकाओं को बनाने के लिए एक अच्छा फ़ंक्शन देता है - वोट क्यों? – digiguru

+0

मैंने आपको वोट दिया। यह वह समाधान है जिसका हम उपयोग करते हैं। एसक्यूएल 2000 के साथ काम करता है और कनिष्ठ टीम के सदस्यों को समझने के लिए अवधारणात्मक रूप से आसान है। अगर मैं कर सकता, तो मैं आपको 5 अंक वोट दूंगा। मैंने पोस्ट और लेखों में वर्णित इस तकनीक को देखा है। यह समाधान SQL रिपोर्ट सेवाओं के साथ भी अच्छी तरह से काम करता है। –

+0

बहुत बढ़िया, धन्यवाद! – Jaxedin

-2

यहाँ एक तकनीक मैं

ALTER Procedure GetProductsBySearchString 
@SearchString varchar(1000), 
as 
set nocount on 
declare @sqlstring varchar(6000) 
select @sqlstring = 'set nocount on 
select a.productid, count(a.productid) as SumOf, sum(a.relevence) as CountOf 
from productkeywords a 
where rtrim(ltrim(a.term)) in (''' + Replace(@SearchString,' ', ''',''') + ''') 
group by a.productid order by SumOf desc, CountOf desc' 

exec(@sqlstring) 
+0

एसक्यूएल तारों को निष्पादित करना उत्पादन वातावरण में चीजों को करने का एक बहुत ही खतरनाक तरीका है। – digiguru

0

का उपयोग आप एक एकल स्तंभ मान के साथ एक अस्थायी तालिका TempTable बना सकते हैं और सभी आईडी डाल सकता है है। फिर आप इसे उप-चयन के साथ कर सकते हैं:

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (SELECT VALUE FROM TempTable) 
0

digiguru द्वारा पोस्ट किए गए समाधान के साथ जाएं। यह एक महान पुन: प्रयोज्य समाधान है और हम उसी तकनीक का भी उपयोग करते हैं। नई टीम के सदस्य इसे पसंद करते हैं, क्योंकि यह समय बचाता है और हमारी संग्रहित प्रक्रियाओं को सुसंगत रखता है।समाधान SQL रिपोर्ट्स के साथ भी अच्छी तरह से काम करता है, क्योंकि वर्चर्स (8000) में रिकॉर्ड्स पास करने के लिए संग्रहीत प्रक्रियाओं में पैरामीटर पारित किए जाते हैं। आप बस इसे हुक और जाओ।

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