2009-01-11 58 views
82

如何在Android中的SQlite中使用預準備語句?如何在Android中的SQlite中使用預準備語句?

+7

考慮改變接受的答案。 – Suragch 2015-06-29 10:55:00

+8

同意 - 考慮改變答案......當有更好的解決方案存在時,從衆心態提高了接受的答案。 – LamonteCristo 2015-07-28 04:54:49

+3

巴勃羅,請改變接受的答案...給出的例子甚至沒有運行。我們的降價還不足以取消它。 – SparK 2016-04-18 16:31:54

回答

30

我使用Android的準備語句的時候,它是相當簡單:

SQLiteDatabase db = dbHelper.getWritableDatabase(); 
SQLiteStatement stmt = db.compileStatement("SELECT * FROM Country WHERE code = ?"); 
stmt.bindString(1, "US"); 
stmt.execute(); 
+0

準備好的語句是否可以將參數設置爲非值?像「SELECT * FROM?」? – Pablo 2009-01-20 06:16:51

9

jasonhudgins例如將無法正常工作。您無法使用stmt.execute()執行查詢並返回值(或Cursor)。

只能預編譯根本不返回任何行(如插入或創建表語句)或單個行和列(並使用simpleQueryForLong()simpleQueryForString())的語句。

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")); 

你想有一個更完整的一個看到這個片段Genscripts萬一。請注意,這是一個參數化的SQL查詢,所以本質上它是一個準備好的語句。

1

要獲得遊標,您不能使用compiledStatement。然而,如果你想使用完整準備的SQL語句,我推薦改編jbaez的方法...使用db.rawQuery()而不是db.query()

131

對於Android中準備好的SQLite語句,有SQLiteStatement。準備好的語句可以幫助你提高性能(特別是對於需要多次執行的語句),並且還有助於避免注入攻擊。請參閱this article以獲取有關預準備報表的一般性討論。

SQLiteStatement旨在與不返回多個值的SQL語句一起使用。 (這意味着你不會用他們最查詢。)下面是一些例子:

Create a table

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

所以宜用與創建和刪除,但要使用的execute()方法不返回一個值不打算與SELECT,INSERT,DELETE和UPDATE一起使用,因爲這些返回值。 (但見this question。)

Insert values

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

注意,executeInsert()方法而不是使用​​。當然,你不想每次都輸入相同的東西。爲此,您可以使用bindings

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); // These match to the two question marks in the sql string 
statement.bindString(2, stringValue); 

long rowId = statement.executeInsert(); 

通常,當您想要快速重複某些操作(如INSERT)多次時使用預準備語句。準備好的語句使得SQL語句不必每次都被解析和編譯。通過使用transactions,您可以加快速度。這允許一次應用所有更改。以下是一個示例:

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(); 
} 

查看這些鏈接,獲取關於事務和加速數據庫插入的更多信息。

Update rows

這是一個基本的例子。您也可以應用上述部分的概念。

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()也可用於DELETE語句和API 11 See this Q&A進行了介紹。

Query

通常,當您運行查詢,你想要得到的光標回來了大量的行。雖然這不是SQLiteStatement。你不運行它的查詢,除非你只需要一個簡單的結果,像中行的數據庫的數量,這可以用simpleQueryForLong()

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

做通常你會運行的SQLiteDatabasequery()方法獲取一個遊標。

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); 

有關查詢的更多詳細信息,請參閱this answer

相關問題