【问题标题】:insert conditionally get row id?有条件地插入获取行ID?
【发布时间】:2013-08-20 16:52:48
【问题描述】:

我想创建一个主题,但前提是主题在该部分中是唯一的。然后我想获取线程的行ID。我如何安全地写它?我的想法是这样的

connection.Query<long>(@"insert into thread(section, subject, body) 
    select @section,@subject,@body
    where not exists in (select 1 from thread where section=@section and subject=@subject;
    select last_insert_rowid()", new {...}).First();

问题是我不知道 last_insert_rowid 是来自过去还是来自我的插入语句。如何安全地编写此查询

【问题讨论】:

  • 在 SQLite 方面我恐怕帮不上忙。如果您知道所需的 SQL,我可以就任何 dapper 提供建议。
  • @MarcGravell:我认为条件插入/返回 id 会有一些 sql 成语。我很震惊没有人回复。我碰巧知道 sqlite 会锁定我读取的值,前提是它们在事务中。我想我会做多个查询/执行

标签: .net sql sqlite dapper


【解决方案1】:

如果理解正确,您可以使用OR IGNORE 语法。为了让它工作,你必须对 sectionsubject 有一个 UNIQUE 约束

CREATE TABLE thread
(id INTEGER PRIMARY KEY, 
 section INT, 
 subject TEXT(128), 
 body TEXT(256),
 UNIQUE (section, subject));

现在忽略违反约束之一的行

INSERT OR IGNORE INTO thread (section, subject, body)
VALUES (1, 'Subject1', 'Body1');

现在,如果插入成功,那么 LAST_INSERT_ROWID() 将返回插入行的 id,但如果它与 sectionsubject 重复,则插入失败将返回 0

【讨论】:

  • 不正确。我的insert or ignore into ...; select last_insert_rowid() 似乎返回了 1 而不是 0。我有一个独特的包含阻止插入但它没有返回 0。
  • 这意味着我假设您首先在同一会话中成功插入,然后第二次被忽略。现在要克服这一建议是在插入之前存储LAST_INSERT_ROWID() 的值,然后在插入之后再次调用它并与存储的值进行比较。如果当前值大于存储的值,那么您有一个成功的插入和一个新的 id。顺便说一句,您不能使用多插入。您应该一次发出一个插入语句。
猜你喜欢
  • 2011-03-19
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
  • 2015-03-01
  • 2014-01-29
  • 2014-12-22
相关资源
最近更新 更多