【问题标题】:Msg 6522, Level 16 but no error message selecting from sys.all_columns消息 6522,级别 16,但从 sys.all_columns 选择时没有错误消息
【发布时间】:2018-01-27 05:27:41
【问题描述】:

我正在使用SqlConnection("context connection=true") 运行 SQLCLR 函数。

在某些情况下,我得到了异常

System.Data.SqlClient.SqlException (0x80131904)
在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔型 breakConnection,Action`1 wrapCloseInAction)
在 System.Data.SqlClient.SqlInternalConnectionSmi.EventSink.DispatchMessages(布尔忽略非致命消息)
在 System.Data.SqlClient.SqlDataReaderSmi.InternalRead(布尔忽略非致命错误)
在 ObjDb.Functions.ObjDb(String db, String schema, String obj, String col, String val)

ClientConnectionId:00000000-0000-0000-0000-000000000000
错误号:200,状态:4,类:25

每次使用相同的查询在相同的记录号时都会发生这种情况。

有连接

SqlConnection(@"Server=" + @"localhost\sqldeveloper16" + ";Database=" + db + ";Integrated Security=true;connect Timeout = 50")

我从来没有遇到过这个错误,一切都很好。

我不明白为什么。

然后我在 SQL Server 2008 上尝试了相同的 CLR,没有问题...我需要检查什么?!?!

这可能是 SQL Server 2016 的错误吗?!

这是我的课

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Xml;
using Newtonsoft.Json;
using System.Xml.Linq;
using System.IO;
using System.Linq;
using System.Text;

namespace ObjDb
{
    public partial class Functions
    {
        [SqlFunction
        (
            //DataAccess = DataAccessKind.Read,//serve x accedere alle tabelle del db, altrimenti accede solo a qlle di sistema...
            SystemDataAccess = SystemDataAccessKind.Read,
            FillRowMethodName = "columns_ok",
            TableDefinition = "c1 nvarchar(max), node nvarchar(max)"
        )
        ]

        public static IEnumerable ObjDb(String db, String schema, String obj, String col, String val)
        {
            List<String> rows = new List<String>();//List<Object[]> rows = new List<Object[]>();
            //List<tuple.t2<String, String>> rows = new List<tuple.t2<String, String>>();

            SqlCommand command = null;// = new SqlCommand(query, conn);
            SqlConnection conn = null;// new SqlConnection("context connection=true");

            try
            {
                conn = new SqlConnection("context connection=true");//new SqlConnection(@"Server=" + @"localhost\sqldeveloper16" + ";Database=" + db + ";Integrated Security=true;connect Timeout = 50"); //new SqlConnection("context connection=true");//
                conn.Open();

                String query;
                StringBuilder sb = new StringBuilder();
                sb.Append("where 0=0");

                if ((col != null && !col.Equals("")) && (val != null && !val.Equals("")))
                {
                    String[] cols = col.Split(',');
                    String[] vals = val.Split(',');

                    for (int i = 0; i < Math.Min(cols.Length, vals.Length); i++)
                    {
                        sb.Append(" and [").Append(cols[i]).Append("]='").Append(vals[i].Replace("'", "''")).Append("'");
                    }
                    //filter = "where 0=0 " + sb.ToString();
                    //filter = "where [" + col + "]='" + val + "'";
                }
                //estrazione inline dell xml (un xml x ogni riga)
                //"BINARY BASE64" -> https://stackoverflow.com/questions/8801697/xml-export-via-bcp-bulk-export - bug 2008R2, converte il varbinary in ascii
                query =
                "select (select t.* for xml raw('root'),BINARY BASE64) " +
                "from [" + db + "].[" + schema + "].[" + obj + "] t " +
                sb.ToString(); ;//filter;

                command = new SqlCommand(query, conn);
                //command.CommandTimeout = 0;
                SqlDataReader dr = command.ExecuteReader();

                while (dr.Read())
                {
                    //rows.Add(new tuple.t2<String, String>("", (String)dr[0]));
                    rows.Add((String)dr[0]);
                }
                return rows;
            }
            catch (Exception e)
            {
                rows.Add(e.ToString().Substring(0, Math.Min(4000, e.ToString().Length)));
                return  rows;
            }
            finally
            {
                if (command != null)
                    command.Dispose();
                if (conn != null)
                    conn.Close();
            }
        }
        private static void columns_ok(object resultObj, out SqlString node)
        {
            //String res = (String)resultObj;

            node = (String)resultObj;
        }
    }
}

然后从 Sql

select *
from dbo.objdb('test','sys','all_columns',null,null)

结果是(5248 条记录,最后包含异常,我只发布了最后 3 条):

<root object_id="-103402673" name="similarity_index_page_count" column_id="4" system_type_id="127" user_type_id="127" max_length="8" precision="19" scale="0" is_nullable="1" is_ansi_padded="0" is_rowguidcol="0" is_identity="0" is_computed="0" is_filestream="0" is_replicated="0" is_non_sql_subscribed="0" is_merge_published="0" is_dts_replicated="0" is_x005F_xml_document="0" xml_collection_id="0" default_object_id="0" rule_object_id="0" is_sparse="0" is_column_set="0" generated_always_type="0" generated_always_type_desc="NOT_APPLICABLE" is_hidden="0" is_masked="0"/>
<root object_id="-103085222" name="database_id" column_id="1" system_type_id="56" user_type_id="56" max_length="4" precision="10" scale="0" is_nullable="0" is_ansi_padded="0" is_rowguidcol="0" is_identity="0" is_computed="0" is_filestream="0" is_replicated="0" is_non_sql_subscribed="0" is_merge_published="0" is_dts_replicated="0" is_x005F_xml_document="0" xml_collection_id="0" default_object_id="0" rule_object_id="0" is_sparse="0" is_column_set="0" generated_always_type="0" generated_always_type_desc="NOT_APPLICABLE" is_hidden="0" is_masked="0"/>
System.Data.SqlClient.SqlException (0x80131904)     at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)     at System.Data.SqlClient.SqlInternalConnectionSmi.EventSink.DispatchMessages(Boolean ignoreNonFatalMessages)     at System.Data.SqlClient.SqlDataReaderSmi.InternalRead(Boolean ignoreNonFatalErrors)     at ObjDb.Functions.ObjDb(String db, String schema, String obj, String col, String val)  ClientConnectionId:00000000-0000-0000-0000-000000000000  Error Number:200,State:4,Class:25

提前致谢!!

更新: 我不知道为什么,但问题是“collation_name”列仅在 SQL 2016 上。

我试图从查询中删除它,没有例外......

【问题讨论】:

  • 您能否发布您的 SQLCLR 代码以及完整的错误消息。错误 0x80131904 可能是几件事,一个是找不到服务器,但也可能是其他错误。另外,“相同记录号的相同查询”是什么意思(我理解相同的查询但相同的记录号???)。
  • 所以,clr 每次为该查询给我一些记录(例如 5249),然后抛出异常。我尝试了 2 sql 2016 和同样的问题,2008r2 一切都很好......
  • 它正在执行什么确切查询?请至少将该查询发布到问题中,但最好还包括 .NET 代码。
  • 没有过多研究,我认为您的错误处理掩盖了实际错误。
  • 这是 .net 给我的...我认为是服务器设置,发生在 sql 2016 istance 上,而不是在 2008 上。我尝试了 3 个 sql 2016 实例,仅在这些实例上给出错误。 .我不知道我要检查什么...

标签: .net sql-server user-defined-functions sqlclr


【解决方案1】:

错误来自sys.system_columns 中的一个特定行,这是sys.all_columns 系统目录视图中查询的两个内部表之一。

只有在从sys.system_columnssys.all_columns 中选择的查询中使用collation_name 字段时,才会出现此错误。

测试行的子集,我能够确定错误仅发生在一行。那个对象是:

sys.pdw_nodes_pdw_physical_databases

这一行在 SQL Server 2012 中存在(除了 2012 SP3 和 2016 SP1,我没有测试过任何东西),并且根本没有错误。

O.P. 提到只有在选择collation_name 字段时才会出现此错误。查看该特定行的字段,它是NULL。当然NULL 没有任何问题,因为collation_name 显示了许多其他行NULL。这一行的不同之处在于数据类型是sysname,它是NVARCHAR(128) 的别名,它是一个字符串类型,因此应该总是有一个非NULL 排序规则。我不确定这列 physical_name 是如何具有 NULL 排序规则的,但它是 SQL Server 2016 中唯一具有 NULL 排序规则的字符串列,而 SQL Server 2012 中没有。

为什么会出错?好吧,真正的错误是:

消息 6522,第 16 级,状态 1,第 406 行
执行用户定义例程或聚合“ObjDb”期间发生 A.NET Framework 错误:
System.Data.SqlClient.SqlException:
System.Data.SqlClient.SqlException:
在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔型 breakConnection,Action`1 wrapCloseInAction)
在 System.Data.SqlClient.SqlInternalConnectionSmi.EventSink.DispatchMessages(布尔忽略非致命消息)
在 System.Data.SqlClient.SqlDataReaderSmi.InternalRead(布尔忽略非致命错误)
在 System.Data.SqlClient.SqlDataReaderSmi.Read()
在 ObjDb.Functions.ObjDb(String db, String schema, String obj, String col, String val)

注意没有实际的错误消息!诡异的。不知道这是怎么发生的,但collation_name 字段实际上是以下表达式:

convert(sysname, ColumnPropertyEx(object_id, name, 'collation')) AS collation_name

ColumnPropertyEx 函数未记录在案,因此没有什么可做的。

我怀疑这是某种错误,ColumnPropertyEx 会引发低级错误,低到不会在 SSMS 中显示为错误。但是,进程内连接(即Context Connection = true)似乎非常敏感,实际上可以捕捉到ColumnPropertyEx 发生的任何事情。

现在,避免这种情况应该只需将以下条件添加到WHERE 子句如果架构名称为sys,object_name 为@ 987654347@或system_columns

NOT (user_type_id IN (231, 256) AND collation_name IS NULL)

但是,由于这些是视图,它似乎会在应用这些过滤器之前处理所有行。

所以,我发现的一种方法是使用以下内容过滤 id 字段:

NOT (t.[object_id] = -103085222 AND t.[column_id] = 2)

现在唯一真正的问题是我不知道 object_id 在所有版本的 SQL Server 2016 中是否相同,在 SQL Server 2017 中也一样(我还没有检查过)。

什么/真正的错误在哪里?

虽然看起来ColumnPropertyEx 函数可能不应该像现在这样运行,但我认为主要问题是pdw_nodes_pdw_physical_databases 的3 列应该首先从sys.all_columns 返回。 pdw_nodes_pdw_physical_databases 在 Azure SQL 数据仓库和并行数据仓库之外甚至不可用。事实上,很奇怪,OBJECT_NAME 函数返回的对象名称pdw_nodes_pdw_physical_databases,却没有出现在sys.all_objects 中;-)。

【讨论】:

  • 嗨,非常感谢您的回答和准确的写作!但是,我的最后一个疑问是为什么在“上下文连接 = true”中,sql 在 SSMS 中引发异常。因为如果我在 SSMS 中执行查询“从 test.sys.all_columns 中选择 collat​​ion_name”很好,在 CLR 中不是,但在 CLR 中使用新连接如“SqlConnection(@"Server=" + @"localhost\sqldeveloper16" + ";Database=" + db + ";Integrated Security=true;connect Timeout = 50")"...我想说的是,在SSMS中结果是正确的或者没有捕获到异常并且结果记录较少真的应该有吗?
  • 仅供参考,我也偶然发现了这一点,并追逐了错误的东西,直到我意识到这是一个客户端/驱动程序问题。例如,它发生在 SSMS 16 上,但不会发生在任何较新的版本上。 sqlblog.org/2019/12/18/metadata-meets-metadata
【解决方案2】:

我不知道这个问题,所以我的解决方法是添加一个新参数来定义要提取的列。

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Xml;
using Newtonsoft.Json;
using System.Xml.Linq;
using System.IO;
using System.Linq;
using System.Text;

namespace ObjDb
{
    public partial class Functions
    {
        [SqlFunction
        (
            //DataAccess = DataAccessKind.Read,//serve x accedere alle tabelle del db, altrimenti accede solo a qlle di sistema...
            SystemDataAccess = SystemDataAccessKind.Read,
            FillRowMethodName = "columns_ok",
            TableDefinition = "c1 nvarchar(max), node nvarchar(max)"
        )
        ]

        public static IEnumerable ObjDb(String db, String schema, String obj, String col, String col, String val)
        {
            List<String> rows = new List<String>();//List<Object[]> rows = new List<Object[]>();
            //List<tuple.t2<String, String>> rows = new List<tuple.t2<String, String>>();

            SqlCommand command = null;// = new SqlCommand(query, conn);
            SqlConnection conn = null;// new SqlConnection("context connection=true");

            try
            {
                conn = new SqlConnection("context connection=true");//new SqlConnection(@"Server=" + @"localhost\sqldeveloper16" + ";Database=" + db + ";Integrated Security=true;connect Timeout = 50"); //new SqlConnection("context connection=true");//
                conn.Open();

                String query;
                StringBuilder sb = new StringBuilder();
                sb.Append("where 0=0");

                if ((col != null && !col.Equals("")) && (val != null && !val.Equals("")))
                {
                    String[] cols = col.Split(',');
                    String[] vals = val.Split(',');

                    for (int i = 0; i < Math.Min(cols.Length, vals.Length); i++)
                    {
                        sb.Append(" and [").Append(cols[i]).Append("]='").Append(vals[i].Replace("'", "''")).Append("'");
                    }
                    //filter = "where 0=0 " + sb.ToString();
                    //filter = "where [" + col + "]='" + val + "'";
                }

            String headers;

            if (col != null && !col.Equals(""))
            {
                headers = col;
            }
            else
            {
                headers = "t.*";
            }
                //estrazione inline dell xml (un xml x ogni riga)
                //"BINARY BASE64" -> https://stackoverflow.com/questions/8801697/xml-export-via-bcp-bulk-export - bug 2008R2, converte il varbinary in ascii
                query =
                "select (select " + headers + " for xml raw('root'),BINARY BASE64) " +
                "from [" + db + "].[" + schema + "].[" + obj + "] t " +
                sb.ToString(); ;//filter;

                command = new SqlCommand(query, conn);
                //command.CommandTimeout = 0;
                SqlDataReader dr = command.ExecuteReader();

                while (dr.Read())
                {
                    //rows.Add(new tuple.t2<String, String>("", (String)dr[0]));
                    rows.Add((String)dr[0]);
                }
                return rows;
            }
            catch (Exception e)
            {
                rows.Add(e.ToString().Substring(0, Math.Min(4000, e.ToString().Length)));
                return  rows;
            }
            finally
            {
                if (command != null)
                    command.Dispose();
                if (conn != null)
                    conn.Close();
            }
        }
        private static void columns_ok(object resultObj, out SqlString node)
        {
            //String res = (String)resultObj;

            node = (String)resultObj;
        }
    }
}

我尝试了什么:

select *
from dbo.objdb('test','sys','all_columns',null,null,null)

错误

select *
from dbo.objdb('test','sys','all_columns','collation_name',null,null)

错误

select *
from dbo.objdb('test','sys','all_columns','object_id,name,column_id,system_type_id,user_type_id,max_length,precision,scale,is_nullable,is_ansi_padded,is_rowguidcol,is_identity,is_computed,is_filestream,is_replicated,is_non_sql_subscribed,is_merge_published,is_dts_replicated,is_xml_document,xml_collection_id,default_object_id,rule_object_id,is_sparse,is_column_set,generated_always_type,generated_always_type_desc,encryption_type,encryption_type_desc,encryption_algorithm_name,column_encryption_key_id,column_encryption_key_database_name,is_hidden,is_masked',null,null)

(所有没有“collat​​ion_name”的列) 好的!

 select *
 from dbo.objdb('test','sys','columns','collation_name',null,null)

很好哦

【讨论】:

  • 问题与sys.system_columns 目录视图有关。我正在进一步研究它。
  • 是的,使用 select * from dbo.objdb('test','sys','system_columns','collat​​ion_name',null,null) 我有同样的问题......但为什么在 sql 2016只要?!?!为什么不使用 sys.columns??
  • 我找到了...很快就会写出来...这是sys.system_columns 中的一个特定行。
猜你喜欢
  • 1970-01-01
  • 2022-08-24
  • 2013-05-01
  • 2016-08-12
  • 2020-11-11
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多