在存储过程中,即使上一条语句失败,如何跳到下一个查询语句



我希望有人能告诉我如何处理这种情况。我有一个更新各种表的存储过程。某些查询需要连接到不同的链接服务器。有时这些链接服务器已关闭,无论如何我都需要该过程仍然运行下一个语句。下面是一个示例:

--Stored Procedure
BEGIN 
    INSERT INTO table1
        SELECT *
        FROM Z1;
    -- IF ABOVE FAILS GO TO NEXT QUERY ANYWAY
    INSERT INTO table1
        SELECT *
        FROM Z2;
    -- IF ABOVE FAILS GO TO NEXT QUERY ANYWAY
    INSERT INTO table1
        SELECT *
        FROM Z3;
END

您可能可以使用TRY/CATCH块做您想做的事:

BEGIN
    BEGIN TRY
        INSERT INTO table1 SELECT * FROM Z1;
    END TRY
    BEGIN CATCH
        -- you can do something here if you want
    END CATCH;
    -- IF ABOVE FAILS GO TO NEXT QUERY ANYWAY
    BEGIN TRY
        INSERT INTO table1 SELECT * FROM Z2;
    END TRY
    BEGIN CATCH
        -- you can do something here if you want
    END CATCH;
    -- IF ABOVE FAILS GO TO NEXT QUERY ANYWAY
    BEGIN TRY
        INSERT INTO table1 SELECT * FROM Z3;
    END TRY
    BEGIN CATCH
        -- you can do something here if you want
    END CATCH;
END;

这将处理运行时错误。 如果您有编译时错误 - 例如表不存在或表之间的列不匹配,则这无济于事。

如果这是从 ssms 作为一堆普通查询运行的,我会在每个查询之间放置批处理分隔符以分别处理它们。但是,由于这是一个存储过程,因此不能这样做。解决此问题的一种方法是为每个查询创建一个存储过程,并将所有这些存储过程作为步骤放入 SQL Server 代理作业中。您运行作业,每个步骤都按从上到下的顺序运行,即使中间的某些步骤失败也是如此。

即使这样也可以工作:@@ROWCOUNT是Oracle的SQL%rowcount等价

--Stored Procedure
BEGIN 
    INSERT INTO table1
        SELECT *
        FROM Z1;

    IF @@ROWCOUNT <>1 
    INSERT INTO table1
        SELECT *
        FROM Z2;
    IF @@ROWCOUNT <>1 
    INSERT INTO table1
        SELECT *
        FROM Z3;
END 

最新更新