2012-03-25 14 views
12

एंड्रॉइड में, android.database.sqlite.SQLiteStatement मुझे इंजेक्शन हमलों से बचने के लिए SQLite में तैयार कथन का उपयोग करने की अनुमति देता है। इसकी execute विधि ऑपरेशन बनाने/अपडेट/हटाने के लिए उपयुक्त है, लेकिन ऐसे कर्सर या जैसे प्रश्नों के लिए कोई विधि प्रतीत नहीं होती है।Android में तैयार कथन के साथ प्रश्न?

अब आईओएस में मैं sqlite3_stmt* के तैयार कथन तैयार कर सकता हूं और प्रश्नों के लिए उनका उपयोग कर सकता हूं, इसलिए मुझे पता है कि यह SQLite की सीमा नहीं है। एंड्रॉइड में तैयार कथन के साथ मैं प्रश्न कैसे कर सकता हूं?

उत्तर

39

एक तैयार बयान के बाद से डेटाबेस कथन में हैं हर बार पार्स करने के लिए

  • बाँध & भागने तर्क तो आप के खिलाफ सेव कर रहे हैं की जरूरत नहीं है तो आपको दो बातें

    • गति को प्रदर्शन करने की अनुमति देता इंजेक्शन हमलों

    मैं कहां/पता नहीं है जब Androids SQLite कार्यान्वयन वास्तव में sqlite3_prepare का उपयोग करता है (afiak नहीं sqlite3_prepare_v2 - here देखें), लेकिन मैं टी इसका उपयोग करता है अन्यथा आपको Reached MAX size for compiled-sql statement cache errors नहीं मिल सका।

    तो यदि आप डेटाबेस से पूछना चाहते हैं तो आपको कार्यान्वयन पर भरोसा करना होगा, मुझे SQLiteStatement के साथ ऐसा करने का कोई तरीका नहीं है।

    इंजेक्शन सुरक्षा के संबंध में, प्रत्येक डेटाबेस क्वेरी, सम्मिलित, आदि विधि में (कभी-कभी वैकल्पिक) संस्करण होते हैं जो आपको तर्कों को बांधने की अनुमति देते हैं।

    उदा।आप

    SELECT * FROM table WHERE column1='value1' OR column2='value2' 
    

    Cursor SQLiteDatabase#rawQuery(

    • String sql, के बाहर एक Cursor प्राप्त करना चाहते हैं: पूर्ण SELECT बयान जो शामिल कर सकते हैं ? हर जगह
    • String[] selectionArgs: मानों ? की जगह की सूची में, आदेश वे
    दिखाई देते हैं

    )

    Cursor c1 = db.rawQuery(
        "SELECT * FROM table WHERE column1=? OR column2=?", 
        new String[] {"value1", "value2"} 
    ); 
    

    Cursor SQLiteDatabase#query (

    • String table,: तालिका नाम, शामिल कर सकते हैं JOIN आदि
    • String[] columns,: स्तंभों की सूची की आवश्यकता है, null = *
    • String selection,: WHERE खंड withouth WHERE/?
    • String[] selectionArgs, शामिल होना चाहिए कर सकते हैं: GROUP BY खंड w/ओ GROUP BY
    • String having,: HAVING खंड मानों ? की जगह, क्रम में वे
    • String groupBy, दिखाई की सूची w/ओ HAVING
    • String orderBy: ORDER BY खंड डब्ल्यू/ORDER BY
    012 ओ

    )

    Cursor c2 = db.query("table", null, 
        "column1=? OR column2=?", 
         new String[] {"value1", "value2"}, 
         null, null, null); 
    

    वाया ContentProviders - उस मामले थोड़ा अलग है क्योंकि आप एक सार प्रदाता है, न एक डेटाबेस के साथ बातचीत है। आकस्मिक रूप से कोई गारंटी नहीं है कि ContentProvider का समर्थन करने वाला एक स्क्लाइट डेटाबेस है। तो जब तक आप नहीं जानते कि वहां कौन से कॉलम हैं/प्रदाता आंतरिक रूप से कैसे काम करता है, आपको दस्तावेज़ों के बारे में क्या कहना चाहिए।

    Cursor ContentResolver#query(

    • Uri uri,: स्तंभों की सूची की आवश्यकता है, null = *
    • String selection,: WHERE खंड एक यूआरआई डेटा स्रोत (आंतरिक एक मेज के अनुवाद)
    • String[] projection, का प्रतिनिधित्व WHERE?
    • शामिल हो सकता है,: ORDER BY खंड w/ओ ORDER BY

    )

    Cursor c3 = getContentResolver().query(
        Uri.parse("content://provider/table"), null, 
        "column=? OR column2=?", 
         new String[] {"value1", "value2"}, 
         null); 
    

    सुझाव:: मानों ? की जगह, क्रम में वे दिखाई देते हैं

  • String sortOrder की सूची यदि आप LIMIT करना चाहते हैं यहाँ आप जोड़ सकते हैं यह ORDER BY खंड:

    String sortOrder = "somecolumn LIMIT 5"; 
    

    या ContentProvider के कार्यान्वयन पर निर्भर करता है Uri के लिए एक पैरामीटर के रूप में जोड़ें:

    Uri.parse("content://provider/table?limit=5"); 
    // or better via buildUpon() 
    Uri audio = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
    audio.buildUpon().appendQueryParameter("limit", "5"); 
    

    सभी मामलों ? में क्या आप बाँध तर्क में डाल के भाग निकले संस्करण से बदल दिया जाएगा।

    ? + "hack'me" = 'hack''me'

  • +1

    बकाया पोस्ट,, धन्यवाद मुझे बहुत बाहर में मदद की। इस तरह के टाइम्स मुझे लगता है कि हमें एक से अधिक बार संशोधित करने में सक्षम होना चाहिए। – Louis

    +1

    भले ही यह उत्तर शांत हो, फिर भी स्ट्रिंग की तुलना में किसी और चीज को बांधने के लिए कोई कामकाज है। मेरे प्रश्न एक संख्यात्मक मान को बाध्य करने का अनुरोध करते हैं लेकिन स्क्लाइटडेटाबेस से प्रत्येक विधियां स्ट्रिंग सरणी का उपयोग करती हैं। और यदि मैं खुद को तैयार किए गए स्टेटमेंट को बना देता हूं, तो मैं कर्सर को पुनर्प्राप्त करने के लिए क्वेरी निष्पादित कर सकता हूं ... मुझे विश्वास नहीं है कि कोई समाधान नहीं है लेकिन मुझे यह नहीं मिला है। – AxelH

    +0

    @AxelH समाधान यह है कि सबकुछ स्ट्रिंग के रूप में व्यक्त किया जा सकता है। उदाहरण के लिए 'String.valueOf (yourNumericThingHere)' का उपयोग करें। – zapl

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

    • कोई संबंधित समस्या नहीं^_^