消息 6522,级别 16 但没有从 sys.all_columns 中选择的错误消息
Msg 6522, Level 16 but no error message selecting from sys.all_columns
我是 运行 SQLCLR 函数 SqlConnection("context connection=true")
。
在某些情况下,我得到异常
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
每次在相同记录编号的相同查询中都会发生这种情况。
有连接
SqlConnection(@"Server=" + @"localhost\sqldeveloper16" + ";Database=" + db + ";Integrated Security=true;connect Timeout = 50")
我从来没有遇到过这个错误,一切都很好。
我不明白为什么。
然后我在 SQL Server 2008 上尝试了相同的 CLR,没有问题...我需要检查什么?!?!
这可能是 SQL Server 2016 错误吗?!
这是我的class
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" -> - 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.
我尝试将其从查询中删除,没有例外...
我不知道这个问题,所以我的解决方法是添加一个新参数来定义要提取的列。
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" -> - 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)
(没有 "collation_name" 的所有列)
很好!
select *
from dbo.objdb('test','sys','columns','collation_name',null,null)
很好O.o
错误来自 sys.system_columns
中的一个特定行,它是 sys.all_columns
系统目录视图中查询的两个内部表之一。
此错误似乎也只发生在 collation_name
字段用于从 sys.system_columns
或 sys.all_columns
中选择的查询中时。
测试行的子集,我能够确定错误只发生在一行中。该对象是:
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 中有 none.
为什么会报错?嗯,真正的错误是:
Msg 6522, Level 16, State 1, Line 406
A.NET Framework error occurred during execution of user-defined routine or aggregate "ObjDb":
System.Data.SqlClient.SqlException:
System.Data.SqlClient.SqlException:
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 System.Data.SqlClient.SqlDataReaderSmi.Read()
at 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
.
发生的任何事情
现在,避免这种 should 很简单,只需将以下条件添加到 WHERE
子句 if 模式名称是 sys
并且 object_name 是 all_columns
或 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 数据仓库和并行数据仓库之外甚至不可用。事实上,对象名称 pdw_nodes_pdw_physical_databases
由 OBJECT_NAME
函数返回,却没有出现在 sys.all_objects
;-).
中,这已经够奇怪了
我是 运行 SQLCLR 函数 SqlConnection("context connection=true")
。
在某些情况下,我得到异常
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
每次在相同记录编号的相同查询中都会发生这种情况。
有连接
SqlConnection(@"Server=" + @"localhost\sqldeveloper16" + ";Database=" + db + ";Integrated Security=true;connect Timeout = 50")
我从来没有遇到过这个错误,一切都很好。
我不明白为什么。
然后我在 SQL Server 2008 上尝试了相同的 CLR,没有问题...我需要检查什么?!?!
这可能是 SQL Server 2016 错误吗?!
这是我的class
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" -> - 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.
我尝试将其从查询中删除,没有例外...
我不知道这个问题,所以我的解决方法是添加一个新参数来定义要提取的列。
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" -> - 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)
(没有 "collation_name" 的所有列) 很好!
select *
from dbo.objdb('test','sys','columns','collation_name',null,null)
很好O.o
错误来自 sys.system_columns
中的一个特定行,它是 sys.all_columns
系统目录视图中查询的两个内部表之一。
此错误似乎也只发生在 collation_name
字段用于从 sys.system_columns
或 sys.all_columns
中选择的查询中时。
测试行的子集,我能够确定错误只发生在一行中。该对象是:
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 中有 none.
为什么会报错?嗯,真正的错误是:
Msg 6522, Level 16, State 1, Line 406
A.NET Framework error occurred during execution of user-defined routine or aggregate "ObjDb":
System.Data.SqlClient.SqlException:
System.Data.SqlClient.SqlException:
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 System.Data.SqlClient.SqlDataReaderSmi.Read()
at 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
.
现在,避免这种 should 很简单,只需将以下条件添加到 WHERE
子句 if 模式名称是 sys
并且 object_name 是 all_columns
或 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 数据仓库和并行数据仓库之外甚至不可用。事实上,对象名称 pdw_nodes_pdw_physical_databases
由 OBJECT_NAME
函数返回,却没有出现在 sys.all_objects
;-).