【问题标题】:SQL Server 2000 equivalent for ON DUPLICATE KEY?SQL Server 2000 等效于 ON DUPLICATE KEY?
【发布时间】:2011-01-14 06:32:40
【问题描述】:

是否有与 MySQL 的 ON DUPLICAT KEY 子句等效的 SQL Server 2000 功能? This Answer 引导我查看了替代触发器构造,但示例看起来很笨重,并且功能将隐藏在触发器中,而不是直接在存储过程中。

FWIW:我正在尝试为每分钟摘要创建一个统计表,这样我就可以调用一个过程来记录一个动作发生的事实并在适当的分钟内增加计数器。

【问题讨论】:

  • 如果您希望在已存在重复项时忽略该值,我不明白您为什么要分配一个 ID。我会从插入中省略 ID 列,并在必要时获取 @@IDENTITY 值。
  • 天啊:谁说过关于 ID 的事?我说的是由统计数据所针对的分钟组成的键。

标签: sql mysql sql-server


【解决方案1】:

我用这个:

begin tran;

update ... where ... ;

if @@rowcount = 0
  insert ...
commit tran;

据我了解,有了适当的索引,更新会放置适当的范围锁,以防止其他人同时插入相同的内容。

【讨论】:

  • 您是否需要更新的 HoldLock 提示以确保在 INSERT 之前不会释放索引上的锁定?
  • @Iain 你是对的,需要一个保持锁,否则这是一个 RACE 问题,如果两个事务正在做同样的事情,@@rowcount 将为零并且两者都会插入。
【解决方案2】:

更新

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

INSERT ... WHERE NOT EXISTS (SELECT 1 FROM table WHERE id = ?)

合并

但我认为只有在 SQL 2003 中

MERGE INTO table_name USING table_name ON (condition)
  WHEN MATCHED THEN
  UPDATE SET column1 = value1 [, column2 = value2 ...]
  WHEN NOT MATCHED THEN
  INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...])

http://en.wikipedia.org/wiki/Merge_(SQL)

【讨论】:

  • 根据 2003 年的 wiki(我在答案中的链接):“它是在 SQL:2003 标准中正式引入的”
  • 我无法让 upsert 示例的语法在 SQL 2000 中工作。它应该能够在那里工作吗?
  • “SQL 2003 标准”与 SQL Server 2008 完全不同。
【解决方案3】:

也很笨重,但你可以在你的程序中这样做:

insert ... where not exists (...);

update ....;

知道您的插入将在数据是新的时触发,而您的更新仅在数据存在时才会触发。

【讨论】:

  • 是否足够原子,我可以从多个线程运行它?然后我应该插入一个 0 计数并始终调用插入和更新吗?
猜你喜欢
  • 2017-06-12
  • 2015-01-20
  • 1970-01-01
  • 2010-11-14
  • 2013-05-13
  • 2020-07-20
  • 2018-04-07
  • 2011-02-12
相关资源
最近更新 更多