我可以为存储过程的开始和结束设置逻辑条件吗?

时间:2013-02-06 00:54:15

标签: sql-server tsql

我编写了一个复杂的存储过程,它基于复杂的逻辑在多个表之间移动记录。我仔细检查了每一小部分逻辑,但我希望对代码有最大的信心。有没有办法声明必须在SP的开头和结尾之间保持的逻辑关系?如果不满足这些条件,我想会回滚SP。

具体来说,我想声明表A中由一组逻辑条件挑选出来的记录将在SP的结尾处(而不是表A中)存在于那些记录中一组逻辑条件仍将在SP的结尾处的表X中。我使用布尔函数来挑选A中符合条件的记录。

我知道我可以用nUnit测试其中的一些东西,但我想知道是否有办法在t-SQL本身内声明和强制执行这种逻辑。

1 个答案:

答案 0 :(得分:1)

如果您的记录包含一个包含唯一ID的字段,您可以从TableA到TableB执行简单的INSERT + SELECT,然后再插入原始记录的简单DELETE

例如,首先将符合您选择条件的所有记录插入TableB:

INSERT INTO TableB (uniqueID, Field1, Field2, FieldN)
SELECT uniqueID,
       Field1,
       Field2,
       FieldN
FROM   TableA
WHERE  FieldN = SomeCriteria

然后从TableA中删除刚插入tableB的所有记录,使用字段uniqueID作为选择标准来确定要删除的记录:

DELETE TableA
WHERE  uniqueID IN (SELECT uniqueID
                    FROM   TableB)

如果你将两个语句放在一个带有几个错误检查的事务中,那么当两个语句执行时出现问题时你应该受到保护:

BEGIN TRANSACTION

INSERT INTO TableB (uniqueID, Field1, Field2, FieldN)
SELECT uniqueID,
       Field1,
       Field2,
       FieldN
FROM   TableA
WHERE  FieldN = SomeCriteria;

IF @@ERROR <> 0 THEN
BEGIN
    ROLLBACK TRANSACTION
    RETURN (@@ERROR)
END

DELETE TableA
WHERE  uniqueID IN (SELECT uniqueID
                    FROM   TableB);
if @@ERROR <> 0 THEN
BEGIN
    ROLLBACK TRANSACTION
    RETURN (@@ERROR)
END

COMMIT TRANSACTION 

如果您没有可以唯一标识每条记录的单个列,则可以使用EXISTS代替IN从TableA中选择DELETE的记录:

DELETE TableA
WHERE  EXISTS (SELECT *
               FROM   TableB
               WHERE  TableA.field1 = TableB.field1
                      AND TableA.field2 = TableB.field2
                      AND TableA.FieldN = TableB.fieldn);