说我有一个包含三列的表GSON
:<input id="name" name="name" class="form-control"
required minlength="4" appForbiddenName="bob"
[(ngModel)]="hero.name" #name="ngModel" >
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert alert-danger">
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors.forbiddenName">
Name cannot be Bob.
</div>
</div>
,MyTableName
,COLUMN_NAME_A
(为简化起见,只有三列,实际上我可能有数十列)。在我当前的实现中,当我插入新行时,所有列都将被覆盖。如何仅覆盖新值不为null的列。一种方法是检查新值,如果它为NULL,则从表中读取该值并将其重写。
有没有更简单和/或通用的方法?
COLUMN_NAME_B
答案 0 :(得分:0)
我认为您有2个选择。第一个比较丑陋,而且速度可能较慢,但据我所知,它是标准SQL并得到广泛支持。第二个不是标准的,但是从3.24.0版本开始,SQLite支持它。
基于this answer,您可以执行类似的操作
INSERT OR REPLACE INTO MyTableName
VALUES (
'example_id',
COALESCE(100, (SELECT COLUMN_NAME_B from MyTableName WHERE COLUMN_NAME_A = 'example_id')),
COALESCE(1.0, (SELECT COLUMN_NAME_C from MyTableName WHERE COLUMN_NAME_A = 'example_id'))
);
这很简单,但也很丑陋,而且可能很慢。您拥有的列越多,您需要执行的嵌入选择就越多(实际上,您只需要具有潜在空值的列就可以使用它们,但仍然如此),而行越多,选择所花费的时间就越多。
但是,如果您使用的是SQLite 3.24.0或更高版本,则可以使用所谓的upsert syntax
INSERT INTO MyTableName
VALUES ('example_id', 100, 1.0)
ON CONFLICT(COLUMN_NAME_A) DO UPDATE SET
COLUMN_NAME_B = COALESCE(EXCLUDED.COLUMN_NAME_B, COLUMN_NAME_B),
COLUMN_NAME_C = COALESCE(EXCLUDED.COLUMN_NAME_C, COLUMN_NAME_C);
其中EXCLUDED.COLUMN_NAME_表示要插入的新值(在我们解决冲突之前,此值已被“排除”)。