我需要用 get readable 读取值并插入到另一个表中,并在同一函数中设置 writeable。
您不需要。就像您已经使用/编码了第二列的子查询一样:-
( SELECT count( "+CUL_ID_PRESENCE+" ) FROM " + TABLE_PRESENCE_TABLE + " WHERE "+ CUL_ID_PRESENCE+ " = ( SELECT "+ CUL_ID +" FROM "+ STUDENT_TABLE +" WHERE "+ CUL_QRCODE + " = "+ msg +"))+"+1+"
您可以为第一个值编写子查询,即将value 替换为获得值的查询。
例如您可以在没有前面的查询的情况下进行单个插入,如下所示:-
INSERT INTO presence VALUES
(
coalesce((SELECT cul_id FROM student WHERE cul_qrcode = 'message'),-99),
(SELECT count(cul_id_presence) FROM presence WHERE CUL_ID_PRESENCE = (SELECT CUL_ID FROM STUDENT WHERE CUL_QRCODE = 'message')+1),
datetime('now')
)
;
-
请注意,coalesce 函数会将 NULL(如果没有 cul_qrcode LIKE msg)转换为另一个值(在上述情况下为 -99)。
-
表名和列名已被猜到,因此它们可能与您实际拥有的不符。
-
否则,要实际接收查询结果,您将在 Cursor 中捕获结果,但您不使用 execSQL,而是使用 rawQuery 或 query 便捷方法。
-
execSQL 执行单个 SQL 语句,该语句不是 SELECT 或任何其他返回数据的 SQL 语句。
我怎样才能在变量字符串中接收 getReadableDatabase() 的值
要使用 query 后跟 insert 你会得到类似的东西:-
Cursor csr = db1.rawQuery(query,null);
String value = "-99"; /* assume that if nothing is returned then use -99 */
if(csr.moveToFirst) {
value = csr.getString(0);
}
csr.close(); /* SHOULD ALWAYS CLOSE CURSORS WHEN FINISHED WITH THEM */
但是,将参数连接到 SQL 是不好的做法,因为这被认为是 SQL 注入的潜在风险。相反,您应该绑定参数(这将克服一个重大缺陷,因为您似乎可能没有将 msg 括在单引号中,绑定参数会将参数括在单引号中)。所以上面应该是:-
public void Check(String msg){
//getdata from database
String query="SELECT "+ CUL_ID +" FROM " + STUDENT_TABLE + " WHERE "+ CUL_QRCODE +" like ?"; //<<<<< use ? to allow bind of msg
SQLiteDatabase db1=this.getReadableDatabase();
Cursor csr = db1.rawQuery(query,new String[]{msg});
String value = "-99"; /* assume that if nothing is returned then use -99 */
if(csr.moveToFirst) {
value = csr.getString(0);
}
csr.close(); /* SHOULD ALWAYS CLOSE CURSORS WHEN FINISHED WITH THEM */
....
此外
没有必要关闭数据库然后重新打开它以明显地在可读和可写之间切换。那就是getReadableDatabase 将返回一个可写的数据库,除非有某种原因不能将数据库打开为可写的。如果返回只读数据库,那么后续的getWritableDatabase 很可能会失败,除非以某种方式修复了底层问题。
根据:-
创建和/或打开数据库。这将与 getWritableDatabase() 返回的对象相同,除非某些问题(例如磁盘已满)需要以只读方式打开数据库。在这种情况下,将返回一个只读数据库对象。如果问题得到解决,将来调用 getWritableDatabase() 可能会成功,在这种情况下,只读数据库对象将被关闭,并且将来会返回读/写对象。