当构建插入到简单链接表中的存储过程时,它应该检查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语句将不会执行,数据库也不会锁定表。