2009-08-20 9 views
27

मेरे पास नामों की एक सूची है जैसे xxx26 तैयार कथन पर पैरामीटर की सूची कैसे सेट करें?

List<String> names = ... 
names.add('charles'); 
... 

और एक कथन:

PreparedStatement stmt = 
    conn.prepareStatement('select * from person where name in (?)'); 

निम्न कार्य कैसे करें:

stmt.setParameterList(1,names); 

क्या कोई कामकाज है? क्या कोई यह समझा सकता है कि यह विधि क्यों गुम है?

का उपयोग कर: जावा, postgresql, jdbc3

+0

संभावित डुप्लिकेट विकल्प?] (http://stackoverflow.com/questions/178479/preparedstatement-in-clause-alternatives) – luator

उत्तर

17

वहाँ बस PreparedStatement है कि मैं के बारे में पता पर एक सूची सेट करके ऐसा करने के लिए कोई साफ रास्ता नहीं है।

प्रश्न लिखें जो प्रश्न संख्याओं की उचित संख्या (आपकी सूची में समान संख्या) के साथ SQL कथन (या बेहतर एकल या समान टोकन को प्रतिस्थापित करता है) लिखता है और फिर प्रत्येक के लिए पैरामीटर सेट करने पर आपकी सूची को फिर से चालू करता है।

1

टाइप एरर के कारण यह विधि अनुपलब्ध है, सूची का पैरामीटर प्रकार रनटाइम पर खो जाता है। इसलिए कई तरीके arires जोड़ने की जरूरत: setIntParameters, setLongParameters, setObjectParameters आदि

+0

यदि प्रत्येक डेटा प्रकार के लिए कोई ऐड विधि है, तो क्यों 'addList' विधि नहीं है हर डेटाटाइप भी? (उदाहरण के लिए addStringList (...)) – Chris

+0

यह बिंदु है, स्टेटमेंट इंटरफ़ेस पहले से ही सूची प्रकारों की गिनती के बिना भी फूला हुआ है – dfa

+2

टाइप एरर एक अच्छा कारण नहीं है, सेटएरे पैरामीटर (int pos, ऑब्जेक्ट [] पैरा) – ycnix

2

postgres 9 के लिए मैं इस दृष्टिकोण का इस्तेमाल किया है,:

jdbcTemplate.query(getEmployeeReport(), new PreparedStatementSetter() { 
     @Override 
     public void setValues(PreparedStatement ps) throws SQLException { 
      ps.setTimestamp(1, new java.sql.Timestamp(from.getTime())); 
      ps.setTimestamp(2, new java.sql.Timestamp(to.getTime())); 
      StringBuilder ids = new StringBuilder(); 
      for (int i = 0; i < branchIds.length; i++) { 
       ids.append(branchIds[i]); 
       if (i < branchIds.length - 1) { 
        ids.append(","); 
       } 
      } 
      // third param is inside IN clause 
      // Use Types.OTHER avoid type check while executing query 
      ps.setObject(3, ids.toString(), **Types.OTHER**); 
     } 
    }, new PersonalReportMapper()); 
+0

हो सकता है क्या यह वास्तव में '(?)' के लिए काम करता है? सर्वर पर जारी किए जाने के बाद वास्तविक कथन कैसा दिखता है? – rbellamy

+0

आप अपने जेडीबीसी कोड में स्ट्रिंग मानों के संयोजन से बचना चाहते हैं, क्योंकि इससे आसानी से एसक्यूएल इंजेक्शन कीड़े हो सकती हैं। -1 –

-1

मैं आज सुबह कोड की समीक्षा की गई थी और मेरे सहयोगियों में से एक के लिए एक अलग था दृष्टिकोण, setString("name1','name2','name3") का उपयोग कर पैरामीटर पास करें।

नोट: मैंने शुरुआत और अंत में एकल उद्धरण छोड़ा क्योंकि इन्हें setString द्वारा जोड़ा जा रहा है।

+1

निरंतर तारों के लिए, यह स्वीकार्य हो सकता है। उपयोगकर्ता इनपुट के लिए, यह SQL इंजेक्शन के लिए कमजोर कोड का एक अच्छा उदाहरण है। –

+0

यह बिल्कुल काम नहीं करना चाहिए। यदि ऐसा होता है, तो आपके जेडीबीसी ड्राइवर में एक बग है। 'सेटस्ट्रिंग' एस्ट्रोफ़ेस के साथ सौदा करता है, ताकि आपको वास्तव में 'स्ट्रिंग' मिल जाए जो आपने पारित किया था। क्या आपके सहयोगी ने अपना कोड परीक्षण किया था? –

18

यह सवाल बहुत पुराना है, लेकिन कोई setArray

का उपयोग कर सुझाव दिया है इस उत्तर https://stackoverflow.com/a/10240302/573057

+2

setArray MySQL या JavaDB के साथ काम नहीं करेगा क्योंकि वे SQL में ARRAY डेटा प्रकार का समर्थन नहीं करते हैं। शीर्ष पर नोट देखें: https://docs.oracle.com/javase/tutorial/jdbc/basics/array.html – TigerC10

+0

@ टाइगरसी 10 अच्छा बिंदु ... जिज्ञासा पिक्ड पुनः: जावा इन-मेमोरी डीबी - डर्बी (जावाडीबी) समर्थन नहीं करता है लेकिन दोनों [एच 2] (http://www.h2database.com/html/datatypes.html#array_type) और [hsqldb] (http://hsqldb.org/doc/guide/sqlgeneral-chapt .html # sgc_array) करें। – earcam

-2

अन्य विधि मदद कर सकता है: विभिन्न मंचों में विभिन्न समाधान की जांच और एक नहीं मिल रहा करने के बाद

public void setValues(PreparedStatement ps) throws SQLException { 
    // first param inside IN clause with myList values 
    ps.setObject(1 , myList.toArray(), 2003); // 2003=array in java.sql.Types 
} 
+1

कृपया अपने कोड – eliasah

+0

पर कुछ स्पष्टीकरण दें क्या यह वास्तव में काम करता है? – wutzebaer

-1

अच्छा समाधान, मुझे लगता है कि मैं नीचे आने वाला हैक महसूस करता हूं, अनुसरण करने और कोड का सबसे आसान तरीका है। ध्यान दें कि यह तैयार क्वेरी का उपयोग नहीं करता है लेकिन काम को वैसे भी किया जाता है:

उदाहरण: मान लीजिए कि आपके पास 'IN' खंड में पास करने के लिए पैरामीटर की एक सूची है। बस 'आईएन' खंड के अंदर एक डमी स्ट्रिंग डालें, कहें, "पैराम" पैरामीटर की सूची को दर्शाता है जो इस डमी स्ट्रिंग के स्थान पर आ जाएगा।

select * from TABLE_A where ATTR IN (PARAM); 

आप अपने जावा कोड में एक ही स्ट्रिंग चर में सभी पैरामीटर एकत्र कर सकते हैं। यह इस प्रकार किया जा सकता है:

String param1 = "X"; 
    String param2 = "Y"; 
    String param1 = param1.append(",").append(param2); 

आप अपने सभी मापदंडों एक एकल स्ट्रिंग वैरिएबल, 'param1', हमारे मामले में में अल्पविराम के द्वारा अलग जोड़ सकते हैं।

सभी पैरामीटर को एक स्ट्रिंग में एकत्र करने के बाद आप अपनी क्वेरी में डमी टेक्स्ट को प्रतिस्थापित कर सकते हैं, यानी, पैरामीटर स्ट्रिंग, यानी पैरामीटर 1 के साथ इस मामले में "पैराम"। यहां आपको यह करने की आवश्यकता है:

String query = query.replaceFirst("PARAM",param1); where we have the value of query as 

    query = "select * from TABLE_A where ATTR IN (PARAM)"; 

अब आप executeQuery() विधि का उपयोग कर अपनी क्वेरी निष्पादित कर सकते हैं। बस सुनिश्चित करें कि आपके पास कहीं भी आपकी क्वेरी में "PARAM" शब्द नहीं है। आप यह सुनिश्चित करने के लिए "PARAM" शब्द के बजाय विशेष वर्णों और अक्षरों के संयोजन का उपयोग कर सकते हैं ताकि क्वेरी में आने वाले ऐसे शब्द की कोई संभावना न हो। आशा है कि आपको समाधान मिल जाएगा।

+0

आप जानते हैं कि इससे एसक्यूएल इंजेक्शन हो सकता है? –

+0

धन्यवाद यह काम करता है ... :) –

0

मामले में सवाल 'का अर्थ एक कॉल में कई पैरामीटर सेट करने के लिए है ...

क्योंकि प्रकार मान्यता पहले से ही एक उच्च स्तर में परिभाषित किया गया है, मुझे लगता है कि केवल जरूरत setObject(...) के लिए है।

इस प्रकार, एक उपयोगिता विधि का इस्तेमाल किया जा सकता है:

public static void addParams(PreparedStatement preparedStatement, Object... params) throws SQLException { 
    for (int i = 0; i < params.length; i++) { 
     Object param = params[i]; 
     preparedStatement.setObject(i+1, param); 
    } 
} 

उपयोग:

SqlUtils.addParams(preparedStatement, 1, '2', 3d); 

एक जावा 8 लैम्ब्डा :) को यह परिवर्तित स्वतंत्र महसूस

खंड में [PreparedStatement की
+0

सेटऑब्जेक्ट एक सूची उत्तीर्ण ओरेकल ड्राइवर के साथ अपवाद फेंकता है –

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