SQL Server 2005-如果不存在则插入

问题描述:

互联网上有很多有关此常见问题"的信息.

There is lots of information in the internet regarding this common "problem".

解决方案,例如:

IF NOT EXISTS() BEGIN INSERT INTO (...) END

我认为不是线程安全的,您可能会同意.

are not thread-safe in my opinion and you will probably agree.

但是,您能否确认将现存项放入一个select的where子句中将解决sql引擎中最高并发性的问题? 够了吗?

However could you confirm that putting the exist into the where clause of one single select would solve the problem of the highest concurrency in sql engine? Is it enough?

insert into Table (columns)
select column1, column2, column3
where not exists (select top 1 1 from Table where something)

应该在那里也添加一些更高的交易级别,或者 可以在默认的一个(已提交)上执行吗?

Should be there also added some higher transaction level or can this be executed on a default one: committed?

这项工作会处于未提交的级别吗?

Would this work under uncommitted level?

谢谢!

//稍后添加

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

Can i assume that both sql' are correct:

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

1) set transaction isolation level repeatable read

   IF NOT EXISTS() BEGIN INSERT INTO (...) END

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

2) set transaction isolation level repeatable read

insert into Table (columns)
select column1, column2, column3
where not exists (select top 1 1 from Table where something)

通过TRY/CATCH,您可以避免多余的阅读

With TRY/CATCH you can avoid the extra read

BEGIN TRY
   INSERT etc
END TRY
BEGIN CATCH
    IF ERROR_NUMBER() <> 2627
      RAISERROR etc
END CATCH

  • 一个不存在的表将读取该表,无论是在IF还是WHERE中
  • INSERT要求读取内容以检查唯一性
  • 如果您可以丢弃重复项,那么这是一种高度可扩展的技术

    If you can discard duplicates, this is a highly scalable technique

    链接:

    • See my answers here: Only inserting a row if it's not already there and SQL Server 2008: INSERT if not exits, maintain unique column
    • If you requires UPDATEs too: Which is the best choice in delete-insert vs if-update else-insert?