Sql server 在sql server中,是否有任何方法可以检查架构更改是否会影响存储的进程?

Sql server 在sql server中,是否有任何方法可以检查架构更改是否会影响存储的进程?,sql-server,refactoring,schema,refactoring-databases,Sql Server,Refactoring,Schema,Refactoring Databases,在SQL Server中,是否有任何方法可以检查架构中的更改是否会影响存储过程(和/或视图)? 例如,更改一个表中的列名可能会中断某些存储过程;如何检查受影响的存储过程?我认为最好的方法是使用视图从实际表中抽象出存储过程,并使用“with schemabind”子句创建这些视图,该子句应防止会破坏视图的更改…使用Visual Studio数据库版进行T-SQL开发。它将在构建过程中捕获此类问题,因为它会创建deployment.dbschema文件。商业工具,例如可以这样做。 我认为Visual

在SQL Server中,是否有任何方法可以检查架构中的更改是否会影响存储过程(和/或视图)?

例如,更改一个表中的列名可能会中断某些存储过程;如何检查受影响的存储过程?

我认为最好的方法是使用视图从实际表中抽象出存储过程,并使用“with schemabind”子句创建这些视图,该子句应防止会破坏视图的更改…

使用Visual Studio数据库版进行T-SQL开发。它将在构建过程中捕获此类问题,因为它会创建deployment.dbschema文件。

商业工具,例如可以这样做。
我认为Visual Studio的最新版本也包含这种功能,但我还没有尝试过

据我所知,Microsoft SQL Server本身没有任何内置功能可以做到这一点更正:我刚刚在KM对这篇文章的回答中读到。。。请注意,sp_depends的用法已被弃用;它被sys.dm_sql_referenced_entities和sys.dm_sql_referenced_entities替换

此外,如果底层存储过程使用动态SQL,则检测依赖项的任务将变得更加困难,并且容易出现“遗漏”。

在SSMS(SQL Server Management Studio)中,右键单击要更改的对象,然后单击查看依赖项。我认为这不会从另一个数据库中找到引用

如果未加密,还可以在存储过程中查找引用。您必须在每个您怀疑可能引用您正在更改的对象的数据库中执行此操作

选择objects.name ,sql_modules.definition 从sys.sql\u模块到sql\u模块 将sys.objects对象连接到sql\u模块上。object\u id=objects.object\u id 其中定义为“%some column name%”

我没有发现100.0000%的准确率为100.000000%。

尝试使用:

EXEC sp_depends 'YourTableName'
和/或

DECLARE @Search nvarchar(500)
SET @Search='YourTableName' --or anything else
SELECT DISTINCT
    LEFT(o.name, 100) AS Object_Name,o.type_desc
    FROM sys.sql_modules        m 
        INNER JOIN sys.objects  o ON m.object_id=o.object_id
    WHERE m.definition Like '%'+@Search+'%'
    ORDER BY 2,1

看看这些答案:


除了动态SQL之外,在可能的情况下使用SCHEMABINDING和sp_refreshsqlmodule以及SQL_依赖项进行其他操作非常准确。

如果要更改对象或列的名称,然后,Red Gate软件的智能重命名功能将生成一个脚本,该脚本将执行重命名并更新对其他对象中旧名称的引用

如果您只是对依赖于列名的内容感兴趣,那么SQL Prompt 5还有一个列依赖项函数,在脚本中将鼠标悬停在列名上会弹出一个窗口,其中包含引用该列的对象列表

你可以免费下载14天的试用版,看看这些功能是否适合你

保罗·斯蒂芬森
SQL Prompt项目管理器
红门软件

如果使用SQL Server

您可以在更改后使用此查询并查找存储过程或视图或

更改后可能会出错

USE <Your_DataBase_Name>;

SET NOCOUNT ON;

DECLARE @name NVARCHAR(MAX) 
DECLARE @sql NVARCHAR(MAX) 
DECLARE @type CHAR(2)
DECLARE @type_desc NVARCHAR(60)
DECLARE @params NVARCHAR(MAX)

DECLARE @tblInvalid TABLE
(
  [type_desc] NVARCHAR(60) ,
  [name] NVARCHAR(MAX) ,
  [error_number] INT ,
  [error_message] NVARCHAR(MAX) ,
  [type] CHAR(2)
);       

DECLARE testSPs CURSOR FAST_FORWARD
FOR
SELECT  [name] = OBJECT_NAME(SM.[object_id]) ,
        [type] = SO.[type] ,
        SO.[type_desc] ,
        [params] = ( SELECT (
                            SELECT  CONVERT(XML, ( SELECT STUFF(( SELECT
                                                          ', ' + [name]
                                                          + '=NULL' AS [text()]
                                                          FROM
                                                          sys.parameters
                                                          WHERE
                                                          [object_id] = SM.[object_id]
                                                          FOR
                                                          XML
                                                          PATH('')
                                                          ), 1, 1, '')
                                                 ))
                     FOR    XML RAW ,
                                TYPE
                 ).value('/row[1]', 'varchar(max)')
                   )
FROM    sys.sql_modules SM
        JOIN sys.objects SO ON SO.[object_id] = SM.[object_id]
WHERE   SO.[is_ms_shipped] = 0
        AND SO.[type] = 'P'


OPEN testSPs 
FETCH NEXT FROM testSPs INTO @name, @type, @type_desc, @params

WHILE ( @@FETCH_STATUS = 0 ) 
BEGIN
    BEGIN TRY
        SET @sql = 'SET FMTONLY ON; exec ' + @name + ' ' + @params
            + '; SET FMTONLY OFF;'
        --PRINT @sql;      
        EXEC (@sql);
    END TRY
    BEGIN CATCH
        PRINT @type_desc + ', ' + @name + ', Error: '
            + CAST(ERROR_NUMBER() AS VARCHAR) + ', ' + ERROR_MESSAGE();
        INSERT  INTO @tblInvalid
                SELECT  @type_desc ,
                        @name ,
                        ERROR_NUMBER() ,
                        ERROR_MESSAGE() ,
                        @type;
    END CATCH


    FETCH NEXT FROM testSPs INTO @name, @type, @type_desc, @params
END

CLOSE testSPs  
DEALLOCATE testSPs


SELECT  [type_desc] ,
    [name] ,
    [error_number] ,
    [error_message]
FROM    @tblInvalid
ORDER BY CHARINDEX([type], ' U V PK UQ F TR FN TF P SQ ') ,
    [name];
使用;
不计数;
声明@name NVARCHAR(最大值)
声明@sql NVARCHAR(最大值)
声明@type字符(2)
声明@type_desc NVARCHAR(60)
声明@params NVARCHAR(最大值)
声明@tblInvalid表
(
[type_desc]NVARCHAR(60),
[名称]NVARCHAR(最大值),
[error_number]INT,
[错误信息]NVARCHAR(最大值),
[类型]字符(2)
);       
声明testSPs游标快进
对于
选择[名称]=对象名称(SM.[对象id]),
[type]=SO[type],
所以。[类型描述],
[参数]=(选择(
选择转换(XML),(选择填充((选择
“,”+[名称]
+“=NULL”作为[text()]
从…起
系统参数
哪里
[object\u id]=SM。[object\u id]
对于
XML
路径(“”)
), 1, 1, '')
))
对于XML原始文件,
类型
).value('/row[1]','varchar(max'))
)
从sys.sql\u模块SM
连接sys.objects,依此类推。[object\u id]=SM。[object\u id]
其中,[是否已装运]=0
因此,[type]=“P”
开放测试SP
从testSPs获取下一个到@name、@type、@type_desc、@params
而(@@FETCH\u STATUS=0)
开始
开始尝试
设置@sql=”设置FMTONLY ON;exec'++@name++'++@params
+ '; 把…放在一边;'
--PRINT@sql;
EXEC(@sql);
结束尝试
开始捕捉
打印@type_desc++','++@name++',错误:'
+CAST(ERROR_NUMBER()作为VARCHAR)+','+ERROR_MESSAGE();
插入@tblInvalid
选择@type_desc,
@名字,
错误号(),
错误消息(),
@类型;
端接
从testSPs获取下一个到@name、@type、@type_desc、@params
结束
关闭测试SP
解除分配测试SP
选择[类型描述],
[姓名],
[错误编号],
[错误消息]
来自@tblInvalid
CHARINDEX的订单([类型],“U V PK U Q F TR FN TF P SQ”),
[姓名];

从sys.sql\u模块中选择objects.name、sql\u modules.definition sql\u modules将sys.objects对象连接到sql\u modules.object\u id=objects.object\u id,其中定义类似于“%some column name%”;此查询注意到RedGate的SQL重构现在已经合并