2009-01-11 64 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

相关问题