【问题标题】:Sqlite INSERT or else return existing itemSqlite INSERT 或返回现有项目
【发布时间】:2021-01-30 19:04:01
【问题描述】:

我有以下数据结构:ID(int)、Name(文本)、Info(文本)、List(文本)。
"List" 是一个字符串枚举列表,其语法为:"word1,word2,word3"

我希望能够添加具有以下内容示例的项目:ID=null、Name=Abc、Info=xyz、List=word3
随着这种行为:

  • 如果尚不存在,请插入一个项目。
  • 如果项目存在,则更新项目(基于“名称”),如下所示:忽略 ID |覆盖信息 |检查列表是否包含每个给定的单词,如果不包含,则将其附加“,”作为分隔符。

添加的每个项目将只有 1 个“列表”枚举,但数据库中的条目应该为每个条目收集它们,因此当查询它们时,可能有多个枚举。

所以问题是,我该怎么做?我可以想象这种方法也可能有效:

  • 如果尚不存在,请插入一个项目。
  • 否则返回现有项目,让我在 C# 中操作它(我自己连接“列表”),然后进行简单的更新。

在这种情况下,我想知道如何进行“插入或其他查询”?还是有更好的方法来完成这一切?

【问题讨论】:

  • 是的,更好的方法是使用关系数据库作为关系数据库......并在另一个表中创建列表
  • @Selvin - 即使这些只是枚举的重复元素?它们由一个 ID、参考 ID 和一个字节或字符串组成,每个主要条目将有大约 1-5 个。但它们没有任何独特的信息,只是大约 5 个项目的副本。

标签: c# sqlite insert-update


【解决方案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), Name (text), Info (text)

列表:id(int,PK),列表(文本)

DataList : id_data(int, FK), id_list(int, FK) 以两个FK的组合为主键,保证值的唯一性

【讨论】:

  • 啊,再次感谢您!使用标记的枚举是一个很好的解决方案。这正是我需要的。顺便说一句,我仅在此示例中使用了名称“列表”,无法想出更好的抽象名称。
【解决方案2】:

使用 '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(如果有),并在任何情况下选择插入或更新的值。

【讨论】:

    猜你喜欢
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 2017-02-26
    相关资源
    最近更新 更多