在用户定义的类型上创建 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属性/装饰的TableDefinitionFillRowMethodName属性似乎暗示应该可以,但实际上没有任何作用。当我这样调用方法时(我预计会失败):

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()