【问题标题】:Sqlite - SELECT or INSERT and SELECT in one statementSqlite - 在一个语句中选择或插入和选择
【发布时间】:2023-03-22 10:51:01
【问题描述】:

我试图避免编写单独的 SQL 查询来实现以下场景:

我有一个名为 Values 的表:

价值观:

id INT (PK)
data TEXT

我想检查表中是否存在某些数据,如果存在则返回其id,否则插入并返回其id。

(非常)天真的方式是:

select id from Values where data = "SOME_DATA";

如果 id 不为空,则取它。 如果 id 为 null 则:

insert into Values(data) values("SOME_DATA");

然后再次选择它以查看其 id 或使用返回的 id。

我试图在一行中实现上述功能。 我想我已经接近了,但我还不能做到: 到目前为止,我得到了这个:

select id from Values where data=(COALESCE((select data from Values where data="SOME_DATA"), (insert into Values(data) values("SOME_DATA"));

我试图利用这样一个事实,即第二个选择将返回 null,然后将返回 COALESCE 的第二个参数。至今没有成功。我错过了什么?

【问题讨论】:

  • 有很多相似之处,也许答案会来自MySQL线程:P
  • 您想要的行为是特定于供应商的。一些供应商提供了一种从插入/更新命令返回插入/删除值的方法。例如,在 SQL Server 中,您可以使用 OUTPUT 子句输出一个新 ID 而无需锁定,而 MySQL 有 LAST_INSERT_ID 来返回最后一个自动生成的 ID

标签: sql sqlite


【解决方案1】:

您的命令不起作用,因为在 SQL 中,INSERT 不返回值。

如果你在data 列上有一个唯一的约束/索引,如果你盲目地插入值,你可以使用它来防止重复;这使用SQLite's INSERT OR IGNORE extension:

INSERT OR IGNORE INTO "Values"(data) VALUES('SOME_DATE');
SELECT id FROM "Values" WHERE data = 'SOME_DATA';

【讨论】:

  • 我明白了,所以你建议无论如何插入(最坏的情况它会被忽略)然后选择。我试图在一个班轮中做到这一点,但似乎没有奏效。谢谢!
  • 如果数据不是唯一的,忽略如何工作?示例:autoID、A、B、C。INSERT ... VALUES(A, B, C) 插入新行。
  • @Sandburg IGNORE clause 取决于某些约束(唯一或主键)。如果没有这样的约束,询问数据是否已经存在于表中是没有意义的。
  • 这确实会进行两次查找吗?
  • @Timmmm 没有办法通过一次查找来做到这一点。在任何情况下,一个 UNIQUE 或 PK 约束都意味着一个索引,并且该值将被缓存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 1970-01-01
  • 2017-05-29
相关资源
最近更新 更多