【问题标题】:Is it OK to swallow an exception for DB INSERT是否可以吞下 DB INSERT 的异常
【发布时间】:2014-02-24 09:19:53
【问题描述】:

是否可以吞下 INSERTS 的重复键违规异常,还是应该检查记录是否存在?

假设我有一张照片表,其中包含一个字段:PhotoName。我正在查看文件目录以将项目添加到 Photo。在此过程中,当我找到照片名称时,它可能已经在数据库中。所以有两种方法可以解决这个问题:

1) //Look to see if it exists before adding it. Only add it if it does not exist.

bool photoExists = SQLSELECTStatementToCheckIfThePhotoExists(photoName);
if(!photoExists)
  SQLCommandToInsertPhoto(photoName)

or 2) //Assume that it doesn't exist. If it does, catch and ignore.
try
{
  SQLCommandToInsertPhoto(photoName);
}
catch(DuplicateKeyException ex)
{
  //swallow it and continue on as if nothing happened.
}

一方面,我不一定喜欢“吞下”异常的概念,但另一方面,try...catch 只使用一次对数据库的调用。这恰好在 SQL Server 中。

【问题讨论】:

  • 您可能需要查看MERGE,因为这将允许您匹配该键上的数据集,并且仅在不匹配的地方插入。
  • 感谢您指出合并。假设一个人正在使用一个没有合并功能的 ORM?想法?

标签: sql sql-server exception-handling


【解决方案1】:

您绝对不应该只是“吞下”异常。您应该尝试查找这些重复项,如果需要,不要插入它们。

On 方法可能是检查键上不存在的位置。

INSERT INTO TargetTable

SELECT 
    KeyID,
    blah,
    blerg,
FROM SourceTable AS S
WHERE NOT EXISTS (
    SELECT 1
    FROM TargetTable AS T
    WHERE S.KeyID = T.KeyID
    )

此方法将只允许您将INSERT 新行放入表中。这种方法当然不考虑您可能需要为UPDATE 进行的任何匹配,但是这超出了这个问题的范围,但仍应考虑。大多数用户也可以使用MERGE 有时间我会发布一个例子。

【讨论】:

  • 谢谢。我什至没有想过在我的语句中添加一个简单的 NOT EXISTS 条件。
  • 由于数据不是来自现有表,如何使用 INSERT VALUES 来完成?
  • 这些值是一次一个吗?
【解决方案2】:

让 SQL Server 引发异常可能非常昂贵(即使您只是吞下它们) - 请参阅 herehere

所以我的建议是先检查违规情况,只有在必要时才插入。但是,我不会将它们分成单独的语句,尤其是在完全独立的应用程序往返中,因为您可以有这种情况:

-- connection A, at 12:00:00.0000001:

SELECT FROM TABLE WHERE key = 'x'; -- 0 rows returned

-- connection B, at 12:00:00.0000002:

SELECT FROM TABLE WHERE key = 'x'; -- 0 rows returned

-- connection A, at 12:00:00.0000003:

INSERT dbo.TABLE(key) VALUES('x'); -- succeeds

-- connection B, at 12:00:00.0000003:

INSERT dbo.TABLE(key) VALUES('x'); -- fails

我宁愿在单个INSERT ... WHERE NOT EXISTS 语句中执行此操作,正如@Zane's answer 所演示的那样,尽管我会在SELECT 部分添加更高的升级。或者,如果发现密钥违规,您可以使用INSTEAD OF INSERT 触发器从插入中退出 (I wrote about this here.) 顺便说一句,我对MERGE 非常谨慎 - 请参阅this article for my reasoningsome other opinions, too

【讨论】:

  • 好文章。我不会知道 MERGE 的问题。另外,我会牢记在未来使用这些类型的触发器。
猜你喜欢
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2018-08-25
  • 2018-05-26
  • 2012-03-06
相关资源
最近更新 更多