2009-02-04 6 views
18

क्या SQL क्वेरी में सरणी (स्केलर्स) को बांधने का कोई मानक तरीका है? मैं बहुत की तरह एक IN खंड में बाध्य करने के लिए, चाहते हैं:क्या सरणी पैरामीटर सरणी के लिए बाध्यकारी है?

SELECT * FROM junk WHERE junk.id IN (?); 

मैं Perl::DBI जो scalars पैरामीटर coerces का उपयोग करने की हो, तो मैं की तरह बेकार प्रश्नों के साथ अंत:

SELECT * FROM junk WHERE junk.id IN ('ARRAY(0xdeadbeef)'); 

स्पष्टीकरण: मैंने क्वेरी को अपनी .sql फ़ाइल में रखा है, इसलिए स्ट्रिंग पहले से ही बनाई गई है। जहां उत्तर क्वेरी स्ट्रिंग को गतिशील रूप से बनाने का उल्लेख करते हैं, तो शायद मैं एक खोज करता हूं और इसके बजाय प्रतिस्थापित करता हूं।

संपादित करें: यह प्रश्न Parameterizing a SQL IN clause? का डुप्लिकेट है। मैंने मूल रूप से सोचा था कि इसे इस तरह बंद किया जाना चाहिए, लेकिन ऐसा लगता है कि यह कुछ अच्छी पर्ल-विशिष्ट जानकारी जमा कर रहा है।

+0

यह एक अच्छी तरह से ज्ञात सवाल का शिकार है उपयोग करने के लिए है। मुझे बस इसे खोजने दो .... – Ray

+0

यह डाटाबेस विशिष्ट है ... –

+0

कूल - खोजा गया, लेकिन इसे खुद नहीं मिला। – cdleary

उत्तर

12

आप निर्दिष्ट करें "यह एक पैरामीटर के साथ एक क्वेरी के लिए एसक्यूएल है" - जब आप कई पैरामीटर चाहते हैं तो यह काम नहीं करेगा। निश्चित रूप से निपटने के लिए दर्द है। पहले से सुझाए गए सुझावों के लिए दो अन्य बदलाव:

1) स्थान धारकों के बजाय डीबीआई-> उद्धरण का उपयोग करें।

my $sql = "select foo from bar where baz in (" 
      . join(",", map { $dbh->quote($_) } @bazs) 
      . ")"; 
my $data = $dbh->selectall_arrayref($sql); 

2) इस प्रकार के निम्न स्तर की सामग्री के लिए एक ओआरएम का उपयोग करें। डीबीआईएक्स :: कक्षा या गुलाब :: डीबी :: ऑब्जेक्ट, उदाहरण के लिए।

+1

है, हालांकि, मेरी ओर से, डीबीआई-> उद्धरण का उपयोग नहीं कर रहा है; मैंने $ dbh-> उद्धरण का उपयोग किया; यहां $ dbh $ dbh = डीबीआई-> कनेक्ट ("डीबीआई: mysql: $ db: $ host", $ user, $ pass) से है; – hetaoblog

+0

@hetablog वास्तव में, आप सही हैं। मैंने जवाब अपडेट कर लिया है। –

2

अजगर में, मैं हमेशा की तरह कुछ कर रही समाप्त कर दिया: '?'

query = 'select * from junk where junk.id in (' 
for id in junkids: 
    query = query + '?,' 
query = query + ')' 

cursor.execute(query, junkids) 

... जो अनिवार्य रूप से एक के साथ एक प्रश्न बनाता है सूची के प्रत्येक तत्व के लिए।

[कोड आसान गैर अजगर लोगों के लिए समझने के लिए बनाने के लिए संपादित करें (और अन्य मानकों को भी है, तो में वहाँ, आप आप चीजों को सही ढंग से लाइन अप जब आप क्वेरी को निष्पादित सुनिश्चित करने की आवश्यकता)। वहाँ एक बग है, जहां क्वेरी पिछले के बाद एक अतिरिक्त अल्पविराम होगा क्योंकि फिक्सिंग यह सिर्फ सामान्य विचार]

+0

निश्चित रूप से, यदि आप SQL इंजेक्शन के बारे में चिंतित नहीं हैं तो आपको पैरामीटर की आवश्यकता नहीं है। – Ray

+1

@ रे: मैं आपकी टिप्पणी को समझ नहीं पा रहा हूं - वह * पैरामीटर बाध्यकारी कर रहा है, बस गतिशील रूप से बांधने के लिए पैरामीटर की एक उचित संख्या जोड़ रहा है। – cdleary

+0

एचएम .. तो वह है। माफ कीजिएगा यह मेरी गलती है। – Ray

9

बादल हैं मैं की तरह कुछ करना जो मैं में छोड़ देंगे है,:

my $dbh = DBI->connect(...); 
my @vals= (1,2,3,4,5); 
my $sql = 'SELECT * FROM table WHERE id IN (' . join(',', map { '?' } @vals) . ')'; 
my $sth = $dbh->prepare($sql); 
$sth->execute(@vals); 
+0

लेकिन एसक्यूएल इंजेक्शन हमलों से खुद को बचाने के लिए याद रखें ... – MatBailie

+3

@ डेम्स, जेड्रागो का उदाहरण पहले से ही बाइंड वैरिएबल का उपयोग कर रहा है, इसलिए उसे एसक्यूएल इंजेक्शन को रोकने के लिए कुछ और करने की आवश्यकता नहीं है। – mpeters

+1

'मानचित्र {'?' } @ vals' अधिक आसानी से '('?') x @ vals' – ysth

4

सादा DBI के साथ आपको उपरोक्त सुझाव के अनुसार स्वयं को SQL बनाना होगा। DBIx::Simple (DBI के लिए एक रैपर) यह आपके लिए स्वचालित रूप से '??' का उपयोग करता है अंकन:

$db->query("select * from foo where bar in (??)", @values); 
+0

लेकिन फिर आप एसक्यूएल में कहीं और पैरामीटर बांध सकते हैं? मैं नहीं देखता कि आप पैरामीटर के बाद पैरामीटर कैसे बांध सकते हैं ?? जब तक कि यह वैकल्पिक रूप से इसके बजाय एक सरणी संदर्भ लेता है। – cdleary

+0

अच्छा सवाल। यदि मैं दस्तावेज़ों को सही ढंग से समझता हूं, तो आपके पास एकाधिक एकल प्लेसहोल्डर या एकल '??' हो सकता है, लेकिन दोनों नहीं। – 8jean

13

तुम वहाँ नक्शा पसंद नहीं है, तो आप 'एक्स' ऑपरेटर का उपयोग कर सकते हैं: '?'

my $params = join ', ' => ('?') x @foo; 
my $sql = "SELECT * FROM table WHERE id IN ($params)"; 
my $sth = $dbh->prepare($sql); 
$sth->execute(@foo); 

कोष्ठकों के आसपास की जरूरत है क्योंकि वह सूची 'x' सूची संदर्भ में होना चाहिए।

अधिक जानकारी के लिए "perldoc perlop" पढ़ें और 'बाइनरी "x' 'के लिए खोजें (यह" गुणक ऑपरेटरों "अनुभाग में है)।

+0

यह सही उत्तर होना चाहिए (कम से कम मेरी राय में)। – maletin

+0

@vals कहां से आते हैं? क्या आपका मतलब @ फू है? – teambob

+0

teambob: हाँ, मेरा मतलब @foo था। मैंने इसे बदल दिया है। धन्यवाद! – Ovid

0

मैं DBIx::DWIW का उपयोग करता हूं। इसमें इनलिस्ट() नामक एक फ़ंक्शन शामिल है। यह सूची के लिए आवश्यक SQL का हिस्सा बनाएगा।हालांकि यह केवल तभी काम करता है यदि आपके पास एक अलग फ़ाइल में बाहर की बजाय प्रोग्राम में आपका सभी एसक्यूएल है।

6

और फिर भी एसक्यूएल निर्माण करने के लिए एक और तरीका है SQL::Abstract की तरह कुछ ....

+0

मैं इसे पोस्ट करने वाला था, और मुझे निश्चित रूप से लगता है कि यह "सही उत्तर" है। यदि आप ओआरएम का उपयोग नहीं कर सकते हैं, कम से कम SQL :: सार (या शायद फे) जैसे कुछ का उपयोग करें। – jrockway

0

उपयोग

SELECT * FROM junk WHERE junk.id = ANY (?); 

बजाय

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