Sqlite INSERT 或 return 现有项目
Sqlite INSERT or else return existing item
我有以下数据结构:ID (int), Name (text), Info (text), List (text)。
“列表”是一个枚举列表,作为具有预期语法的字符串:“word1,word2,word3”
我希望能够添加具有以下内容示例的项目:ID=null,Name=Abc,Info=xyz,List=word3
有了这个行为:
- 插入一个项目(如果尚不存在)。
- 如果项目存在(基于“名称”),则更新该项目,如下所示:忽略 ID |覆盖信息 |检查列表是否包含每个给定的单词,如果不包含,则在其后附加“,”作为分隔符。
添加的每个项目将只有 1 个“列表”枚举,但数据库中的条目应该为每个条目收集它们,以便在查询它们时,可能有多个枚举。
所以问题是,我该怎么做?我可以想象这种方法也可能有效:
- 插入一个项目(如果尚不存在)。
- 否则 return 现有项目,让我在 C# 中操作它(自己连接“列表”),然后做一个简单的更新。
在这种情况下,我想知道如何进行“插入或查询”?还是有更好的方法来完成所有这些?
要插入或更新现有的,您可以执行 UPSERT
由于您的 data.List
(顺便说一句,名称选择不当)可能包含枚举的任意组合,您可以使用标志来代替,例如:
public enum Words
{
word1 = 1,
word2 = 2,
word3 = 4
}
现在,您可以使用 bitwise operators 到 set/check/switch 位 :
// Set only the value Words.word1
var myWord = Words.word1; // MyWords = 1
// Use bitwise OR to add the value Words.word3 to the existing ones :
myWord |= Words.word3;
/*
* 001
* | 100
* ------
* 101
*/
// Use bitwise AND to check if the value Words.word2 is already set :
if (myWord & Words.word2 == Words.word2) { /* do something */ }
/*
* 101
* & 010
* ------
* 000
*/
// Use bitwise XOR to switch the bit Words.word3
myWord ^= Words.word3;
/*
* 101
* ^ 100
* ------
* 001
*/
// And once again, with the previous result :
myWord ^= Words.word3;
/*
* 001
* ^ 100
* ------
* 101
*/
然后,在您的数据库中,您可以将字段类型 List
替换为 INT
。
UPDATE yourTable
SET List = List | newValue
WHERE id = 42;
另一种方法是使用规范化数据库,使用 3 个表:
数据:id (int, PK), Name (text), Info (text)
列表:id(整数,PK),列表(文本)
DataList : id_data (int, FK), id_list (int, FK) 以两个 FK 的组合作为主键以确保值的唯一性
可以使用 'upsert' 插入或更新(要求 Name 具有 UNIQUE 约束)。这个查询应该可以解决问题:
INSERT INTO sometable (Name, Info, List)
VALUES(@name,@info,@list)
ON CONFLICT(Name) DO UPDATE SET
Info = excluded.Info,
List = excluded.List;
SELECT ID, Name, Info, List FROM sometable WHERE Name = @name
如果具有给定名称的条目尚不存在,则此查询执行插入;如果有更新 Info 和 List,并在任何情况下选择插入或更新的值。
我有以下数据结构:ID (int), Name (text), Info (text), List (text)。
“列表”是一个枚举列表,作为具有预期语法的字符串:“word1,word2,word3”
我希望能够添加具有以下内容示例的项目:ID=null,Name=Abc,Info=xyz,List=word3
有了这个行为:
- 插入一个项目(如果尚不存在)。
- 如果项目存在(基于“名称”),则更新该项目,如下所示:忽略 ID |覆盖信息 |检查列表是否包含每个给定的单词,如果不包含,则在其后附加“,”作为分隔符。
添加的每个项目将只有 1 个“列表”枚举,但数据库中的条目应该为每个条目收集它们,以便在查询它们时,可能有多个枚举。
所以问题是,我该怎么做?我可以想象这种方法也可能有效:
- 插入一个项目(如果尚不存在)。
- 否则 return 现有项目,让我在 C# 中操作它(自己连接“列表”),然后做一个简单的更新。
在这种情况下,我想知道如何进行“插入或查询”?还是有更好的方法来完成所有这些?
要插入或更新现有的,您可以执行 UPSERT
由于您的 data.List
(顺便说一句,名称选择不当)可能包含枚举的任意组合,您可以使用标志来代替,例如:
public enum Words
{
word1 = 1,
word2 = 2,
word3 = 4
}
现在,您可以使用 bitwise operators 到 set/check/switch 位 :
// Set only the value Words.word1
var myWord = Words.word1; // MyWords = 1
// Use bitwise OR to add the value Words.word3 to the existing ones :
myWord |= Words.word3;
/*
* 001
* | 100
* ------
* 101
*/
// Use bitwise AND to check if the value Words.word2 is already set :
if (myWord & Words.word2 == Words.word2) { /* do something */ }
/*
* 101
* & 010
* ------
* 000
*/
// Use bitwise XOR to switch the bit Words.word3
myWord ^= Words.word3;
/*
* 101
* ^ 100
* ------
* 001
*/
// And once again, with the previous result :
myWord ^= Words.word3;
/*
* 001
* ^ 100
* ------
* 101
*/
然后,在您的数据库中,您可以将字段类型 List
替换为 INT
。
UPDATE yourTable
SET List = List | newValue
WHERE id = 42;
另一种方法是使用规范化数据库,使用 3 个表:
数据:id (int, PK), Name (text), Info (text)
列表:id(整数,PK),列表(文本)
DataList : id_data (int, FK), id_list (int, FK) 以两个 FK 的组合作为主键以确保值的唯一性
可以使用 'upsert' 插入或更新(要求 Name 具有 UNIQUE 约束)。这个查询应该可以解决问题:
INSERT INTO sometable (Name, Info, List)
VALUES(@name,@info,@list)
ON CONFLICT(Name) DO UPDATE SET
Info = excluded.Info,
List = excluded.List;
SELECT ID, Name, Info, List FROM sometable WHERE Name = @name
如果具有给定名称的条目尚不存在,则此查询执行插入;如果有更新 Info 和 List,并在任何情况下选择插入或更新的值。