android - SQLite 从另一个数据库中的一行替换一个数据库中的一行
问题描述
我有两个数据库文件,每个文件都有一个共同的单表组成。当第二个数据库中的列设置了标志时,我想用第二个数据库中的类似行替换第一个数据库中的整个表行。我知道如何将一个数据库附加到另一个数据库,但我不知道正确的UPDATE SET
说明。我正在寻找传递基于 kotlin 的 android studio android.database.sqlite
execSQL 调用的字符串指令。
例如:每个数据库中的表有五列命名 -name,address,date,value,flag
我打开主数据库 ( main.db
) 并调用ATTACH DATABASE
附加辅助数据库 ( secondary.db
) 作为 'db2' 然后我想在主数据库中找到与辅助数据库中的行匹配的行名称和地址字段匹配且辅助数据库中的标志字段包含值 1 的数据库。
然后我想用辅助数据库中的行替换主数据库行
我为 execSQL 尝试了以下字符串命令的变体,但未成功:
val TABLE_NAME = "users"
val COL_NAME = "name"
val COL_ADR = "address"
val COL_DATE = "date"
val COL_VAL = "value"
val COL_FLG = "flag"
val db = this.writableDatabase
val attachDb = ("ATTACH DATABASE '$secondaryDbFile' AS 'db2'")
db.execSQL(attachDb)
val updateRows = ("UPDATE $TABLE_NAME SET ($COL_NAME, $COL_ADR, $COL_DATE, $COL_VAL, $COL_FLG) FROM db2.$TABLE_NAME WHERE $COL_FLG = 1")
db.execSQL(updateRows)
我对 SQLite 的掌握不够好,无法构建正确的指令,请帮忙。
解决方案
您在语句中使用的语法UPDATE
是错误的。
您可以使用ROW VALUES并仅更新 columns date
,因为其他 2 列必须匹配。
还使用 2 个表的别名(如和)来区分具有相同名称的列:value
flag
t1
t2
val db = this.writableDatabase
val attachDb = ("ATTACH DATABASE '$secondaryDbFile' AS db2") // no need for single quotes around db2
db.execSQL(attachDb)
val updateRows = "UPDATE $TABLE_NAME AS t1 " +
"SET ($COL_DATE, $COL_VAL, $COL_FLG) = " +
"(SELECT t2.$COL_DATE, t2.$COL_VAL, 1 FROM db2.$TABLE_NAME AS t2 WHERE (t2.$COL_NAME, t2.$COL_ADR) = (t1.$COL_NAME, t1.$COL_ADR) AND t2.$COL_FLG = 1) " +
"WHERE EXISTS (SELECT 1 FROM db2.$TABLE_NAME AS t2 WHERE (t2.$COL_NAME, t2.$COL_ADR) = (t1.$COL_NAME, t1.$COL_ADR) AND t2.$COL_FLG = 1);"
db.execSQL(updateRows)
对于不允许更新表使用别名的 SQLite 版本,请使用以下语句:
val updateRows = "UPDATE $TABLE_NAME " +
"SET ($COL_DATE, $COL_VAL, $COL_FLG) = " +
"(SELECT t2.$COL_DATE, t2.$COL_VAL, 1 FROM db2.$TABLE_NAME AS t2 WHERE (t2.$COL_NAME, t2.$COL_ADR) = ($TABLE_NAME.$COL_NAME, $TABLE_NAME.$COL_ADR) AND t2.$COL_FLG = 1) " +
"WHERE EXISTS (SELECT 1 FROM db2.$TABLE_NAME AS t2 WHERE (t2.$COL_NAME, t2.$COL_ADR) = ($TABLE_NAME.$COL_NAME, $TABLE_NAME.$COL_ADR) AND t2.$COL_FLG = 1);"
如果 SQLite 的版本是 3.33.0+,则语句的语法UPDATE
可以简化,但它在 Android 中不起作用,到目前为止,在 API 级别 31 中支持版本 3.32.2。
这是UPDATE
声明的简化版本(供未来的读者使用):
val updateRows = "UPDATE $TABLE_NAME AS t1 " +
"SET ($COL_DATE, $COL_VAL, $COL_FLG) = (t2.$COL_DATE, t2.$COL_VAL, 1) " +
"FROM db2.$TABLE_NAME AS t2 WHERE (t2.$COL_NAME, t2.$COL_ADR) = (t1.$COL_NAME, t1.$COL_ADR) AND t2.$COL_FLG = 1;"
推荐阅读
- angular - 输入错误:fs.readFileSync 不是函数
- java - 以编程方式创建 VPN 配置文件 Android
- javascript - 手动安装 mysql2 包 - 错误
- maven - Gitlab appengine:仅在 Gitlab 上部署缺少的 JAR
- excel - Angular ui-grid - 导出到 excel 时出错
- config - Google Cloud IoT - 多个配置消息
- node.js - Node.js 电报机器人返回 ECONNREFUSED
- xamarin.forms - 如何将不记名令牌添加到简单 OData 客户端
- python-3.x - Python 中的对象实例是否每个都有其方法的单独实例?
- slack - 在设置 Slack 应用程序时向用户询问 API 密钥的最佳方式是什么?