【问题标题】:How do i properly insert a tag? SQL如何正确插入标签? SQL
【发布时间】:2009-12-26 21:50:44
【问题描述】:

例子

tag  { id PK, name TEXT };
item { id PK, exampleData LONG, tagId LONG //or foreign key depending on provider }

我正在使用 SQLite 和 C#。合适吗

  1. 开始交易
  2. 插入标签
  3. 如果受影响的行 = 0,请选择获取 tag.PK,否则使用 last_insert_rowid
  4. 插入项目

或者上面会有问题吗?我打算改用 MySql 或 TSQL

【问题讨论】:

    标签: c# sql ado.net


    【解决方案1】:

    如果标签不存在,您可以有条件地插入标签:

    insert into tag (name)
    select 'NewTagName'
    where not exists (select * from tag where name = 'NewTagName')
    

    然后,在插入新项目的同时,可以查询标签id:

    insert into item (exampleData, tagid)
    select 'NewData', (select id from tag where name = 'NewTagName')
    

    此方法不需要检索插入行的 id,无需事务即可正常工作。

    【讨论】:

    • 或更简单地说:“select 'NewData', id from tag where name = 'NewTagName'”
    • 已接受,因为这有助于我编写查询,而且您没有说先选择哪个是错误的
    【解决方案2】:

    我通常更喜欢:

    1. 开始交易
    2. select from tag判断标签是否已经存在
    3. 如果不存在,则insert into tag,并获取生成的id(当然是检查插入是否有效)
    4. nsert into item
    5. 提交事务(如果有错误则回滚)

    与您建议的唯一区别是我在尝试插入之前尝试从标签中选择。为什么 ?因为我不喜欢做一个很可能会失败的插入——至少,如果我在标签的名称上有一个唯一索引(你可能应该)

    但它可能不会有太大变化......

    【讨论】:

    • 我忘记写了,是的,它是独一无二的。但是我被告知永远不要先选择,因为它不是写操作,并且在我选择后另一个事务可以插入它,导致插入失败(唯一)或不正确的逻辑来自另一个副本
    • @acidzombie24:但交易会保护你免受这种情况的影响。想象一下,如果您正在编写一个银行应用程序。要将资金从我的帐户转入您的帐户,我必须先select 可用余额。如果balance >= transfer_amount 则进行传输,否则不进行。这同样适用于您的情况。
    • 其实没有。我写了一个测试用例,它失败了。 pastie.org/757356 将其粘贴到 winform 项目中(当我尝试此操作时,网络似乎崩溃了)。由于 Semaphore,没有竞争条件,您可以看到结果是 6 而不是 7。它们都在事务中。
    【解决方案3】:

    我看到您的设计的唯一问题是每个项目只能有 1 个标签。这是你的意图吗?

    否则,您的插入过程很好。您只需要按照 Pascal Martin 的建议检查标签是否已经存在。

    【讨论】:

    • 很好地抓住了单个标签。通常我允许多个,但在这种情况下我没有使用标签并且不确定我应该如何插入数据。
    【解决方案4】:

    我认为你的解决方案没有错,我相信它是正确的并使用它

    但是当你更改为 MySql 或 TSql 使用相同的解决方案

    1- 先插入 2-返回插入行的@@identity“ID” .....

    【讨论】:

      猜你喜欢
      • 2011-07-30
      • 1970-01-01
      • 1970-01-01
      • 2021-01-23
      • 2018-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多