SQLite:INSERT或REPLACE某些列,不要用NULL覆盖其他列?

时间:2018-02-21 00:15:57

标签: sql sqlite

想象一下,我有一个带有柱子的桌子(冰箱):(日期(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")

当我这样做时,如果我没有为(糖果)指定一个值,它将被NULL覆盖。

date     | fruits | veggies | starches | sweets 
20180220 | apple  | carrot  |  bread   | NULL

这样做的正确方法是什么,不能替换我指定的值?

我确信这显然是显而易见的。随意嘲笑我。

3 个答案:

答案 0 :(得分:5)

现在它按预期工作,如果行不存在,也会插入行。 如果没有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小提琴:Refrigerator SQL Fiddle

Results

答案 1 :(得分:3)

我用两行解决了这个问题。

UPDATE refrigerator SET fruits='apple', veggies='carrot', starches='bread' WHERE date='20180220';

然后

INSERT or IGNORE INTO refrigerator (fruits, veggies, starches) VALUES ("apple", "carrot", "bread");

我正在考虑倒退的事情,这可能会让答案过于复杂。如果存在具有(date)的行,我首先更新特定列。如果不存在,下一行将插入带有所需信息的新行 - 如果存在则忽略它。

这种方式可能会出现任何并发症吗?我已经对它进行了测试,到目前为止一切正常。

答案 2 :(得分:-1)

要更新现有数据,请使用更新

https://www.tutorialspoint.com/sqlite/sqlite_update_query.htm

将fruits列更新为apple使用的示例

更新refigerator set fruits =' Apple' YOURWHERECLAUSEHERE

如果您不提供任何内容,请插入预期插入的内容?该计划不会读你的想法。