Sql server 使用EXEC()重新创建存储过程找不到错误
我通过获取现有存储过程的定义并在其上运行ALTER语句来检查它们的有效性 我遇到的问题是,任何由于依赖关系消失而未编译的存储过程都没有被标记为依赖关系 如果我尝试在SSMS中运行相同的ALTER命令,我会收到错误消息。 编辑:不,我不Sql server 使用EXEC()重新创建存储过程找不到错误,sql-server,tsql,Sql Server,Tsql,我通过获取现有存储过程的定义并在其上运行ALTER语句来检查它们的有效性 我遇到的问题是,任何由于依赖关系消失而未编译的存储过程都没有被标记为依赖关系 如果我尝试在SSMS中运行相同的ALTER命令,我会收到错误消息。 编辑:不,我不 DECLARE @def nvarchar(MAX) BEGIN TRY -- refresh the stored procedure SELECT @def = REPLACE(definition,'CREATE PROCEDURE ','A
DECLARE @def nvarchar(MAX)
BEGIN TRY
-- refresh the stored procedure
SELECT @def = REPLACE(definition,'CREATE PROCEDURE ','ALTER PROCEDURE ')
FROM sys.sql_modules
WHERE ... -- selecting/limiting clause
EXEC (@def);
END TRY
BEGIN CATCH
PRINT 'Validation failed : ' + ERROR_MESSAGE()
END CATCH
要捕获非编译错误,我必须做什么?谢谢忘了这件事吧——你找错树了- 存储的进程将编译为OK,即使其依赖项已消失。 SSMS中的编辑器将突出显示缺少的项,但不会停止ALTER语句的工作 此查询将标识缺少依赖项的所有存储过程:
-- table variable to store procedure names
DECLARE @v TABLE (RecID INT IDENTITY(1,1), spname sysname)
-- retrieve the list of stored procedures
INSERT INTO @v(spname)
SELECT
'[' + s.[name] + '].[' + sp.name + ']'
FROM sys.procedures sp
INNER JOIN sys.schemas s ON s.schema_id = sp.schema_id
WHERE is_ms_shipped = 0
AND sp.name like 'Get%'
-- counter variables
DECLARE @cnt INT, @Tot INT
SELECT @cnt = 1
SELECT @Tot = COUNT(*) FROM @v
DECLARE @spname sysname
DECLARE @ref nvarchar(MAX)
-- start the loop
WHILE @Cnt <= @Tot BEGIN
SELECT @spname = spname
FROM @v
WHERE RecID = @Cnt
BEGIN
SELECT @ref = referenced_entity_name
FROM sys.dm_sql_referenced_entities (@spname, 'OBJECT')
WHERE referenced_id IS NULL;
END
SET @Cnt = @cnt + 1
END
忘了这件事吧——找错树了- 存储的进程将编译为OK,即使其依赖项已消失。 SSMS中的编辑器将突出显示缺少的项,但不会停止ALTER语句的工作 此查询将标识缺少依赖项的所有存储过程:
-- table variable to store procedure names
DECLARE @v TABLE (RecID INT IDENTITY(1,1), spname sysname)
-- retrieve the list of stored procedures
INSERT INTO @v(spname)
SELECT
'[' + s.[name] + '].[' + sp.name + ']'
FROM sys.procedures sp
INNER JOIN sys.schemas s ON s.schema_id = sp.schema_id
WHERE is_ms_shipped = 0
AND sp.name like 'Get%'
-- counter variables
DECLARE @cnt INT, @Tot INT
SELECT @cnt = 1
SELECT @Tot = COUNT(*) FROM @v
DECLARE @spname sysname
DECLARE @ref nvarchar(MAX)
-- start the loop
WHILE @Cnt <= @Tot BEGIN
SELECT @spname = spname
FROM @v
WHERE RecID = @Cnt
BEGIN
SELECT @ref = referenced_entity_name
FROM sys.dm_sql_referenced_entities (@spname, 'OBJECT')
WHERE referenced_id IS NULL;
END
SET @Cnt = @cnt + 1
END
SQL Server存储过程使用: 创建存储过程时,将解析过程中的语句以确保语法准确性。如果在过程定义中遇到语法错误,将返回错误,并且不会创建存储过程。如果语句语法正确,则存储过程的文本将存储在sys.sql_modules目录视图中 第一次执行存储过程时,查询处理器从sys.sql_modules目录视图中读取存储过程的文本,并检查过程使用的对象的名称是否存在。此过程称为延迟名称解析,因为在创建存储过程时,存储过程引用的表对象不必存在,而仅在执行存储过程时才存在
所以你观察到的行为是故意的。您需要的是找出哪些过程依赖于丢失的表。有关此问题,请参阅,正确答案取决于您的SQL Server版本。SQL Server 2016在某种程度上更好地跟踪这些信息,并提供更好的视图。在此之前,该过程是众所周知的困难和不可靠的,请阅读。SQL Server存储过程使用: 创建存储过程时,将解析过程中的语句以确保语法准确性。如果在过程定义中遇到语法错误,将返回错误,并且不会创建存储过程。如果语句语法正确,则存储过程的文本将存储在sys.sql_modules目录视图中 第一次执行存储过程时,查询处理器从sys.sql_modules目录视图中读取存储过程的文本,并检查过程使用的对象的名称是否存在。此过程称为延迟名称解析,因为在创建存储过程时,存储过程引用的表对象不必存在,而仅在执行存储过程时才存在
所以你观察到的行为是故意的。您需要的是找出哪些过程依赖于丢失的表。有关此问题,请参阅,正确答案取决于您的SQL Server版本。SQL Server 2016在某种程度上更好地跟踪这些信息,并提供更好的视图。在这之前,这个过程是出了名的困难和不可靠,请阅读。当您准确地更改一个过程时,会出现什么错误?您可能永远不会看到问题,因为SQL Server在创建procs.Oops时至少会延迟表的名称解析!!我的错误-SSMS将编译缺少依赖项的存储过程-它只会用红色波浪线突出显示缺少的项…好的,现在投票关闭它,因为它不可复制。当您完全更改过程时,会出现什么错误?您可能永远不会看到问题,因为SQL Server在创建procs.Oops时至少会延迟表的名称解析!!我的错误-SSMS将编译缺少依赖项的存储过程-它只会用红色曲线突出显示缺少的项…好的,现在投票关闭它,因为它不可复制。