【问题标题】:How do I avoid a T-SQL error in a stored procedure?如何避免存储过程中的 T-SQL 错误?
【发布时间】:2011-01-14 20:26:16
【问题描述】:

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

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

我尝试过如下操作:

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

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

为了便于维护,我真的很想避免在db3 中拥有该过程的特殊副本。通常我不会在过程中放置​​这样的 IF 语句,但在这种特殊情况下,它确实是最好的解决方案,而且它不会随着时间的推移而变成其他特殊情况的巢穴。

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

编辑: 因为使用动态 SQL 对我来说有点太麻烦了,所以我的最终解决方案是保留 IF 块作为陷阱,但注释掉 db3 中的违规块.不理想,但有效。幸运的是,我不会经常更改此 SP,但我希望在每个数据库中都有一个“完整”副本。

【问题讨论】:

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


    【解决方案1】:

    我认为唯一的方法是使用动态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
    

    【讨论】:

      【解决方案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
      

      【讨论】:

        【解决方案3】:

        IF 块中为零件设置一个 SP 是否可能/更方便?仅对于 DB3 来说,这将是一个无所事事的虚拟 SP,而对于所有其他执行实际插入的人来说。每个 DB 的原始 SP 将是相同的。

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

        【讨论】:

          猜你喜欢
          • 2020-12-10
          • 1970-01-01
          • 2018-10-03
          • 2013-05-28
          • 2018-04-12
          • 2011-02-26
          • 2019-06-26
          • 1970-01-01
          • 2011-08-03
          相关资源
          最近更新 更多