SQL Server存储过程报告执行成功,但其中的查询未执行

问题描述

我们使用一组存储过程来实现我们的ETL管道之一,该管道依赖于使用推送策略的链接服务器。存储过程在SQL Server代理作业中一步一步运行。这些服务器位于相同的VLAN中,并具有10GBPS的连接。

我们意识到拉动策略是理想的,并且正在努力将这种方法应用于我们的工作负载。

ETL代理通常是成功的,并且在相当长的一段时间内一直是可行的解决方案。一个或多个存储过程将间歇性地报告成功执行,但实际上不执行。我已经多次验证了这种情况。

代理历史记录表明未发生任何错误,并且我们的自定义错误表(由我们的错误处理程序存储过程填充)未显示迁移错误。所有存储过程都经过验证可以正常工作,并且没有逻辑错误,事实证明,在大多数情况下,数据是成功INSERT|UPDATE|DELETE编辑的。

手动执行失败的存储过程不会产生不同的结果。关于这种情况的令人困惑的部分是,如果存储过程中包含的查询被手动提取并执行,它将成功INSERT|UPDATE|DELETE(ing)数据。

我最好的猜测是,这可能是由缓存的查询计划引起的。不过,我完全不确定。


我们针对该用例的存储过程始终包含一个try / catch来处理和记录任何错误。在结构上,它们通常类似于以下内容:

CREATE PROCEDURE dbo.some_etl_proc
AS
  BEGIN
    SET NOCOUNT ON;

    SET XACT_ABORT ON;

    BEGIN TRY

      ---------
      -- delete
      ---------
      DELETE  at
      FROM    LINKED_SERVER.ANOTHER_DB.dbo.another_table AS at
              LEFT JOIN SOME_DB.dbo.some_table AS st 
                ON st.some_table_id = at.some_table_id
      WHERE   st.some_table_id IS NULL;

      ---------
      -- update
      ---------
      UPDATE  at
      SET     col_1 = st.col_1,col_2 = st.col_2
      FROM    LINKED_SERVER.ANOTHER_DB.dbo.another_table AS at
              JOIN SOME_DB.dbo.some_table AS st 
                ON st.some_table_id = at.some_table_id;

      ---------
      -- insert 
      ---------
      INSERT INTO LINKED_SERVER.ANOTHER_DB.dbo.another_table (col_1,col_2)
      SELECT  st.col_1,st.col_2
      FROM    SOME_DB.dbo.some_table AS st              
              LEFT JOIN LINKED_SERVER.ANOTHER_DB.dbo.another_table AS at
                ON at.some_table_id = st.some_table_id
      WHERE   at.some_table_id IS NULL;
      
    END TRY
    BEGIN CATCH
      IF @@TRANCOUNT > 0
        ROLLBACK TRAN;

      -- we log the error here using a custom sproc
      EXEC dbo.error_handler

      RETURN 55555;
    END CATCH;
  END;

我们的错误处理程序如下:

CREATE PROCEDURE dbo.error_handler
AS
  DECLARE @errmsg NVARCHAR(2048),@severity TINYINT,@state TINYINT,@errno INT,@proc sysname,@lineno INT;

  SELECT  @errmsg = ERROR_MESSAGE(),@severity = ERROR_SEVERITY(),@state = ERROR_STATE(),@errno = ERROR_NUMBER(),@proc = ERROR_PROCEDURE(),@lineno = ERROR_LINE();

  IF @errmsg NOT LIKE '***%'
    BEGIN
      SELECT  @errmsg = N'*** ' + COALESCE(QUOTENAME(@proc),'<dynamic SQL>') + N',Line ' + LTRIM(STR(@lineno)) + N'. Errno ' + LTRIM(STR(@errno)) + N': ' + @errmsg;
    END;

  INSERT INTO dbo.db_error 
  SELECT  GETDATE(),SYSTEM_USER,@errno,@severity,@state,@lineno,@errmsg,@proc;

  RAISERROR('%s',@errmsg);

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...