想象我有一张桌子(冰箱),上面有列:(日期(PK)、水果、蔬菜、淀粉、糖果)。这是一个示例行:
date | fruits | veggies | starches | sweets
20180220 | melon | potato | pasta | fudge
我只想用以下内容插入或替换冰箱中的某些列:
> INSERT or REPLACE into refrigerator (date, fruits, veggies, starches) VALUES ("20180220", "apple", "carrot", "bread")
当我这样做时,如果我没有为 (sweets) 指定值,它将被 NULL 覆盖。
date | fruits | veggies | starches | sweets
20180220 | apple | carrot | bread | NULL
不替换我指定的值的正确方法是什么?
我确信这是显而易见的事情。随意嘲笑我吧。
现在它按预期工作,并且如果该行不存在也会插入该行。 如果没有 UNION ALL,它将无法正常工作。第一个 SELECT 使用 COALESCE() 在行确实存在的情况下保留现有列值。第二个带有 NOT EXISTS 的 SELECT 涵盖了该行不存在的情况,因此它构造了一个。因此,UNION ALL 只返回 1 行:来自现有行的“合并”行,或全新的行。然后,REPLACE INTO 通过主键将此合并/创建的行替换回表中。
CREATE TABLE refrigerator
(
date TEXT(8) NOT NULL PRIMARY KEY
, fruits TEXT(50) NULL
, veggies TEXT(50) NULL
, starches TEXT(50) NULL
, sweets TEXT(50) NULL
);
INSERT INTO refrigerator (date, fruits, veggies, starches, sweets)
VALUES ("20180220", "melon", "potato", "pasta", "fudge");
REPLACE INTO refrigerator (date, fruits, veggies, starches, sweets)
SELECT
date
, COALESCE("apple", fruits) as fruits
, COALESCE("carrot", veggies) as veggies
, COALESCE("bread", starches) as starches
, COALESCE(NULL, sweets) as sweets
FROM
refrigerator
WHERE
date = "20180220"
UNION ALL
SELECT
T.date, T.fruits, T.veggies, T.starches, T.sweets
FROM
(
SELECT
"20180220" as date
, "apple" as fruits
, "carrot" as veggies
, "bread" as starches
, NULL as sweets
) AS T
WHERE
NOT EXISTS (SELECT * FROM refrigerator AS R WHERE R.date = T.date);
SELECT date, fruits, veggies, starches, sweets FROM refrigerator;
这是一个 SQL Fiddle:冰箱 SQL Fiddle
我用两行解决了这个问题。
UPDATE refrigerator SET fruits='apple', veggies='carrot', starches='bread' WHERE date='20180220';
然后
INSERT or IGNORE INTO refrigerator (fruits, veggies, starches) VALUES ("apple", "carrot", "bread");
我在逆向思考问题,这可能使这里的答案过于复杂。如果存在带有(日期)的行,我首先更新特定列。如果不存在,下一行将插入包含所需信息的新行 - 如果存在则忽略它。
这种方式可能会出现任何并发症吗?我已经测试过了,到目前为止一切都按预期工作。
要更新现有数据,请使用更新
https://www.tutorialspoint.com/sqlite/sqlite_update_query.htm
将水果列更新为苹果使用的示例
更新冰箱套装水果 = 'Apple',其中 YOURWHERECLAUSEHERE
至于如果你什么都不提供的话,插入什么是期望插入的?该程序不会读懂你的想法。
提出问题时,SQLite 中尚不提供此功能。
我使用 UPSERT 解决了这个问题 (https://sqlite.org/lang_upsert.html)。
INSERT INTO refrigerator (date, fruits, veggies, starches) VALUES ("20180220", "apple", "carrot", "bread")
ON CONFLICT(date) DO UPDATE SET fruits="apple", veggies="carrot", starches="bread";
这会尝试将数据插入数据库,当由于唯一性约束而发生冲突时,它会执行更新;因此现有数据保持不变,仅更改指定的列。