【问题标题】:Is it possible to create table-valued *methods* in a SQL CLR user-defined type?是否可以在 SQL CLR 用户定义类型中创建表值 *methods*?
【发布时间】:2011-11-28 16:57:19
【问题描述】:

我有一个可以从表值方法中受益匪浅的 CLR UDT,ala xml.nodes():

-- nodes() example, for reference:
declare @xml xml = '<id>1</id><id>2</id><id>5</id><id>10</id>'
select c.value('.','int') as id from @xml.nodes('/id') t (c)

我想要类似的东西用于我的 UDT:

-- would return tuples (1, 4), (1, 5), (1, 6)....(1, 20)
declare @udt dbo.FancyType = '1.4:20'
select * from @udt.AsTable() t (c)

有人有这方面的经验吗?任何帮助将不胜感激。我尝试了几件事,但都失败了。我查找了文档和示例,但没有找到。

是的,我知道我可以创建以我的 UDT 作为参数的表值 UDF,但我更希望将所有内容捆绑在一个单一类型中,OO 样式。

编辑

Russell Hart 找到了the documentation states that table-valued methods are not supported,并修复了我的语法以产生预期的运行时错误(见下文)。

在 VS2010 中,创建新的 UDT 后,我在 struct 定义的末尾添加了这个:

[SqlMethod(FillRowMethodName = "GetTable_FillRow", TableDefinition = "Id INT")]
public IEnumerable GetTable()
{
    ArrayList resultCollection = new ArrayList();
    resultCollection.Add(1);
    resultCollection.Add(2);
    resultCollection.Add(3);
    return resultCollection;
}

public static void GetTable_FillRow(object tableResultObj, out SqlInt32 Id)
{
    Id = (int)tableResultObj;
}

这将成功构建和部署。但是在 SSMS 中,我们得到了预期的运行时错误(如果不是逐字):

-- needed to alias the column in the SELECT clause, rather than after the table alias.
declare @this dbo.tvm_example = ''
select t.[Id] as [ID] from @this.GetTable() as [t]

Msg 2715, Level 16, State 3, Line 2
Column, parameter, or variable #1: Cannot find data type dbo.tvm_example.
Parameter or variable '@this' has an invalid data type.

所以,看来这毕竟是不可能的。即使有可能,考虑到在 SQL Server 中更改 CLR 对象的限制,它也可能不明智。

也就是说,如果有人知道解决此特定限制的技巧,我将相应地提出新的赏金。

【问题讨论】:

    标签: sql-server sql-server-2008 sqlclr user-defined-types


    【解决方案1】:

    您为表设置了别名,但没有为列设置别名。试试看,

    declare @this dbo.tvm_example = ''
    select t.[Id] as [ID] from @this.GetTable() as [t]
    

    根据文档http://msdn.microsoft.com/en-us/library/ms131069(v=SQL.100).aspx#Y4739,这应该会因另一个有关不正确类型的运行时错误而失败。

    SqlMethodAttribute 类继承自 SqlFunctionAttribute 类,因此 SqlMethodAttribute 继承自 SqlFunctionAttribute 的 FillRowMethodName 和 TableDefinition 字段。这意味着可以编写表值方法,但事实并非如此。方法编译并部署程序集,但在运行时引发有关 IEnumerable 返回类型的错误,并显示以下消息:“程序集 '' 中的类 '' 中的方法、属性或字段 '' 具有无效的返回类型。”

    他们可能会避免支持这种方法。如果您使用方法更新更改程序集,这可能会导致 UDT 列中的数据出现问题。 一个合适的解决方案是有一个最小的 UDT,然后有一个单独的方法类来伴随它。这将确保灵活性和功能齐全的方法。

    xml 节点方法不会改变,因此它不受相同的实现限制。

    希望这对彼得有所帮助,祝你好运。

    【讨论】:

    猜你喜欢
    • 2019-08-02
    • 1970-01-01
    • 2021-07-04
    • 2010-10-02
    • 2014-04-18
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多