【问题标题】:SQL Server : get messages from referenced entities procedure in codeSQL Server:从代码中的引用实体过程中获取消息
【发布时间】:2018-09-24 20:10:29
【问题描述】:

我正在对遗留数据库运行大依赖项扫描,发现某些对象具有过时的引用链接,如果您在 SSMS 中运行此代码以查看指向不存在的表的视图,就像我的情况一样,您将在 @ 上获得输出987654323@ 选项卡和Messages 中的错误信息。就像我下面的例子一样。

我试图检查我知道的所有 env 内容和这个存储过程的输出,但没有看到任何迹象。

当我在循环动态 SQL 脚本中运行此事件并在我的表中捕获输出以进行进一步处理时,如何捕获此事件?

更新:

  1. 它只是 Message 框中的文本,如果出错,您仍然可以在
    Results 选项卡上看到输出
  2. 这是 sp,它循环遍历我从 sys.object 获取的对象列表,并将此字符串作为我的示例运行以获取所有依赖项,将所有内容加载到表中。这个呼吁 sql_reference_entities 是获取跨数据库的唯一方法
    依赖于列级别。所以我需要坚持这 100 美元>

--

Select * 
From  sys.dm_sql_referenced_entities('dbo.v_View_Obs_Table','Object')

--

【问题讨论】:

  • 它会导致错误还是只是打印的消息?
  • 另外,这只是手动运行还是将成为工作的一部分?

标签: sql-server sql-server-2016


【解决方案1】:

----更新-----

此行为已在 SQL Server 2014 SP3 和 SQL Server 2016 SP2 中修复:

从 Microsoft SQL Server 2012 开始,错误由 sys.dm_sql_referenced_entities(例如当一个对象经历了 架构更改)无法在 TRY...CATCH Transact-SQL 块中捕获。 虽然这种行为在 SQL Server 2012 及更高版本中是预期的,但此 改进引入了一个名为 is_incomplete 的新列 动态管理视图 (DMV)。

KB4038418 - Update adds a new column to DMV sys.dm_sql_referenced_entities in SQL Server 2014 and 2016

----更新-------

tldr 是您无法在服务器端捕获这些信息,必须使用 C#、PowerShell 或其他可以处理信息消息的客户端程序。

DMV 正在做一些我不完全理解的奇怪事情。它正在生成错误(普通的 UDF 不允许这样做),并且这些错误不会触发 TRY/CATCH 块或设置 @@error。 EG

create table tempdb.dbo.foo(id int)
go
create view dbo.v_View_Obs_Table
as

select * from tempdb.dbo.foo

go

drop table tempdb.dbo.foo
go
begin try
   Select * From  sys.dm_sql_referenced_entities('dbo.v_View_Obs_Table','Object')
end try
begin catch
  select ERROR_MESSAGE(); --<-- not hit
end catch  

然而这些是真正的错误,你可以看到从客户端代码运行它:

using System;
using System.Data.SqlClient;

namespace ConsoleApp6
{


    class Program
    {
        static void Main(string[] args)
        {

            using (var con = new SqlConnection("Server=.;database=AdventureWorks;integrated security=true"))
            {
                con.Open();
                con.FireInfoMessageEventOnUserErrors = true;


                con.InfoMessage += (s, a) =>
                {
                    Console.WriteLine($"{a.Message}");
                    foreach (SqlError e in a.Errors)
                    {
                        Console.WriteLine($"{e.Message} Number:{e.Number} Class:{e.Class} State:{e.State} at {e.Procedure}:{e.LineNumber}");
                    }

                };

                var cmd = con.CreateCommand();

                cmd.CommandText = "Select * From  sys.dm_sql_referenced_entities('dbo.v_View_Obs_Table','Object')";
                           
                using (var rdr = cmd.ExecuteReader())
                {
                    
                    while (rdr.Read() || (rdr.NextResult() && rdr.Read()))
                    {
                        Console.WriteLine(rdr[0]);
                    }
                    
                }

                Console.ReadKey();


            }
        }
    }
}

输出

Invalid object name 'tempdb.dbo.foo'.
Invalid object name 'tempdb.dbo.foo'. Number:208 Class:16 State:3 at v_View_Obs_Table:4
0
The dependencies reported for entity "dbo.v_View_Obs_Table" might not include references to all columns. This is either because the entity references an object that does not exist or because of an error in one or more statements in the entity.  Before rerunning the query, ensure that there are no errors in the entity and that all objects referenced by the entity exist.
The dependencies reported for entity "dbo.v_View_Obs_Table" might not include references to all columns. This is either because the entity references an object that does not exist or because of an error in one or more statements in the entity.  Before rerunning the query, ensure that there are no errors in the entity and that all objects referenced by the entity exist. Number:2020 Class:16 State:1 at :1

【讨论】:

  • Tx 很多和布朗先生 !!!!!!唉,我不在 C# 业务,但我会尝试。
  • @Mr.Browne tldr ==> “太长;没读过”的缩写??互联网俚语是说某些被回复的文本因其长度而被忽略。在俚语中,它也可以代表“太懒;没读过”。它还用作在线帖子或新闻文章摘要的符号。学习俚语....
  • 我不知道自从这个答案以来这是否已经改变,但我可以在上面的 SSMS 中运行 SQL 并且捕获中的代码被命中。答案仍然相关且有用。
猜你喜欢
  • 2015-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多