在用户定义的类型上创建 table 方法(类似于 XML 数据类型上的 'nodes')
Creating a table method on a user defined type (like like 'nodes' on the XML data type)
我已经创建了工作的基于 SQLCLR 的用户定义 table 值函数以及用户定义类型。
我现在想要的是 returns 一个 table 的 SQLCLR UDT 上的方法,类似于 XML 数据类型上的 nodes
方法。
SqlMethod
属性/装饰的TableDefinition
和FillRowMethodName
属性似乎暗示应该可以,但实际上没有任何作用。当我这样调用方法时(我预计会失败):
SELECT @Instance.AsTable();
我得到:
invalid data type
这与我以这种方式调用 SQLCLR table 值函数时得到的错误不同。
当我这样调用时:
SELECT * FROM @Instance.AsTable();
我收到(可能是预期的)错误:
The table (and its columns) returned by a table-valued method need to be aliased.
当我这样调用时:
SELECT * FROM @Instance.AsTable() t(c1,c2);
它说:
Table-valued function 'AsTable' cannot have a column alias
我感觉这个问题可能与 table 函数应该是静态的这一事实有关,所以我也尝试将它实现为扩展方法,但在那种情况下它甚至不会编译。我得到:
Extension method must be defined in a non-generic static class
显然,我可以将其实现为一个普通的 SQLCLR table 函数,该函数需要我的 UDT 类型的参数。事实上,我实际上已经做到了这一点并且 SELECT * FROM dbo.AsTable(@Instance);
有效,但我不喜欢那个解决方案。我真的很想让这个语法起作用:SELECT * FROM @Instance.AsTable() t(c1,c2);
这是一个非工作版本:
[SqlMethod(IsDeterministic = false, DataAccess = DataAccessKind.None, OnNullCall=true
, TableDefinition = "RowKey nvarchar(32),RowValue nvarchar(1000)"
, FillRowMethodName = "FormatLanguageRow")]
public IEnumerable AllRows()
{
return _rowCollection;
}
遗憾的是,无法在 returns a table(即 returns IEnumerable
)的 UDT 上创建方法。您对 SqlMethod
属性的两个属性的混淆是可以理解的,因为它们具有误导性。如果您查看 SqlMethodAttribute Class 的 MSDN 页面,您将在 "Remarks" 部分看到以下注释:
SqlMethodAttribute inherits from a SqlFunctionAttribute, so SqlMethodAttribute inherits the FillRowMethodName and TableDefinition fields from SqlFunctionAttribute. Note that it is not possible to write a table-valued method, although the names of these fields might suggest that it is possible.
除了您已经尝试过的解决方法(即创建 TVF)之外,您还可以 return 来自 UDT 方法的数据 XML(即 SqlXml
) .它肯定不会像流式 TVF 那样高效,但它 returning 一个值可以通过 [=14= 的 nodes()
方法转换为 table 内联] 数据类型。
更新 (2017-01-16)
我已将此作为 Microsoft Connect 建议正式提交:
Allow CLR UDT to return IEnumerable / Table / TVF from a method ( SqlMethod ) like XML.nodes()
我已经创建了工作的基于 SQLCLR 的用户定义 table 值函数以及用户定义类型。
我现在想要的是 returns 一个 table 的 SQLCLR UDT 上的方法,类似于 XML 数据类型上的 nodes
方法。
SqlMethod
属性/装饰的TableDefinition
和FillRowMethodName
属性似乎暗示应该可以,但实际上没有任何作用。当我这样调用方法时(我预计会失败):
SELECT @Instance.AsTable();
我得到:
invalid data type
这与我以这种方式调用 SQLCLR table 值函数时得到的错误不同。
当我这样调用时:
SELECT * FROM @Instance.AsTable();
我收到(可能是预期的)错误:
The table (and its columns) returned by a table-valued method need to be aliased.
当我这样调用时:
SELECT * FROM @Instance.AsTable() t(c1,c2);
它说:
Table-valued function 'AsTable' cannot have a column alias
我感觉这个问题可能与 table 函数应该是静态的这一事实有关,所以我也尝试将它实现为扩展方法,但在那种情况下它甚至不会编译。我得到:
Extension method must be defined in a non-generic static class
显然,我可以将其实现为一个普通的 SQLCLR table 函数,该函数需要我的 UDT 类型的参数。事实上,我实际上已经做到了这一点并且 SELECT * FROM dbo.AsTable(@Instance);
有效,但我不喜欢那个解决方案。我真的很想让这个语法起作用:SELECT * FROM @Instance.AsTable() t(c1,c2);
这是一个非工作版本:
[SqlMethod(IsDeterministic = false, DataAccess = DataAccessKind.None, OnNullCall=true
, TableDefinition = "RowKey nvarchar(32),RowValue nvarchar(1000)"
, FillRowMethodName = "FormatLanguageRow")]
public IEnumerable AllRows()
{
return _rowCollection;
}
遗憾的是,无法在 returns a table(即 returns IEnumerable
)的 UDT 上创建方法。您对 SqlMethod
属性的两个属性的混淆是可以理解的,因为它们具有误导性。如果您查看 SqlMethodAttribute Class 的 MSDN 页面,您将在 "Remarks" 部分看到以下注释:
SqlMethodAttribute inherits from a SqlFunctionAttribute, so SqlMethodAttribute inherits the FillRowMethodName and TableDefinition fields from SqlFunctionAttribute. Note that it is not possible to write a table-valued method, although the names of these fields might suggest that it is possible.
除了您已经尝试过的解决方法(即创建 TVF)之外,您还可以 return 来自 UDT 方法的数据 XML(即 SqlXml
) .它肯定不会像流式 TVF 那样高效,但它 returning 一个值可以通过 [=14= 的 nodes()
方法转换为 table 内联] 数据类型。
更新 (2017-01-16)
我已将此作为 Microsoft Connect 建议正式提交:
Allow CLR UDT to return IEnumerable / Table / TVF from a method ( SqlMethod ) like XML.nodes()