房间更新多个字段
Room Update Multiple Fields
我想将 table 1
中的某些字段更新为与另一个 table
(甚至子查询)中的值相同。问题是当有超过 1 个字段时,我在 DAO
更新查询中得到 compilation error
。
您可以在下面查看代码(重写为通用代码):
@Query("UPDATE table1 " +
" SET (field1, field2) = " +
" (SELECT SUM(table2.foreign_field1) as summaryForeign_field1, table2.foreign_field2 " +
" FROM table2 " +
" WHERE table1.id = table2.id " +
" GROUP BY table2.foreign_field2 ) ")
void setFieldsInTable1();
我用 SQLite Update Query Ref 中的注释检查了查询,并尝试了 DB Browser
中的代码 SQLite
,它工作正常。
如有任何帮助,我们将不胜感激。
您忘记了第 4 行的 +
。
如果这只是一个 copy/past 错误,那么您的原始查询中一定有问题,您在尝试使其成为您的问题的通用查询时将其删除。
这应该有效,这是一个有效的例子:
代码:
BEGIN TRANSACTION;
/* Create tables */
CREATE TABLE table1(
id integer PRIMARY KEY,
field1 text,
field2 text
);
CREATE TABLE table2(
id integer PRIMARY KEY,
field1 text,
foreign_field1 integer,
FOREIGN KEY(foreign_field1) REFERENCES table1(id)
);
/* Create few records */
INSERT INTO table1 VALUES(1,'Tom', 'French');
INSERT INTO table1 VALUES(2,'Lucy', 'American');
INSERT INTO table1 VALUES(3,'Frank', 'English');
INSERT INTO table1 VALUES(4,'Jane', 'Polish');
INSERT INTO table1 VALUES(5,'Robert', 'French');
INSERT INTO table2 VALUES(1,'Monday', 3);
INSERT INTO table2 VALUES(2,'Wednesday', 5);
INSERT INTO table2 VALUES(3,'Friday', 1);
INSERT INTO table2 VALUES(4,'Tuesday', 4);
INSERT INTO table2 VALUES(5,'Monday', 1);
COMMIT;
/* Display records from the table1 */
SELECT * FROM table1;
/* Update records from table1 */
UPDATE table1
SET (field1, field2) = (
SELECT
SUM(table2.foreign_field1) as summaryForeign_field1,
table2.field1
FROM table2
WHERE table1.id = table2.id
GROUP BY table2.field1
);
/* Check that the update has been executed correctly */
SELECT * FROM table1;
因此,也许可以尝试构建一个更接近您的原始查询的在线最小示例。
EDIT :好的,根据您的评论我已经测试并且可以在我的项目中重现该问题,实际上它无法编译,错误是:
error: no viable alternative at input 'update test SET (name,'
extraneous input ')' expecting {, ';', ',', '=', '*', '+', '-',
'||', '/', '%', '<<', '>>', '&', '|', '<', '<=', '>', '>=', '==',
'!=', '<>', ...}
不幸的是,我认为这是一个房间限制。也许您可以向 Google 提交问题以获取有关此的更多信息。
同时,您可以尝试使用 RawQuery(如文档中所述,它必须 return 非空类型,但您可以 return 假字符串或空 POJO ) :
@RawQuery
String setFieldsInTable1(SupportSQLiteQuery query);
然后像这样使用它:
SimpleSQLiteQuery query = new SimpleSQLiteQuery("UPDATE table1 SET ...");
yourDao.setFieldsInTable1(query);
另一种解决方案是以这种方式使用 2 个子查询:
UPDATE table1
SET field1 = (
SELECT SUM(table2.foreign_field1)
FROM table2
WHERE table1.id = table2.id
GROUP BY table2.foreign_field2
),
field2 = (
SELECT table2.foreign_field2
FROM table2
WHERE table1.id = table2.id
);
另外,根据您的应用程序工作流程,您可以在代码中修改您的实体,然后使用 Update
界面更新它:
@Update
void update(Table1Entity... table1Entities);
我想将 table 1
中的某些字段更新为与另一个 table
(甚至子查询)中的值相同。问题是当有超过 1 个字段时,我在 DAO
更新查询中得到 compilation error
。
您可以在下面查看代码(重写为通用代码):
@Query("UPDATE table1 " +
" SET (field1, field2) = " +
" (SELECT SUM(table2.foreign_field1) as summaryForeign_field1, table2.foreign_field2 " +
" FROM table2 " +
" WHERE table1.id = table2.id " +
" GROUP BY table2.foreign_field2 ) ")
void setFieldsInTable1();
我用 SQLite Update Query Ref 中的注释检查了查询,并尝试了 DB Browser
中的代码 SQLite
,它工作正常。
如有任何帮助,我们将不胜感激。
您忘记了第 4 行的 +
。
如果这只是一个 copy/past 错误,那么您的原始查询中一定有问题,您在尝试使其成为您的问题的通用查询时将其删除。
这应该有效,这是一个有效的例子:
代码:
BEGIN TRANSACTION;
/* Create tables */
CREATE TABLE table1(
id integer PRIMARY KEY,
field1 text,
field2 text
);
CREATE TABLE table2(
id integer PRIMARY KEY,
field1 text,
foreign_field1 integer,
FOREIGN KEY(foreign_field1) REFERENCES table1(id)
);
/* Create few records */
INSERT INTO table1 VALUES(1,'Tom', 'French');
INSERT INTO table1 VALUES(2,'Lucy', 'American');
INSERT INTO table1 VALUES(3,'Frank', 'English');
INSERT INTO table1 VALUES(4,'Jane', 'Polish');
INSERT INTO table1 VALUES(5,'Robert', 'French');
INSERT INTO table2 VALUES(1,'Monday', 3);
INSERT INTO table2 VALUES(2,'Wednesday', 5);
INSERT INTO table2 VALUES(3,'Friday', 1);
INSERT INTO table2 VALUES(4,'Tuesday', 4);
INSERT INTO table2 VALUES(5,'Monday', 1);
COMMIT;
/* Display records from the table1 */
SELECT * FROM table1;
/* Update records from table1 */
UPDATE table1
SET (field1, field2) = (
SELECT
SUM(table2.foreign_field1) as summaryForeign_field1,
table2.field1
FROM table2
WHERE table1.id = table2.id
GROUP BY table2.field1
);
/* Check that the update has been executed correctly */
SELECT * FROM table1;
因此,也许可以尝试构建一个更接近您的原始查询的在线最小示例。
EDIT :好的,根据您的评论我已经测试并且可以在我的项目中重现该问题,实际上它无法编译,错误是:
error: no viable alternative at input 'update test SET (name,' extraneous input ')' expecting {, ';', ',', '=', '*', '+', '-', '||', '/', '%', '<<', '>>', '&', '|', '<', '<=', '>', '>=', '==', '!=', '<>', ...}
不幸的是,我认为这是一个房间限制。也许您可以向 Google 提交问题以获取有关此的更多信息。
同时,您可以尝试使用 RawQuery(如文档中所述,它必须 return 非空类型,但您可以 return 假字符串或空 POJO ) :
@RawQuery
String setFieldsInTable1(SupportSQLiteQuery query);
然后像这样使用它:
SimpleSQLiteQuery query = new SimpleSQLiteQuery("UPDATE table1 SET ...");
yourDao.setFieldsInTable1(query);
另一种解决方案是以这种方式使用 2 个子查询:
UPDATE table1
SET field1 = (
SELECT SUM(table2.foreign_field1)
FROM table2
WHERE table1.id = table2.id
GROUP BY table2.foreign_field2
),
field2 = (
SELECT table2.foreign_field2
FROM table2
WHERE table1.id = table2.id
);
另外,根据您的应用程序工作流程,您可以在代码中修改您的实体,然后使用 Update
界面更新它:
@Update
void update(Table1Entity... table1Entities);