2011-01-25 18 views
26

सब मैं करना चाहता हूँ एक प्रश्नSQLite: मूल्यों का बाँध सूची "कहां में col (: पी आर एम)" के लिए

SELECT * FROM table WHERE col IN (110, 130, 90); 

की तरह भेजने तो मैं

SELECT * FROM table WHERE col IN (:LST); 

तो निम्न कथन तैयार मैं

sqlite_bind_text(stmt, 1, "110, 130, 90", -1, SQLITE_STATIC); 

का उपयोग दुर्भाग्य से यह हो जाता है

SELECT * FROM table WHERE col IN ('110, 130, 90'); 

और बेकार है (दो अतिरिक्त सिंगल कोट्स नोट करें)। मैंने स्ट्रिंग में अतिरिक्त 'डालने की कोशिश की है लेकिन वे भाग गए हैं। मुझे बचने से रोकने का विकल्प नहीं मिला या पाठ को सिंगल कोट्स से संलग्न होने से रोक दिया गया। आखिरी बात जो मैं सोच सकता हूं वह तैयार कथन का उपयोग नहीं कर रहा है, लेकिन मैं इसे केवल अंतिम विकल्प के रूप में ले जाऊंगा। क्या तुम्हारे पास कोई विचार या सुझाव है?

धन्यवाद

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

पैरामीटर की संख्या, गतिशील है, इसलिए यह तीन नंबर हो सकता है, ऊपर के उदाहरण के रूप में, एक या एक से बारह।

उत्तर

23

आप गतिशील रूप से एक पैरामिट्रीकृत SQL विवरण

SELECT * FROM TABLE WHERE col IN (?, ?, ?) 

निर्माण कर सकते हैं और उसके बाद प्रत्येक के लिए एक बार sqlite_bind_int कॉल "?" आपने कथन में जोड़ा।

एकाधिक पूर्णांक (या, उस मामले के लिए, एकाधिक पाठ) पैरामीटर को सीधे पाठ पैरामीटर को बांधने का कोई तरीका नहीं है।

यहाँ मैं क्या मन में है के लिए छद्म कोड है:

-- Args is an array of parameter values 
for i = Lo(Args) to Hi(Args) 
    paramlist = paramlist + ', ?' 

sql = 'SELECT * FROM TABLE WHERE col IN (' + Right(paramlist, 3) + ')' 

for i = Lo(Args) to Hi(Args) 
    sql_bind_int(sql, i, Args[i] 

-- execute query here. 
+0

आपके उत्तर के लिए धन्यवाद। मैंने इसे अपने मूल पोस्ट (बस संपादित) में उल्लेख नहीं किया है, लेकिन पैरामीटर की संख्या गतिशील है। मैं वास्तव में अभी भी अपना उत्तर "संभव नहीं" के रूप में लेता हूं, जिसका अर्थ है कि मैं बस तैयार कथन का उपयोग नहीं कर सकता। – Sebastian

+0

नहीं, सेबेस्टियन, मेरा सुझाव गतिशील रूप से पैरामीटर की एक चर संख्या के साथ एक SQL कथन का निर्माण करता है और फिर प्रत्येक पैरामीटर के लिए एक लूप में sqlite_bind_in को कॉल करता है। यह आपके लिए काम करना चाहिए। मैं जवाब में छद्म कोड जोड़ दूंगा। –

+0

sql_bind_ को कॉल करने में सक्षम होने के लिए * पहले sql_prepare को कॉल करने की आवश्यकता है। मुझे क्वेरी बनाने, तैयार करने, निष्पादित करने और अंतिम रूप देने के दौरान सीधे पैरामीटर डालने के बजाय गतिशील रूप से एक कथन बनाने, इसे तैयार करने, बांधने, निष्पादित करने और अंतिम रूप देने का बिंदु दिखाई नहीं देता है। हर बार जब मैं क्वेरी निष्पादित करना चाहता हूं तो मुझे sql_prepare को कॉल करने की आवश्यकता होगी और यही वह है जिसे मैं सहेजना और केवल एक बार करना चाहता हूं। – Sebastian

9

मैं सिर्फ यह सवाल अपने आप का सामना करना पड़ा है, लेकिन एक अस्थायी तालिका बनाने और उस में सभी मूल्यों डालने से यह उत्तर दिया, ताकि मैं तो कर सकता है : एक सैम पर कार्य करना

"SELECT * FROM TABLE WHERE col IN ("+",".join(["?"]*len(lst))+")" 
+0

क्या आपके पास कोई प्रदर्शन तुलना है? मैं कल्पना कर सकता हूं कि एक अस्थायी तालिका बनाने का उपर निष्पादन योजना निर्माण से अधिक है। हालांकि, तालिका आकारों पर निर्भर करेगा .. मुझे लगता है कि कोई अस्थायी तालिका को चारों ओर रख सकता है और हर बार इसे साफ़ और पुन: उपयोग कर सकता है (उचित सिंक्रनाइज़ेशन माना जाता है)। फिर भी यह बनाम निष्पादन योजना – Sebastian

+0

भरना होगा यह एक मीठा समाधान है। टेबल diff तुलना के मेरे कोड ऑर्डर बढ़ाया। –

4

यहां तक ​​कि सरल, इस तरह आपकी क्वेरी का निर्माण ई कार्यक्षमता मुझे इस दृष्टिकोण के लिए नेतृत्व: (NodeJS, ES6, वादा)

var deleteRecords = function (tblName, data) { 
     return new Promise((resolve, reject) => { 
      var jdata = JSON.stringify(data); 
      this.run(`DELETE FROM ${tblName} WHERE id IN (?)`, jdata.substr(1, jdata.length - 2), function (err) { 
       err ? reject('deleteRecords failed with : ' + err) : resolve(); 
      }); 
     }); 
    }; 
+0

वह भाषा क्या है? जावा?! – Sebastian

+3

यह पाइथन है।आप किस भाषा की तलाश में हैं? – xtin

0

:

SELECT * FROM TABLE WHERE col IN (SELECT col FROM temporarytable); 
0

उदाहरण के लिए, यदि आप SQL क्वेरी हैं:

select * from table where col in (110, 130, 90) 

के बारे में क्या:

my_list = [110, 130, 90] 
my_list_str = repr(my_list).replace('[','(').replace(']',')') 
cur.execute("select * from table where col in %s" % my_list_str) 
0

यह ठीक काम करता है (जावास्क्रिप्ट ES6):

let myList = [1, 2, 3]; 
`SELECT * FROM table WHERE col IN (${myList.join()});` 
+0

रनटाइम पर क्वेरी में डेटा को मैन्युअल रूप से इंजेक्ट करना वास्तव में एक बुरा विचार है। यह एक प्रमुख सुरक्षा जोखिम है जो आपको एसक्यूएल-इंजेक्शन हमले के लिए खोल देता है। https://www.netsparker.com/blog/web-security/sql-injection-cheat-sheet/ – jasonseminara

0

एक बहुत ही सरल और सुरक्षित उत्तर में मास्क उत्पन्न करना (क्वेरी के डेटा हिस्से के विपरीत) और एसक्यूएल-इंजेक्शन फॉर्मेटर इंजन को अपना काम करने की अनुमति देना शामिल है।

मान लीजिए कि हमें एक सरणी में कुछ id रों है, और कुछ cb कॉलबैक:

/* we need to generate a '?' for each item in our mask */ 
const mask = Array(ids.length).fill('?').join(); 

db.get(` 
    SELECT * 
    FROM films f 
    WHERE f.id 
     IN (${mask}) 
`, ids, cb);