2010-05-26 11 views
10

मैं कोड के साथ एक PreparedStatement इस के समान उपयोग करने के लिए कोशिश कर रहा हूँ:PreparedStatement.setString() उद्धरण चिह्नों के बिना विधि

SELECT * FROM ? WHERE name = ? 

जाहिर है, क्या जब मैं setString का उपयोग() स्थापित करने के लिए मेज और नाम क्षेत्र है होता है यह:

SELECT * FROM 'my_table' WHERE name = 'whatever' 

और क्वेरी काम नहीं करती है।

SELECT * FROM my_table WHERE name = 'whatever' 

या मैं सिर्फ यह छोड़ देना और इसके बजाय नियमित वक्तव्य का उपयोग करना चाहिए (तर्क प्रणाली, की न के दूसरे हिस्से से आते हैं: वहाँ उद्धरण के बिना स्ट्रिंग सेट करने के लिए एक तरह से तो लाइन इस तरह दिखता है उन उपयोगकर्ताओं द्वारा दर्ज किया जाता है)?

+0

तथ्य यह है कि यदि आप ऐसा करने पर विचार कर रहे मेरे लिए पता चलता है कि आप अपने डेटा remodeling विचार करना चाहिए। शायद आपको एक ऐसा दृश्य बनाना चाहिए जो सभी टेबलों को विलय कर लेता है, जिसमें एक जोड़ा कॉलम 'टेबल नाम' होता है। – nsayer

उत्तर

15

पैरामीटर का उपयोग तालिका को पैरामीटर करने या किसी भी डेटाबेस ऑब्जेक्ट को पैरामीटर करने के लिए नहीं किया जा सकता है। वे अधिकतर WHERE/HAVING खंडों को पैरामीटर करने के लिए उपयोग किए जाते हैं।

जो भी आप चाहते हैं, उसे करने के लिए आपको प्रतिस्थापन करना होगा और आवश्यकतानुसार नियमित विवरण बनाना होगा।

जब आप एक तैयार कथन का उपयोग करते हैं, तो यह कथन पर आगे प्रसंस्करण करने के लिए डेटाबेस का संकेत है - उदा। स्ट्रिंग को पार्स करें और संभवतः निष्पादन योजना निर्धारित करें। यदि क्वेरी में उपयोग की जाने वाली ऑब्जेक्ट गतिशील रूप से बदल सकती हैं, तो डेटाबेस बहुत आगे की तैयारी नहीं कर सका।

+0

इसके आगे, ऐसा नहीं है कि सेटस्ट्रिंग का उपयोग तारों के चारों ओर उद्धरण डालता है, क्योंकि ऐसा नहीं होता है (वेरिएबल्स बाध्य नहीं करते हैं)। यह सिर्फ इतना है कि आप क्वेरी के उस हिस्से के लिए एक चर का उपयोग नहीं कर सकते हैं। – Donnie

+0

समझ गया, धन्यवाद! क्या आप तैयार किए गए स्टेटमेंट का उपयोग करके कहेंगे कि यहां बहुत अधिक समझ नहीं है, क्या पैरामीटर उपयोगकर्ता दर्ज नहीं किए गए हैं? मेरा मतलब है कि यह नियमित वक्तव्य का उपयोग कर शायद अधिक महंगा बनाम है। या मुझे हर जगह तैयार किए गए स्टेटमेंट का उपयोग करना चाहिए, इससे कोई फर्क नहीं पड़ता? – Slavko

+1

आप अभी भी एक प्रीपेयरस्टेटमेंट का उपयोग कर सकते हैं, बस तालिका नाम को पैरामीटर करने का प्रयास न करें - 'जो भी' पैरामीटर करें। तैयार बनाम नियमित बयानों के उपयोग पर कुछ बहस है, लेकिन मेरा मानना ​​है कि सहमति तैयार तैयार बयानों का उपयोग करना है जबतक कि आप अच्छे कारणों की खोज न करें। – mdma

2

दुर्भाग्यवश आप तैयार बयानों के लिए तालिका नाम पैरामीटर नहीं कर सकते हैं। अगर वांछित है, तो आप एक स्ट्रिंग का निर्माण कर सकते हैं और इसे गतिशील एसक्यूएल के रूप में निष्पादित कर सकते हैं।

3

मुझे संदेह है कि आपका एसक्यूएल वास्तव में उस तरह असीम रूप से लचीला है। आपके पास केवल सीमित संख्या में टेबल हैं, इसलिए आपको आवश्यक SQL को व्यक्त करने के लिए स्थिर अंतिम स्ट्रिंग्स की संख्या भी सीमित है।

तैयार किए गए स्तर का उपयोग करना जारी रखें और अपने चर को बांधें। यह पूरी तरह से लायक है, विशेष रूप से सहायक जब एसक्यूएल इंजेक्शन समस्याओं से परहेज करते हैं।

+0

आपने स्पष्ट रूप से पर्याप्त TheDailywtf.com को नहीं पढ़ा है। प्रति ग्राहक एक टेबल (और ग्राहकों की संख्या बाध्य नहीं है) एक प्रयोग किया विरोधी विरोधी पैटर्न है। –

+0

स्पष्ट रूप से नहीं। सर उठाने के लिए धन्यवाद। 8) – duffymo

2

गलती तुमने किया था कि आप एक पैरामीटर के रूप में तालिका नाम पारित नहीं हो सकता है। आपको केवल एसक्यूएल स्टेटमेंट में मानों को पास करना चाहिए।

पूर्व: आप wantto कर रहे हैं:

Select * from LoggedUsers where username='whatever' and privilege='whatever'; 

तो आप PreparedStatement के रूप में निर्माण करने के लिए है:

Select * from LoggedUsers where username=? and privilege=? 

setString(1, usernameObject); 
setString(2, privilegeObject); 

PreparedStatement के प्रयोजन कठिनाई और की पठनीयता को कम करना है डेटाबेस कनेक्शन कोड। जब डेवलपर को स्टेटमेंट के उदाहरण के साथ कई कॉलम मानों का उपयोग करना पड़ता है तो अर्धविराम, कॉमा और प्लस (कॉन्सट ऑपरेटर) रखना मुश्किल होता है।

मुझे लगता है कि आप गलती से इसका लाभ है, जो करने के लिए डिज़ाइन नहीं किया गया है ले जाना चाहते थे रहे हैं ....

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