【发布时间】:2018-05-01 00:32:36
【问题描述】:
关于这个错误有很多问题,但似乎没有一个相关。
我们得到的原始异常
Der eingehende Tabular Data Stream (TDS) für das RPC-Protokoll (Remote Procedure Call) ist nicht Richtig。
0-Tabellenwertparameter (""),Zeile 0,Spalte 0:Der 0xE7-Datentyp hat eine ungültige Datenoder Metadatenlänge。
我尝试翻译它
传入的表格数据流 (TDS) 远程过程调用 (RPC) 协议流不正确
0-TableValuedParameter (""),Row 0, Column 0: The 0xE7-Datatype has an invalid Data- or Metadatalength.
SqlServer的版本
Microsoft SQL Server 2016 (SP1) (KB3182545) - 13.0.4001.0 (X64) 2016 年 10 月 28 日 18:17:30 版权所有 (c) 微软公司 Windows Server 2016 Standard 6.3(内部版本 14393:)(管理程序)上的标准版(64 位)
这是什么原因:
我们使用用户定义的类型来传递表值参数。该错误是可重现的,将具有单行和单列的 DataTable 包含 String.Empty 作为参数传递给如下类型:
CREATE TYPE dbo.para_table_varchar AS TABLE (value nvarchar(10) COLLATE Latin1_General_ci_ai NOT NULL);
C# 代码 (.net 4.6.1)
DataTable table = new DataTable();
DataColumn column = table.Columns.Add("value", typeof(string));
column.MaxLength = 0;
table.Rows.Add(string.Empty);
SqlParameter para = _cmd.Parameters.Add("@ptable", SqlDbType.Structured, 0);
para.Value = table;
para.TypeName ="dbo.para_table_varchar";
命令如下所示
SELECT * FROM someTable WHERE someColumn IN (SELECT value FROM @ptable)
这只发生在提到的 SQLServer 2016 上。大约 20 个其他客户端没有这个问题。
虽然 Microsoft 涵盖了此问题 here,但建议的解决方法(将大小设置为 -1)似乎不起作用。
【问题讨论】:
-
试试
DataColumn column = table.Columns.Add("value", typeof(string), 10);。我不知道知识库文章是否适用于此处,因为它于 2009 年发布,并提到它将在下一个主要的 .NET 框架版本中修复。 -
另外,this article 讨论了当
DataTable作为 TVP 传递时,为什么应该为DataTable列指定最大字符串长度。 -
@DanGuzman 对不起,我忘了提,在这种情况下,列的最大长度设置为 0。
-
对,这就是为什么我建议在 Add 方法中明确指定最大长度 10。这可能会避免错误。
-
为什么你将
MaxLength设置为 0?它不是 0,而是 10。TVP 要求它们的列类型完全匹配;不能像使用常规参数那样动态地推断/转换类型(在这种情况下,您可以摆脱不正确的长度,但会以性能为代价)。这是引擎要求(或限制,如果您愿意的话);你无法在客户端大小上解决这个问题。
标签: c# sql-server sql-server-2016 table-valued-parameters