10

我有一个 SqlServer 项目,对表值函数进行了非常简单的测试:-

[SqlFunction(TableDefinition = "forename nvarchar(50)", FillRowMethodName = "TestFillRow", DataAccess = DataAccessKind.Read)]
public static IEnumerable TestConn(int ID)
{
    using (SqlConnection con = new SqlConnection("context connection=true"))
    {
        //con.Open();
        yield return "Anthony";
    }
}

public static void TestFillRow(object obj, out string forename)
{
    forename = (string)obj;
}

请注意,连接上的 Open 当前已被注释掉。部署后,我可以在 SQL 中像这样执行:-

SELECT * FROM [dbo].[TestConn](1)

一切正常。

现在我取消注释con.open()它失败了: -

在这种情况下不允许数据访问。上下文要么是未使用 DataAccessKind.Read 或 SystemDataAccessKind.Read 标记的函数或方法,要么是从表值函数的 FillRow 方法获取数据的回调,要么是 UDT 验证方法。

我看不出问题出在哪里,TestConn 函数得到了DataAccessKind.Read.

任何人都知道出现此错误的任何其他原因吗?

4

2 回答 2

16

问题如下:

  1. SQLCLR 不允许 TestFillRow 内的任何数据访问

  2. 即使它“看起来”像您的 TestFillRow 不访问数据,编译器使用“yield”语句翻译代码的方式实际上是将其执行推迟到第一个 .MoveNext() 调用迭代器。因此以下声明:

    using (SqlConnection con = new SqlConnection("context connection=true"))        
    

    在里面被执行TestFillRow......这是非法的。

不要使用 yield return;而是将整个结果加载到 aList<>并在 UD 函数的末尾返回列表。

于 2009-06-14T12:54:00.140 回答
1

“SQLCLR 不允许 TestFillRow 内的任何数据访问”是一个错误。

如果您不使用context connection = true连接字符串,您可以访问FillRow方法内的数据。

于 2014-07-12T20:31:39.510 回答