问题描述
我具有以下数据结构:ID(int),名称(文本),Info(文本),List(文本)。
“列表”是具有预期语法的字符串形式的枚举列表:“ word1,word2,word3”
我希望能够使用以下内容示例添加项目:ID = null,Name = Abc,Info = xyz,List = word3
具有以下行为:
- 插入尚不存在的项目。
- 否则,如果存在该项目(基于“名称”),则按如下方式更新:忽略ID |覆盖信息|检查列表中是否包含每个给定的单词,如果没有,请在其后附加“,”作为分隔符。
添加的每个项目将只有1个“列表”枚举,但是数据库中的条目应该为每个条目收集它们,以便在查询它们时,可能会有多个枚举。
问题是,我该怎么做?我可以想象这种方法也可以工作:
在这种情况下,我想知道如何进行“插入或查询”?还是有更好的方法来完成所有这些工作?
解决方法
要插入或更新现有文件,您可以执行UPSERT
由于您的data.List
(名称不正确的名称)可能包含枚举的任意组合,因此您可以改用标志,例如:
public enum Words
{
word1 = 1,word2 = 2,word3 = 4
}
现在,您可以使用bitwise operators来设置/检查/切换位:
// 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),名称(文本),信息(文本)
列表:id(int,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,List FROM sometable WHERE Name = @name
如果具有给定名称的条目尚不存在,则此查询将执行插入操作;如果有,则更新信息和列表,并在任何情况下都选择插入或更新的值。