繁体   English   中英

SQLite 用另一个数据库中的行替换一个数据库中的行

[英]SQLite replace a row in one database from a row in another database

我有两个数据库文件,每个文件都有一个共同的单表结构。 当第二个数据库中的列设置了标志时,我想用第二个数据库中的类似行替换第一个数据库中的整个表行。 我知道如何将一个数据库附加到另一个数据库,但我无法找出正确的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并仅更新列datevalueflag因为其他 2 列必须匹配。
还使用 2 个表的别名(如t1t2 )来区分具有相同名称的列:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM