重命名SQL Server中的表后验证所有对象

时间:2019-03-06 07:55:13

标签: sql-server

我使用此存储过程来验证SQL Server中的所有对象。

此存储过程在当前数据库中存在的每个对象上使用sp_refreshsqlmodule。除了我重命名表格外,它都能正常工作。

之后,所有使用重命名表的对象都会引发错误,但是下面的过程无法检测到这些错误。

我该如何解决?

DECLARE @NumberRecords INT
DECLARE @RowCount INT
DECLARE @Name NVARCHAR(MAX)
DECLARE @Command NVARCHAR(MAX)
DECLARE @Result int

DECLARE @Names TABLE 
               (
                    [RowId] INT NOT NULL IDENTITY(1, 1),
                    [Name]  NVARCHAR(MAX),
                    [Type]  NVARCHAR(MAX)
                )

INSERT INTO @Names
    SELECT
        QUOTENAME(SCHEMA_NAME([Objects].schema_id)) + '.' + QUOTENAME(OBJECT_NAME([Objects].object_id)) [Name],
        type_desc [Type]
    FROM 
        sys.objects [Objects]
    WHERE 
        type_desc IN ('SQL_STORED_PROCEDURE',
                      'SQL_TRIGGER',
                      'SQL_SCALAR_FUNCTION',
                      'SQL_TABLE_VALUED_FUNCTION',
                      'SQL_INLINE_TABLE_VALUED_FUNCTION',
                      'VIEW')
    ORDER BY
        [Name]

SET @RowCount = 1
SET @NumberRecords = (SELECT COUNT(*) FROM @Names)

WHILE (@RowCount <= @NumberRecords)
BEGIN
    SELECT @Name = [Name]
    FROM @Names
    WHERE [RowId] = @RowCount

    SET @Command = N'EXEC sp_refreshsqlmodule ''' + @Name + ''''

    BEGIN TRY
        EXEC @Result = sp_executesql @Command

        IF @Result <> 0
        BEGIN
            RAISERROR('Failed', 16, 1)
        END
        ELSE
        BEGIN
            DELETE @Names
            WHERE [RowId] = @RowCount
        END
    END TRY
    BEGIN CATCH
        -- Nothing
    END CATCH

    SET @RowCount = @RowCount + 1
END

SELECT  
    [Name], [Type]
FROM @Names

2 个答案:

答案 0 :(得分:3)

T-SQL语言有很多奇怪之处。当您创建或更改视图或函数时,如果SQL Server无法找到该定义所依赖的所有表,视图和函数,则SQL Server将不接受您提供的定义。您可以进一步处理这些对象,并指定WITH SCHEMABINDING以防止在视图/函数仍然存在时更改其从属对象。

对于存储过程,SQL Server将不会抱怨存储过程 1 的定义中缺少表/视图/函数。当过程开始执行时,服务器将根据当前存在的对象编译尽可能多的代码并开始执行。随着执行过程的进行,它可能根据已经存在但在过程开始执行之前不存在的对象重新编译过程的后续部分。这被称为“延迟名称解析”,并且没有退出的选择(我们已经要求了多年)。

对于编写依赖于例如临时表。但这意味着没有机制可以提前验证存储过程所引用的所有对象确实存在。


1 它会验证定义在语法上是否有效。

答案 1 :(得分:1)

高兴,我有一个解决方案:

while read sign; do