如何避免存储过程中的T-SQL错误?

时间:2011-01-14 20:26:16

标签: sql-server tsql error-handling try-catch

我有几个我正在管理的数据库,每个数据库都需要一个特定存储过程的副本。

问题是,存储过程插入到除了其中一个数据库之外的所有数据库的表中。对于那个数据库,该表是一个分区视图,不可更新,我不需要插入。

我试图做类似以下的事情:

CREATE PROCEDURE st_doit AS
    -- Do lots of other stuff...
    IF(DB_NAME() <> 'db3') BEGIN
       INSERT INTO mytable...;
    END

由于db3语句,尝试在INSERT中执行存储过程时仍然收到错误消息,即使在该数据库中,插入实际上也不会被执行。将INSERT包裹在TRY...CATCH块中也无济于事。

为了便于维护,我真的希望避免在db3中获得该程序的特殊副本。通常我不会在程序中放置这样的IF语句,但在这种特殊情况下,它确实是最好的解决方案,并且随着时间的推移它不会随着时间的推移而变成其他特殊情况的嵌套。

那么,如果我实际尝试插入表中,如何强制SQL Server执行存储过程而生成错误?

编辑:由于使用动态SQL对我来说有点过于混乱,我的最终解决方案是将IF块保留为陷阱,但要注释掉{}中的有问题的块{1}}。不理想,但有效。幸运的是,我不会经常更改此SP,但我希望在每个数据库中都有一个“完整”的副本。

3 个答案:

答案 0 :(得分:3)

我认为唯一的方法是使用动态sql

if( objectproperty(object_id('dbo.MyTable'), 'isUserTable') = 1 ) begin
    -- insert the value 32 into MyColumn of MyTable
    exec sp_executesql 
        N'insert into MyTable(MyColumn) values(@MyColumnParam)',
        N'@MyColumnParam int',
        32

end

答案 1 :(得分:2)

您必须使用动态SQL从SQL Server“隐藏”INSERT。

CREATE PROCEDURE st_doit AS
    -- Do lots of other stuff...
    IF(DB_NAME() <> 'db3') BEGIN
       EXEC SP_EXECUTESQL N'INSERT INTO mytable...';
    END

答案 2 :(得分:0)

IF区块中为部件设置SP是否可行/更方便?仅适用于DB3,它将是一个虚拟SP,不执行任何操作以及执行实际插入的所有其他SP。对于每个数据库,原始SP都是相同的。

编辑:当然,这需要支持两个“类似的”SP,但是当初始SP非常复杂时,我可以想象这种方法的一些实用性,因此特殊情况可能更容易维护第二个是较小的一个,它可以插入也可以不插入。