2009-02-17 5 views
5

में "संदिग्ध कॉलम नाम" मेरे पास SQLite डीबी, INVITEM और SHOPITEM में दो टेबल हैं। उनकी साझा विशेषता ItemId है और मैं एक इनर जॉइन करना चाहता हूं। क्वेरी है:SQLite INNER JOIN

SELECT INVITEM.CharId AS CharId, 
      INVITEM.ItemId AS ItemId 
     FROM (INVITEM as INVITEM 
INNER JOIN SHOPITEM AS SHOPITEM 
     ON SHOPITEM.ItemId = INVITEM.ItemId) 
    WHERE ItemId = 3; 

SQLite इसे पसंद नहीं करता है:

SQL error: ambiguous column name: ItemId 

त्रुटि दूर हो जाता है तो मैं WHERE INVITEM.ItemId = 3 लिखते हैं, लेकिन जब से जहां हालत कमोबेश उपयोगकर्ता द्वारा निर्दिष्ट, मैं नहीं बल्कि बनाना यह टेबल निर्दिष्ट करने के बिना काम करता है। प्राकृतिक जॉइन इस मुद्दे को हल करने लगता है, लेकिन मुझे यकीन नहीं है कि समाधान सामान्य है (यानी मैं इस मामले में उपयोग कर सकता हूं, लेकिन मुझे यकीन नहीं है कि मैं हर मामले में उपयोग कर सकता हूं)

कोई वैकल्पिक SQL वाक्यविन्यास जो समस्या को ठीक करेगा?

उत्तर

0

मैं उपयोगकर्ता को एसक्यूएल क्लॉज सीधे लिखने की अनुमति देने से स्पष्ट करता हूं। यह एसक्यूएल इंजेक्शन भेद्यता का स्रोत है।

यदि आपको लचीला होने के लिए क्वेरी की आवश्यकता है, तो उपयोगकर्ता के इनपुट को पार्स करने और उचित जहां खंड को जोड़ने का प्रयास करें।

यहां एक सामान्य उपाय

// from user input 
string user_column = "ItemID"; 
string user_value = "3"; 

string sql = "SELECT INVITEM.CharId AS CharId, INVITEM.ItemId AS ItemId FROM (INVITEM as INVITEM INNER JOIN SHOPITEM AS SHOPITEM ON SHOPITEM.ItemId = INVITEM.ItemId) "; 

if (user_column == "ItemID") 
{ 
    // using Int32.Parse here to prevent rubbish like "0 OR 1=1; --" being entered. 
    sql += string.Format("WHERE INVITEM.ItemID={0}",Int32.Parse(user_value)); 
} 

जाहिर है अगर आप एक से अधिक खंड के साथ काम कर रहे दिखाने के लिए कुछ सी # कोड है, तो आप विकल्प और बाद में खंड में कहां के लिए करना होगा।

+0

मैंने ऐसा कुछ करने का अंत किया। मैं उपयोगकर्ता को सीधे एसक्यूएल लिखने की इजाजत नहीं देता, लेकिन जहां खंड खंड अभिव्यक्ति टेम्पलेट का उपयोग करके बनाए जाते हैं। कॉलम नामों की योग्यता जहां आवश्यक था पर्याप्त था। – ggambett

0

बस अपने कॉलम उपनाम को कुछ समान, लेकिन अद्वितीय (जैसे ITEM_ID) में बदलें।

SELECT i.CharId AS CharId, i.ItemId AS ItemId 
FROM INVITEM as i INNER JOIN SHOPITEM AS s USING (ItemId) 
WHERE i.ItemId = 3; 

मैं USING (ItemId) वाक्य रचना जो स्वाद का मामला है उपयोग कर रहा हूँ:

10

मैं इस क्वेरी इस तरह से लिखते थे। यह ON (i.ItemID = s.ItemID) के बराबर है।

लेकिन मैंने WHERE खंड में i.ItemID योग्यता प्राप्त करके अस्पष्टता का समाधान किया। आपको लगता है कि यह अनावश्यक है, क्योंकि i.ItemID = s.ItemID। वे दोनों कम्यूटिटीविटी के बराबर हैं, इसलिए कोई अर्थपूर्ण अस्पष्टता नहीं है। लेकिन स्पष्ट रूप से SQLite यह जानने के लिए पर्याप्त स्मार्ट नहीं है।

मुझे NATURAL JOIN का उपयोग करना पसंद नहीं है। यह के प्रत्येक कॉलम के समान इक्विटी के समतुल्य है जो समान नाम वाले दोनों तालिकाओं में मौजूद है। मैं इसका उपयोग करना पसंद नहीं करता क्योंकि मैं नहीं चाहता कि यह उन स्तंभों की तुलना करें जो मैं नहीं चाहता हूं, सिर्फ इसलिए कि उनके पास एक ही नाम है।