存储过程最佳实践?他们应该在插入之前检查是否存在外键吗



当构建插入到简单链接表中的存储过程时,它应该检查FK是否存在并正常返回错误,还是让SQL抛出异常?

  • 什么是最佳实践
  • 什么是最有效的

万一有人不理解我的问题:

  • Table A
  • Table B
  • Table AB

我应该这样做吗:

IF EXISTS(SELECT 1 FROM A WHERE Id = @A) AND EXISTS(SELECT 1 FROM B WHERE Id = @B)
BEGIN
      INSERT AB (AId,BId) VALUES (@A,  @B)
END
ELSE
   --handle gracefully, return error code or something

INSERT AB (AId,BId) VALUES (@A, @B)

并让SQL抛出异常

感谢

如果表在您的控制之下,就没有理由执行额外的检查假设它们设置正确,并让SQL处理任何错误。不断检查您是否确实完成了您想要做的事情是过于防御性的编程,这会给代码增加不必要的复杂性。

例如,你不会写这样的代码:

i = 1;
if (i != 1) 
{
    print "Error: i is not 1!";
}

我认为这种情况也是类似的。

如果表不在您的控制之下,那么优雅地处理错误可能会很有用例如,如果此过程可以在用户创建的任意一组表上运行,或者如果它将分发给需要在自己的数据库中设置表的外部用户,则可能需要添加一些自定义错误处理。这样做的目的是让用户更清楚地描述出了什么问题。

作为一个基本概念,在可能引发错误的代码之前验证值是一件好事。然而,在这种情况下,表a或表b中的exists检查和insert语句之间可能存在(至少在理论上)更改,这将引发fk违规错误。

我会这样做:

BEGIN TRY
  INSERT AB (AId,BId) VALUES (@A,  @B)
  SELECT NULL As ErrorMessage
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE() AS ErrorMessage
END CATCH

ERROR_MESSAGE()函数返回在try块中引发的错误。

然后在执行代码中,您可以简单地检查返回的错误消息是否为null。如果是,则表示插入成功。如果没有,您可以按照自己认为合适的方式处理此异常。

通常我会检查Fk。如果Fk不存在,那么抛出一个错误友好的,insert语句将不会执行,数据库也不会锁定表。

最新更新