问题标签 [upsert]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
9 回答
52700 浏览

sql - 在 SQL Server 上插入更新存储过程

我编写了一个存储过程,如果记录存在,它将进行更新,否则它将进行插入。它看起来像这样:

我以这种方式编写它的逻辑是,更新将使用 where 子句执行隐式选择,如果返回 0,则插入将发生。

这样做的替代方法是进行选择,然后根据返回的行数进行更新或插入。我认为这是低效的,因为如果您要进行更新,它将导致 2 次选择(第一次显式选择调用和第二次隐式在更新的位置)。如果proc要进行插入,那么效率就没有区别。

我的逻辑在这里合理吗?这是您将插入和更新组合到存储过程中的方式吗?

0 投票
23 回答
793851 浏览

sql - SQL Server 上的 INSERT OR UPDATE 解决方案

假设表结构为MyTable(KEY, datafield1, datafield2...)

通常我想更新现有记录,或者如果它不存在则插入一条新记录。

本质上:

写这个的最佳执行方式是什么?

0 投票
11 回答
476566 浏览

sql - Oracle:如何 UPSERT(更新或插入表?)

UPSERT 操作更新或插入表中的行,具体取决于表是否已有与数据匹配的行:

由于 Oracle 没有特定的 UPSERT 语句,那么最好的方法是什么?

0 投票
7 回答
35077 浏览

nhibernate - 如何使用 NHibernate 插入或更新(或覆盖)记录?

无论它是否已经存在,我都需要向数据库写入一行。在使用 NHibernate 之前,这是通过存储过程完成的。该过程将尝试更新,如果没有行被修改,它将回退到插入。这很有效,因为应用程序并不关心记录是否存在。

使用 NHibernate,我发现的解决方案需要加载实体并对其进行修改,或者删除实体以便插入新实体。应用程序必须关心记录是否已经存在。有办法解决吗?

身份证重要吗?

分配的 ID

该对象有一个关键字作为分配的 id,并且是表中的主键。

我了解 SaveOrUpdate() 将根据 Id 适当调用 Save() 或 Update() 方法。使用分配的 id,这将不起作用,因为 id 不是未保存的值。但是,可以将版本或时间戳字段用作指示符。实际上,这无关紧要,因为这仅反映内存中的对象是否与数据库中的记录相关联;它不指示该记录是否存在于数据库中。

生成的 ID

如果分配的 id 确实是问题的原因,我可以使用生成的 id 而不是关键字作为主键。这将避免 NHibernate 插入/更新问题,因为它总是会有效地插入。但是,我仍然需要防止重复的关键字。使用关键字列上的唯一索引,即使主键不同,它仍然会为重复关键字抛出异常。

另一种方法?

也许问题不在于 NHibernate,而在于建模的方式。与应用程序的其他领域不同,这更以数据为中心,而不是以对象为中心。很高兴 NHibernate 使其易于读/写并消除了存储过程。但是,不考虑现有值而简单地编写的愿望与对象身份模型的模型不太吻合。有没有更好的方法来解决这个问题?

0 投票
5 回答
63921 浏览

sql - DB2 是否有“插入或更新”语句?

从我的代码(Java)中,我想确保在我的代码执行后数据库(DB2)中存在一行。

我的代码现在执行 a select,如果没有返回结果,它执行insert. 我真的不喜欢这段代码,因为它让我在多线程环境中运行时遇到并发问题。

我想做的是将这个逻辑放在 DB2 中,而不是放在我的 Java 代码中。DB2 有insert-or-update声明吗?或者我可以使用的任何类似的东西?

例如:

另一种方法可能是始终执行插入并捕获“SQL-code -803 主键已经存在”,但如果可能的话,我想避免这种情况。

0 投票
6 回答
5430 浏览

sql - 在 sql (Firebird/MySql) 中更新/插入记录的正确/最快方法是什么

我需要一些 SQL 来更新数据库中的记录(如果存在)并在不存在时插入它,环顾四周似乎有几种解决方案,但我不知道什么是正确/可接受的方法来做到这一点。

理想情况下,我希望它可以在 Firebird 2 和 MySQL 5 上运行,因为需要对两个数据库运行更新,如果在两个数据库上运行相同的 SQL 会更简单,如果它可以在更多数据库上运行,那将是一个加号.

速度和可靠性也是考虑因素,在这种情况下可靠性超过速度,但它可能用于快速连续更新 1000 条记录(在不同的表上)。

有什么服从吗?

0 投票
19 回答
338409 浏览

sql - SQLite - UPSERT *not* INSERT 或 REPLACE

http://en.wikipedia.org/wiki/Upsert

在 SQL Server 上插入更新存储过程

在 SQLite 中是否有一些我没有想到的聪明方法?

基本上,如果记录存在,我想更新四列中的三列,如果不存在,我想用第四列的默认(NUL)值插入记录。

ID 是主键,因此 UPSERT 永远只有一条记录。

(我试图避免 SELECT 的开销以确定我是否需要 UPDATE 或 INSERT 显然)

建议?


我无法在 SQLite 站点上确认 TABLE CREATE 的语法。我还没有建立一个演示来测试它,但它似乎不受支持。

如果是,我有三列,所以它实际上看起来像:

但前两个 blob 不会引起冲突,只有 ID 会所以我假设 Blob1 和 Blob2 不会被替换(根据需要)


当绑定数据是一个完整的事务时,SQLite 中的 UPDATE,这意味着要更新的每个发送的行都需要: Prepare/Bind/Step/Finalize 语句与允许使用重置功能的 INSERT 语句不同

语句对象的生命周期是这样的:

  1. 使用 sqlite3_prepare_v2() 创建对象
  2. 使用 sqlite3_bind_ 接口将值绑定到主机参数。
  3. 通过调用 sqlite3_step() 运行 SQL
  4. 使用 sqlite3_reset() 重置语句,然后返回步骤 2 并重复。
  5. 使用 sqlite3_finalize() 销毁语句对象。

UPDATE 我猜与 INSERT 相比速度很慢,但它与使用主键的 SELECT 相比如何?

也许我应该使用 select 来读取第 4 列(Blob3),然后使用 REPLACE 编写一条新记录,将原始第 4 列与前 3 列的新数据混合?

0 投票
3 回答
8770 浏览

stored-procedures - 如何在合并语句中使用过程参数

我正在创建一个使用合并语句(upsert)更新/插入表的过程。现在我遇到了一个问题:使用过程参数我必须执行此 upsert。

过程 xyz( a in table.a%type,b in table.b%type,....) 是一些局部变量;开始使用 source_table 合并到 target_table -而不是源表,我必须 在匹配时在(表中主键的条件)上使用过程参数,然后在不匹配时更新表,然后插入表;结束 xyz;那么如何在合并语句中使用过程参数而不是源表?或建议我查询以获取过程参数并将其用作源表值。

请帮帮我。提前致谢。

0 投票
2 回答
270 浏览

sql - 如何在查询中使用过程参数

如何使用查询访问同一过程中的过程参数
,例如:请参阅此过程

在上述过程和合并语句中,我需要一个查询,以便它使用参数值作为表引用,并根据给定的条件使用这些值更新或插入到表中。

请帮帮我。提前致谢

0 投票
10 回答
148856 浏览

mysql - 我如何更新表中的一行或如果它不存在则插入它?

我有以下计数器表:

我想增加一个计数器,或者如果相应的行尚不存在,则将其设置为零。有没有办法在标准 SQL 中没有并发问题的情况下做到这一点?该操作有时是事务的一部分,有时是单独的。

如果可能,SQL 必须在 SQLite、PostgreSQL 和 MySQL 上未经修改地运行。

搜索产生了几个想法,这些想法要么存在并发问题,要么特定于数据库:

  • 尝试INSERT一个新的行,UPDATE如果有错误。不幸的是,错误INSERT中止当前事务。

  • UPDATE行,如果没有行被修改,则为INSERT新行。

  • MySQL 有一个ON DUPLICATE KEY UPDATE子句。

编辑:感谢所有伟大的答复。看起来 Paul 是对的,而且没有一种单一的、可移植的方式来做到这一点。这让我很惊讶,因为这听起来像是一个非常基本的操作。