简体   繁体   English

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

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

I have two database files each with a common single table makeup.我有两个数据库文件,每个文件都有一个共同的单表结构。 I'd like to replace an entire table row in the first database with the similar row from the second database when a column in the second database has a flag set.当第二个数据库中的列设置了标志时,我想用第二个数据库中的类似行替换第一个数据库中的整个表行。 I know how to Attach one database to another but I can't figure out the proper UPDATE SET instruction.我知道如何将一个数据库附加到另一个数据库,但我无法找出正确的UPDATE SET指令。 I'm looking for string instruction to pass in a kotlin based android studio android.database.sqlite execSQL call.我正在寻找字符串指令以传递基于 kotlin 的 android studio android.database.sqlite execSQL 调用。

For example: The table in each database has five columns named - name,address,date,value,flag I open the main database ( main.db ) and call ATTACH DATABASE to attach secondary database ( secondary.db ) as 'db2' I then want to find a row in the main database that matches a row in the secondary database where the name and address fields match and the flag field in the secondary database contains a value of 1.例如:每个数据库中的表有五个名为name,address,date,value,flag的列 我打开主数据库 ( main.db ) 并调用ATTACH DATABASE将辅助数据库 ( secondary.db ) 附加为 'db2' 我然后想在主数据库中找到与辅助数据库中名称和地址字段匹配且辅助数据库中的标志字段包含值 1 的行匹配的行。
I then want to replace the main database row with the row from the secondary database然后我想用辅助数据库中的行替换主数据库行

I unsuccessfully tried variations of the following string command for execSQL:我为 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) 

I don't have a good enough grasp of SQLite to construct the proper instruction, please help.我对 SQLite 的掌握不够好,无法构建正确的指令,请帮忙。

The syntax that you use in the UPDATE statement is wrong.您在UPDATE语句中使用的语法是错误的。
You can use ROW VALUES and update only the columns date , value and flag since the other 2 columns must match.您可以使用ROW VALUES并仅更新列datevalueflag因为其他 2 列必须匹配。
Also use aliases for the 2 tables (like t1 and t2 ) to distinguish the columns that have the same names:还使用 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)

For versions of SQLite that do not allow an alias for the updated table, use this statement:对于不允许更新表别名的 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);"

The syntax of the UPDATE statement could be simplified if the version of SQLite was 3.33.0+, but it would not work in Android which up till now, in API Level 31 supports version 3.32.2.如果SQLite的版本是3.33.0+, UPDATE语句的语法可以简化,但是在Android中是不行的,目前API Level 31支持3.32.2版本。

This is the simplified version of the UPDATE statement (for future readers):这是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