我正在使用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(Boolean ignoreNonFatalMessages)
在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
错误号码: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
提前谢谢!!
更新:
我不知道为什么,但问题是专栏&#34; collation_name
&#34;仅限SQL 2016。
我试图将其从查询中删除,没有例外......
答案 0 :(得分:2)
错误来自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
没有任何问题,因为NULL
显示了collation_name
这么多其他行。这一行的不同之处在于数据类型为sysname
,它是NVARCHAR(128)
的别名,它是一种字符串类型,因此应始终具有非NULL
排序规则。我不确定此列physical_name
是否具有NULL
排序规则,但它是SQL Server 2016中唯一具有NULL
排序规则的字符串列,并且在SQL Server 2012中没有。
为什么会出错?嗯,真正的错误是:
Ms 6522,Level 16,State 1,Line 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(Boolean ignoreNonFatalMessages)
在System.Data.SqlClient.SqlDataReaderSmi.InternalRead(Boolean ignoreNonFatalErrors)
在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
发生的任何事情。
现在,如果模式名称为WHERE
,那么,避免使用 应该<{em> 将一个简单的问题添加到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)
现在唯一真正的问题是我不知道所有版本的SQL Server 2016中的object_id
是否相同,也不知道SQL Server 2017中是否相同(我还没有检查过)。
什么/真正的错误在哪里?
虽然似乎ColumnPropertyEx
函数可能不应该按原样运行,但我认为主要问题是pdw_nodes_pdw_physical_databases
的3列应该从sys.all_columns
返回第一名。在Azure SQL数据仓库和并行数据仓库之外,甚至无法使用pdw_nodes_pdw_physical_databases
。实际上,pdw_nodes_pdw_physical_databases
函数返回了对象名OBJECT_NAME
,但却没有显示在sys.all_objects
; - )中,这很奇怪。
答案 1 :(得分:0)
我不知道这个问题,所以我的工作是添加一个新参数来定义要提取的列。
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)
(所有列都没有“collation_name”) FINE!
select *
from dbo.objdb('test','sys','columns','collation_name',null,null)
FINE O.o