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

时间:2016-04-13 09:10:54

标签: sql sql-server stored-procedures

构建插入到简单链接表中的存储过程时,是否应该检查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抛出异常

由于

3 个答案:

答案 0 :(得分:3)

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

例如,您不会编写如下代码:

i = 1;

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

我认为这种情况类似。

如果表不在您的控制范围内,则可以正常处理错误。例如,如果此过程可以在用户创建的任意一组表上运行,或者如果它将分发给需要在自己的数据库中设置表的外部用户,您可能希望添加一些自定义错误处理。这样做的目的是让用户更清楚地描述出错的地方。

答案 1 :(得分:2)

作为一个基本概念,在潜在的错误提升代码之前验证值是一件好事。但是,在这种情况下,(至少在理论上)可能存在表a或表b在存在检查和insert语句之间的变化,这会引起fk违规错误。

我会做这样的事情:

new IntWriteable(Integer.parseInt(someString))

here函数返回try块中出现的错误。

然后在执行代码中,您只需检查返回的错误消息是否为空。如果是,您知道插入成功。如果没有,您可以按照自己的意愿处理此异常。

答案 2 :(得分:0)

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