SqlFunction не может открыть контекстное соединение, несмотря на наличие DataAccessKind.Read

У меня есть проект 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.

Кто-нибудь знает какие-либо другие причины получения этой ошибки?


person AnthonyWJones    schedule 26.02.2009    source источник


Ответы (2)


Проблема в следующем:

  1. SQLCLR не разрешает доступ к данным внутри TestFillRow.

  2. Несмотря на то, что это «выглядит» так, как будто ваш TestFillRow не обращается к данным, способ, которым компилятор переводит код с операторами «выходности», фактически откладывает его выполнение до первого вызова итератора .MoveNext(). Поэтому следующее утверждение:

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

    выполняется внутри TestFillRow... что незаконно.

Не использовать возврат доходности; вместо этого загрузите весь результат в List<> и верните список в конце функции UD.

person Nestor    schedule 14.06.2009
comment
Очень запоздалое принятие и голосование (побуждено, мне стыдно сказать, отрицательным голосованием по моему вопросу). Вы абсолютно правы, ничего не работает до Movenext. Я даже сам писал об этом в блоге здесь: - geekswithblogs.net/codingbloke/archive/2010/09/12/, но до сих пор я явно не видел между ними связи. - person AnthonyWJones; 29.01.2011
comment
См. ошибку Connect, касающуюся ограничений FillRow: connect.microsoft.com/SQLServer/feedback/details/442200/ - person piers7; 17.01.2014
comment
Проблема не в том, что соединение открывается внутри TestFillRow. Даже если вы предоставите собственную реализацию перечислителя, который открывает соединение и извлекает первую строку внутри основного метода, этот перечислитель не будет работать из TestFillRow, поскольку соединение будет принудительно закрыто. - person GSerg; 05.02.2015

«SQLCLR не разрешает доступ к данным внутри TestFillRow» — это ошибка.

Если вы не используете строку подключения context connection = true, вы можете получить доступ к данным внутри метода FillRow.

person mshakurov    schedule 12.07.2014