sql-server - T-SQL 插入或更新

标签 sql-server tsql insert-update

我有一个关于 SQL Server 性能的问题。

假设我有一个表persons,其中包含以下列:idnamesurname

现在,我想在此表中插入一个新行。规则如下:

  1. 如果表中不存在id,则插入该行。

  2. 如果 id 存在,则更新。

我这里有两个解决方案:

第一:

update persons
  set id=@p_id, name=@p_name, surname=@p_surname
where id=@p_id
if @@ROWCOUNT = 0 
  insert into persons(id, name, surname)
  values (@p_id, @p_name, @p_surname)

第二:

if exists (select id from persons where id = @p_id)
  update persons
    set id=@p_id, name=@p_name, surname=@p_surname
  where id=@p_id
else
  insert into persons(id, name, surname)
  values (@p_id, @p_name, @p_surname)

什么是更好的方法?似乎在第二个选择中,要更新一行,必须搜索两次,而在第一个选项中 - 只需搜索一次。还有其他解决方案吗?我正在使用 MS SQL 2000。

最佳答案

两者都工作正常,但我通常使用选项 2(mssql 2008 之前的版本),因为它读起来更清晰一些。我也不会强调这里的性能...如果它成为问题,您可以在 exists 子句中使用 NOLOCK 。不过,在开始到处使用 NOLOCK 之前,请确保您已经涵盖了所有基础知识(索引和总体架构内容)。如果您知道您将多次更新每个项目,那么考虑选项 1 可能是值得的。

选项 3 是不使用破坏性更新。这需要更多的工作,但基本上每次数据更改时都会插入一个新行(从不更新或从表中删除),并且有一个选择所有最新行的 View 。如果您希望表包含其所有先前状态的历史记录,那么它很有用,但它也可能有点矫枉过正。

关于sql-server - T-SQL 插入或更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2275946/

相关文章:

c# - 无法从 C# 表单应用程序连接到本地数据库 (mdf)

sql - 如何在不使用500,000+行表中的截断表的同时有效地删除行

asp.net-mvc - 带有 asp.net mvc 更新问题的 RavenDB

MySQL:将数据插入表中,一些数据来自另一个表(关系型)

sql-server - access和sql server实时同步

sql-server - 数据库批准拒绝工作流程

sql-server - 触发器内游标中的 SQL Server 错误处理

sql-server - 当T-SQL中有重叠时如何编写case when语句

sql - 如何以数据透视格式获取 sql 查询?

sql-server-2005 - 为什么在 SQL Server 2005 中无法在不锁定整个表的情况下插入/更新数据?