首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Sql Server 2005 -如果不存在则插入

Sql Server 2005 -如果不存在则插入
EN

Stack Overflow用户
提问于 2011-05-25 15:16:18
回答 2查看 5K关注 0票数 7

在互联网上有很多关于这个常见的“问题”的信息。

解决方案包括:

代码语言:javascript
运行
复制
IF NOT EXISTS() BEGIN INSERT INTO (...) END

在我看来不是线程安全的,你可能会同意。

但是,您能否确认将exist放入单个select的where子句中就可以解决sql引擎中的最高并发问题?这足够了吗?

代码语言:javascript
运行
复制
insert into Table (columns)
select column1, column2, column3
where not exists (select top 1 1 from Table where something)

是否还应该添加一些更高的事务级别,或者这是否可以在默认的事务级别上执行:已提交?

这会在未提交的级别下工作吗?

谢谢!

//稍后添加

我可以假设两个sql都是正确的吗:

1)设置事务隔离级别可重复读取

代码语言:javascript
运行
复制
   IF NOT EXISTS() BEGIN INSERT INTO (...) END

2)设置事务隔离级别可重复读取

代码语言:javascript
运行
复制
insert into Table (columns)
select column1, column2, column3
where not exists (select top 1 1 from Table where something)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-25 15:41:39

使用TRY/CATCH可以避免额外的读取

代码语言:javascript
运行
复制
BEGIN TRY
   INSERT etc
END TRY
BEGIN CATCH
    IF ERROR_NUMBER() <> 2627
      RAISERROR etc
END CATCH

无论是在IF中还是在WHERE中,

  • A NOT EXISTS都将读取表。INSERT需要一个read来检查唯一性

如果您可以丢弃重复项,这是一种高度可伸缩的技术

链接:

在这里查看我的答案:Which is the best choice in delete-insert vs if-update else-insert?

票数 6
EN

Stack Overflow用户

发布于 2011-05-25 15:53:19

要回答更新后的问题,repeatable read仍然不够。

它是您需要的holdlock / serializable级别。

您正在尝试阻止phantoms (在第一次读取时,没有满足条件的行,因此NOT EXISTS返回true,但随后并发事务会插入满足条件的行)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6120819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档