मैं एंड्रॉइड में SQlite में तैयार किए गए बयानों का उपयोग कैसे करूं?


100

मैं एंड्रॉइड में SQlite में तैयार किए गए बयानों का उपयोग कैसे करूं?


9
स्वीकृत उत्तर को बदलने पर विचार करें।
सुरगाछ

9
सहमत - जवाब बदलने पर विचार करें ... झुंड मानसिकता ने स्वीकार किए गए उत्तर को उकसाया, जब एक बेहतर समाधान मौजूद होता है।
goodguys_activate

4
पाब्लो, कृपया स्वीकृत उत्तर बदलें ... दिया गया उदाहरण भी नहीं चलता है। और हमारे डाउनवोट इसे अनपिन करने के लिए पर्याप्त नहीं हैं।
स्पार्क

जवाबों:


21

मैं हर समय Android में तैयार कथनों का उपयोग करता हूं, यह काफी सरल है:

SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement stmt = db.compileStatement("INSERT INTO Country (code) VALUES (?)");
stmt.bindString(1, "US");
stmt.executeInsert();

81
मुझे नहीं पता कि इस जवाब में इतने वोट कैसे हो सकते हैं। एसक्यूएल प्रश्नों के लिए SQLIteStatement # निष्पादित नहीं किया जाना चाहिए, केवल बयान। कृपया डेवलपर.
android.com/reference/android/database/sqlite/…

9
फिर डेटा को क्वेरी करने के लिए तैयार स्टेटमेंट का उपयोग कैसे किया जाता है?
जुआन मेंडेस

12
ध्यान दें कि SQLiteStatement.bindXXX()1-आधारित सूचकांक है, 0-आधारित नहीं है जैसे कि सबसे अधिक हैं।
सिमुलेंट

6
@jasonhudgins क्यों न केवल अपने चयन को एक INSERT से बदल दें? मैं सिर्फ इस धागे से आया हूं , जहां आपने शुरुआत की है
कीसर

35
झुंड मानसिकता का आदर्श उदाहरण जो पूरी तरह से गलत है और एक जवाब को स्वीकार करता है

165

Android में तैयार SQLite स्टेटमेंट्स के लिए SQLiteStatement है । तैयार किए गए बयान आपको प्रदर्शन को गति देने में मदद करते हैं (विशेषकर ऐसे बयानों के लिए जिन्हें कई बार निष्पादित करने की आवश्यकता होती है) और इंजेक्शन हमलों से बचने में भी मदद करते हैं। तैयार बयानों पर सामान्य चर्चा के लिए यह लेख देखें ।

SQLiteStatementका उपयोग SQL कथनों के साथ किया जाना है जो कई मान वापस नहीं करते हैं। (इसका मतलब है कि आप उन्हें अधिकांश प्रश्नों के लिए उपयोग नहीं करेंगे।) नीचे कुछ उदाहरण दिए गए हैं:

एक तालिका बनाएं

String sql = "CREATE TABLE table_name (column_1 INTEGER PRIMARY KEY, column_2 TEXT)";
SQLiteStatement stmt = db.compileStatement(sql);
stmt.execute();

execute()विधि एक मूल्य वापस नहीं करता है तो यह साथ बनाएँ और ड्रॉप का उपयोग करने के लिए उपयुक्त है, लेकिन नहीं, का चयन करें, सम्मिलित करें के साथ प्रयोग की जाने वाली DELETE इरादा है, और क्योंकि अद्यतन इन वापसी मान। (लेकिन इस सवाल को देखें )

मान डालें

String sql = "INSERT INTO table_name (column_1, column_2) VALUES (57, 'hello')";
SQLiteStatement statement = db.compileStatement(sql);
long rowId = statement.executeInsert();

ध्यान दें कि executeInsert()विधि का उपयोग इसके बजाय किया जाता है execute()। बेशक, आप हमेशा हर पंक्ति में समान चीजें दर्ज नहीं करना चाहेंगे। उसके लिए आप बाइंडिंग का उपयोग कर सकते हैं ।

String sql = "INSERT INTO table_name (column_1, column_2) VALUES (?, ?)";
SQLiteStatement statement = db.compileStatement(sql);

int intValue = 57;
String stringValue = "hello";

statement.bindLong(1, intValue); // 1-based: matches first '?' in sql string
statement.bindString(2, stringValue);  // matches second '?' in sql string

long rowId = statement.executeInsert();

आमतौर पर आप तैयार किए गए कथनों का उपयोग तब करते हैं जब आप कई बार (INSERT की तरह) किसी चीज़ को जल्दी दोहराना चाहते हैं। तैयार किया गया विवरण इसे बनाता है ताकि SQL स्टेटमेंट को हर बार पार्स और संकलित न किया जाए। आप लेन-देन का उपयोग करके चीजों को और अधिक गति प्रदान कर सकते हैं । यह सभी परिवर्तनों को एक बार में लागू करने की अनुमति देता है। यहाँ एक उदाहरण है:

String stringValue = "hello";
try {

    db.beginTransaction();
    String sql = "INSERT INTO table_name (column_1, column_2) VALUES (?, ?)";
    SQLiteStatement statement = db.compileStatement(sql);

    for (int i = 0; i < 1000; i++) {
        statement.clearBindings();
        statement.bindLong(1, i);
        statement.bindString(2, stringValue + i);
        statement.executeInsert();
    }

    db.setTransactionSuccessful(); // This commits the transaction if there were no exceptions

} catch (Exception e) {
    Log.w("Exception:", e);
} finally {
    db.endTransaction();
}

लेनदेन के बारे में कुछ और अच्छी जानकारी के लिए इन लिंक की जाँच करें और डेटाबेस आवेषण में तेजी लाएं।

पंक्तियों को अपडेट करें

यह एक बुनियादी उदाहरण है। आप ऊपर दिए गए अनुभाग से अवधारणाओं को भी लागू कर सकते हैं।

String sql = "UPDATE table_name SET column_2=? WHERE column_1=?";
SQLiteStatement statement = db.compileStatement(sql);

int id = 7;
String stringValue = "hi there";

statement.bindString(1, stringValue);
statement.bindLong(2, id);

int numberOfRowsAffected = statement.executeUpdateDelete();

पंक्तियों को हटाएं

executeUpdateDelete()विधि को भी हटा बयानों के लिए इस्तेमाल किया जा सकता और एपीआई 11 में शुरू की गई थी देखें इस क्यू एंड ए

यहाँ एक उदाहरण है।

try {

    db.beginTransaction();
    String sql = "DELETE FROM " + table_name +
            " WHERE " + column_1 + " = ?";
    SQLiteStatement statement = db.compileStatement(sql);

    for (Long id : words) {
        statement.clearBindings();
        statement.bindLong(1, id);
        statement.executeUpdateDelete();
    }

    db.setTransactionSuccessful();

} catch (SQLException e) {
    Log.w("Exception:", e);
} finally {
    db.endTransaction();
}

सवाल

आम तौर पर जब आप एक क्वेरी चलाते हैं, तो आप बहुत सारी पंक्तियों के साथ एक कर्सर वापस प्राप्त करना चाहते हैं। SQLiteStatementहालांकि, इसके लिए क्या नहीं है। आप इसके साथ एक क्वेरी नहीं चलाते हैं जब तक कि आपको केवल एक सरल परिणाम की आवश्यकता न हो, जैसे डेटाबेस में पंक्तियों की संख्या, जो आप कर सकते हैंsimpleQueryForLong()

String sql = "SELECT COUNT(*) FROM table_name";
SQLiteStatement statement = db.compileStatement(sql);
long result = statement.simpleQueryForLong();

आमतौर पर आप कर्सर पाने के लिए SQLiteDatabase की query()विधि चलाते हैं ।

SQLiteDatabase db = dbHelper.getReadableDatabase();
String table = "table_name";
String[] columnsToReturn = { "column_1", "column_2" };
String selection = "column_1 =?";
String[] selectionArgs = { someValue }; // matched to "?" in selection
Cursor dbCursor = db.query(table, columnsToReturn, selection, selectionArgs, null, null, null);

प्रश्नों के बारे में बेहतर जानकारी के लिए यह उत्तर देखें ।


5
बस एक अनुस्मारक: .bindString / .bindLong / ... विधियाँ सभी 1-आधारित हैं।
विटाली

मैं एंड्रॉइड सुविधा विधियों जैसे कि .query, .insert और .delete के हुड के नीचे देख रहा था और ध्यान दिया कि वे हुड के नीचे SQLiteStatement का उपयोग करते हैं। क्या अपने बयानों के निर्माण के बजाय सिर्फ सुविधा के तरीकों का उपयोग करना आसान नहीं होगा?
निकोलस कैरास्को

@ NicolásCarrasco, जब से मैंने इस पर काम किया है तब से कुछ समय हो गया है इसलिए मैं अब थोड़ा रूखी हूं। प्रश्नों और एकल आवेषण, अद्यतन और हटाने के लिए, मैं निश्चित रूप से सुविधा विधियों का उपयोग करूंगा। हालाँकि, यदि आप बड़े पैमाने पर आवेषण कर रहे हैं, अपडेट कर रहे हैं या हटा रहे हैं, तो मैं लेनदेन के साथ-साथ तैयार कथनों पर भी विचार करूंगा। जैसा कि SQLiteStatement हुड के तहत इस्तेमाल किया जा रहा है और क्या सुविधा के तरीके काफी अच्छे हैं, मैं उससे बात नहीं कर सकता। मुझे लगता है कि मैं कहूंगा, अगर सुविधा के तरीके आपके लिए पर्याप्त तेजी से प्रदर्शन कर रहे हैं, तो उनका उपयोग करें।
Suragch

आप क्लियरबिन्डिंग () का उपयोग क्यों करते हैं? आप अपने सभी मूल्यों को बिना किसी शर्त के बांधते हैं। यह मुझे समझ में नहीं आता है कि उन्हें पहले और वास्तविक मूल्य पर शून्य सेट करें।
अविश्वसनीय जन

@ TheincredibleJan, मुझे यकीन नहीं है। यह आवश्यक नहीं हो सकता है और आप बाइंडिंग को साफ किए बिना यह देखने की कोशिश कर सकते हैं कि क्या इससे कोई फर्क पड़ता है। हालाँकि, उन्होंने कहा, कॉलिंग clearBindings()उन्हें null( स्रोत कोड देखें ) सेट नहीं करता है । मैं इसे राज्य को साफ करने के रूप में देखता हूं ताकि पिछले लूप से कुछ भी प्रभावित न हो। शायद यह आवश्यक नहीं है, हालांकि। मुझे उस व्यक्ति के लिए खुशी होगी जो टिप्पणी करना जानता है।
सुरगाच

22

यदि आप वापसी पर एक कर्सर चाहते हैं, तो आप कुछ इस तरह से विचार कर सकते हैं:

SQLiteDatabase db = dbHelper.getWritableDatabase();

public Cursor fetchByCountryCode(String strCountryCode)
{
    /**
     * SELECT * FROM Country
     *      WHERE code = US
     */
    return cursor = db.query(true, 
        "Country",                        /**< Table name. */
        null,                             /**< All the fields that you want the 
                                                cursor to contain; null means all.*/
        "code=?",                         /**< WHERE statement without the WHERE clause. */
        new String[] { strCountryCode },    /**< Selection arguments. */
        null, null, null, null);
}

/** Fill a cursor with the results. */
Cursor c = fetchByCountryCode("US");

/** Retrieve data from the fields. */
String strCountryCode = c.getString(cursor.getColumnIndex("code"));

/** Assuming that you have a field/column with the name "country_name" */
String strCountryName = c.getString(cursor.getColumnIndex("country_name"));

यदि आप एक अधिक पूर्ण चाहते हैं, तो इस स्निपेट जेनस्क्रिप्ट को देखें । ध्यान दें कि यह एक पैरामीटर वाली SQL क्वेरी है, इसलिए संक्षेप में, यह एक तैयार विवरण है।


ऊपर दिए गए कोड में छोटी सी गलती: यह "नया स्ट्रिंग {strCountryCode}" के बजाय "नया स्ट्रिंग [] {strCountryCode}" होना चाहिए।
पियरे-ल्यूक सिमार्ड

डेटा पुनर्प्राप्त करने से पहले आपको कर्सर को स्थानांतरित करने की आवश्यकता है
चिन

9

jasonhudgins उदाहरण काम नहीं करेगा। आप किसी क्वेरी को निष्पादित नहीं कर सकते हैं stmt.execute()और मान (या a Cursor) वापस प्राप्त कर सकते हैं।

आप केवल ऐसे बयान प्रस्तुत कर सकते हैं, जो या तो कोई पंक्तियाँ नहीं लौटाते (जैसे कि एक प्रविष्टि, या तालिका विवरण बनाएँ) या एक पंक्ति और स्तंभ, (और उपयोग simpleQueryForLong()या simpleQueryForString())।


1

एक कर्सर पाने के लिए, आप एक संकलित उपयोग नहीं कर सकते। हालाँकि, यदि आप पूर्ण रूप से तैयार SQL कथन का उपयोग करना चाहते हैं, तो मैं jezez की विधि के अनुकूलन की सलाह देता हूँ ... के db.rawQuery()बजाय का उपयोग करना db.query()

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.