Warm tip: This article is reproduced from serverfault.com, please click

sql-检查存储过程是否存在语法错误

(sql - Check if Stored procedures have syntax errors)

发布于 2009-11-24 17:06:21

我的数据库中有很多存储过程。我们一直在改变数据结构(正在开发中)是否有工具可以告诉我哪些存储过程无法编译?

创建存储过程时,它可以防止你发现无效的表或列,但是如果在创建存储过程后更改了列名,则proc无效。我想获取这些无效进程的列表。

干杯!

约瑟夫

Questioner
BrokeMyLegBiking
Viewed
0
Carlos Vásquez Polanco 2020-12-03 07:02:37

监视的一项重大改进是拥有一个持续集成(CI),它可以每隔一段时间(可能每两小时或每天一次)检查数据库中的对象。另一种选择是创建一个调用端点的Windows服务。

当有人中断构建时,CI或Windows服务可以向开发团队发送通知。

在该后端的端点中,你可以有一个类似的过程,该过程将通知你有关数据库中有错误的视图,存储过程和函数。

CREATE PROCEDURE Get_Objects_With_Errors 
AS

    SET NOCOUNT ON;
    DECLARE @objectName AS VARCHAR(255);

    DECLARE @count int = 0;

    -- Find all views in dbo schema
    DECLARE listViews CURSOR FOR
        SELECT [TABLE_NAME]
        FROM INFORMATION_SCHEMA.VIEWS v
        WHERE [TABLE_SCHEMA] = 'dbo';

    OPEN listViews
    FETCH NEXT FROM listViews into @objectName;

    WHILE (@@FETCH_STATUS <> -1)
    BEGIN
        BEGIN TRY
            EXEC sp_refreshview @objectName;
        END TRY
        BEGIN CATCH
            PRINT @objectName + ' has ERRORS : ' + ERROR_MESSAGE();
            SET @count = @count + 1;
        END CATCH
        FETCH NEXT FROM listViews INTO @objectName;
    END

    CLOSE listViews;
    DEALLOCATE listViews;

    -- Find all procedures and functions in dbo schema
    DECLARE listRoutines CURSOR FOR
        SELECT SPECIFIC_NAME
        FROM INFORMATION_SCHEMA.ROUTINES
        WHERE SPECIFIC_SCHEMA = 'dbo' 
        GROUP BY SPECIFIC_NAME;

    OPEN listRoutines
    FETCH NEXT FROM listRoutines into @objectName;

    WHILE (@@FETCH_STATUS <> -1)
    BEGIN
        BEGIN TRY
            EXEC sp_refreshsqlmodule @objectName;
        END TRY
        BEGIN CATCH
            PRINT @objectName + ' has ERRORS : ' + ERROR_MESSAGE();
            SET @count = @count + 1;
        END CATCH
        FETCH NEXT FROM listRoutines INTO @objectName;
    END

    CLOSE listRoutines;
    DEALLOCATE listRoutines;

    PRINT 'Total with errors : ' + CAST(@count AS nvarchar(10));

SET NOCOUNT OFF;