ฉันจะใช้คำสั่งที่เตรียมไว้ใน SQlite ใน Android ได้อย่างไร
ฉันจะใช้คำสั่งที่เตรียมไว้ใน SQlite ใน Android ได้อย่างไร
คำตอบ:
ฉันใช้งบที่เตรียมไว้ใน Android ตลอดเวลามันค่อนข้างง่าย:
SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement stmt = db.compileStatement("INSERT INTO Country (code) VALUES (?)");
stmt.bindString(1, "US");
stmt.executeInsert();
SQLiteStatement.bindXXX()
มีดัชนี 1 ฐานไม่ใช่ 0 เหมือนดัชนีส่วนใหญ่
สำหรับงบ SQLite เตรียมใน Android มี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()
วิธีการไม่คืนค่าจึงมีความเหมาะสมที่จะใช้กับการสร้างและ DROP แต่ไม่ได้มีเจตนาที่จะใช้กับ SELECT, INSERT, DELETE และ UPDATE เพราะเหล่านี้ค่าที่ส่งคืน (แต่ดูคำถามนี้)
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()
วิธีนอกจากนี้ยังสามารถนำมาใช้สำหรับงบลบและเป็นที่รู้จักใน API 11. ดู Q & A นี้
นี่คือตัวอย่าง
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();
โดยปกติคุณจะเรียกใช้query()
เมธอดของSQLiteDatabaseเพื่อรับเคอร์เซอร์
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);
ดูคำตอบนี้เพื่อดูรายละเอียดที่ดีขึ้นเกี่ยวกับข้อความค้นหา
clearBindings()
ไม่เพียง แต่ตั้งค่าเป็นnull
(ดูซอร์สโค้ด ) ฉันมองว่ามันเป็นการล้างสถานะเพื่อไม่ให้ไม่มีอะไรมากระทบกับมันจากลูปก่อนหน้านี้ บางทีนั่นอาจไม่จำเป็น ฉันยินดีสำหรับคนที่รู้จักแสดงความคิดเห็น
หากคุณต้องการให้เคอร์เซอร์กลับมาคุณอาจพิจารณาสิ่งนี้:
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"));
ดูตัวอย่างGenscriptsนี้ในกรณีที่คุณต้องการให้สมบูรณ์ยิ่งขึ้น โปรดทราบว่านี่เป็นแบบสอบถาม SQL ที่กำหนดพารามิเตอร์ดังนั้นโดยพื้นฐานแล้วมันเป็นคำสั่งที่เตรียมไว้
ตัวอย่าง jasonhudgins จะไม่ทำงาน คุณไม่สามารถเรียกใช้แบบสอบถามstmt.execute()
และรับค่า (หรือ a Cursor
) กลับมาได้
คุณสามารถคอมไพล์ได้เฉพาะคำสั่ง precompile ที่ไม่ส่งคืนแถวเลย (เช่นคำสั่งแทรกหรือสร้างตาราง) หรือแถวและคอลัมน์เดียว (และใช้simpleQueryForLong()
หรือsimpleQueryForString()
)
หากต้องการรับเคอร์เซอร์คุณไม่สามารถใช้ compileStatement อย่างไรก็ตามหากคุณต้องการใช้คำสั่ง SQL ที่เตรียมไว้เต็มรูปแบบฉันขอแนะนำให้ปรับวิธีการของ jbaez ... โดยใช้db.rawQuery()
แทนdb.query()
.