2009-02-26 4 views
9

ich ein SqlServer Projekt mit einem sehr einfachen Test für eine Tabellenwert-Funktion haben: -SqlFunction versagt trotz DataAccessKind.Read Kontext-Verbindung zu öffnen vorhanden

[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; 
} 

Hinweis Open auf der Verbindung zur Zeit ist auskommentiert. Einmal installiert, kann ich so in SQL ausführen: -

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

Alles funktioniert gut.

Jetzt Kommentar- ich die con.open() und es nicht mit: -

Der Datenzugriff wird in diesem Kontext nicht erlaubt. Entweder ist der Kontext ist eine Funktion oder Methode nicht markiert mit DataAccessKind.Read oder SystemDataAccessKind.Read, ist ein Rückruf zu erhalten Daten von FillRow Methode einer Tabellenwertfunktion oder ist eine UDT Validierungsmethode.

Ich sehe nicht, was das Problem ist, die TestConn-Funktion hat DataAccessKind.Read.

Wer kennt noch andere Gründe für diesen Fehler?

Antwort

12

Das Problem ist folgendes:

  1. SQLCLR keine Datenzugriff innerhalb TestFillRow

  2. Selbst "sieht" wie Ihre TestFillRow doesnt Zugangsdaten, die Art und Weise der Compiler übersetzt Code erlaubt, obwohl es Bei "Yield" -Anweisungen wird die Ausführung bis zum ersten .MoveNext() - Aufruf an den Iterator verzögert. Daher ist die folgende Erklärung ab:

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

    wird innerhalb TestFillRow ausgeführt ... was illegal ist.

nicht yield return Verwenden Sie; Laden Sie stattdessen das gesamte Ergebnis auf List<> und geben Sie die Liste am Ende der UD-Funktion zurück.

+0

Eine verspätete Annahme und Upvote, (aufgefordert, ich schäme mich, durch eine Abstimmung unten auf meine Frage zu sagen). Du hast absolut recht, das Nichts läuft bis zum Movenext. Ich habe sogar selbst über dieses Verhalten hier gebloggt: - http://geekswithblogs.net/codingbloke/archive/2010/09/12/simple-asynchronous-operation-runner-ndash-part-1.aspx, aber ich habe eindeutig nicht Ich sehe die Verbindung zwischen ihnen bis jetzt. – AnthonyWJones

+0

Siehe Fehler bei FillRow-Einschränkungen: http://connect.microsoft.com/SQLServer/feedback/details/442200/sql-server-2008-clr-tvf-data-access-limitations-break-existing-code – piers7

+2

Es ist nicht das Problem, dass die Verbindung * innerhalb von 'TestFillRow' geöffnet wird.Selbst wenn Sie Ihre eigene "eifrige" Implementierung eines Enumerators bereitstellen, der die Verbindung öffnet und die erste Zeile innerhalb der Hauptmethode abruft, funktioniert dieser Enumerator nicht von 'TestFillRow', weil die Verbindung zwangsweise geschlossen wurde. – GSerg

1

"SQLCLR erlaubt keinen Datenzugriff innerhalb von TestFillRow" ist ein Fehler.

Wenn Sie nicht context connection = true Verbindungszeichenfolge verwenden, können Sie auf Daten innerhalb FillRow Methode zugreifen.