Assembly 'system.web, Version = 4.0.0.0, Kultur = neutral, publickeytoken = b03f5f7f11d50a3a.' wurde nicht im SQL-Katalog gefunden

9

Ich versuche, eine SQL CLR-Funktion mithilfe der HTTPUtility.UrlDecode-Methode von System.Web bereitzustellen, kann sie jedoch nicht bereitstellen. Fehler erhalten:

.Net SqlClient-Datenprovider: Nachricht 6503, Ebene 16, Status 12, Zeile 1 Assembly 'system.web, Version = 4.0.0.0, Kultur = neutral, publickeytoken = b03f5f7f11d50a3a.' wurde nicht im SQL-Katalog gefunden.

Die Funktion (als Teil des SSDT-Projekts):

using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true)]
    public static SqlString udf_UrlDecode(SqlString encodedXML)
    {
        string decodedXML;

        decodedXML = HttpUtility.UrlDecode(encodedXML.ToString());

        return new SqlString(decodedXML);
    }
}

Es ist in Bezug auf diesen Thread . Ich bin SQL Server 2014 mit VS2012 SSDT und Datenbankprojekt. Habe es mit anderen Target Frameworks versucht, zB 3, 3.5, 4 und 4.5.

Ich habe auch versucht, ASSEMBLY mit System.Web zu erstellen, muss dann aber andere Assemblys hinzufügen, z. B. Microsoft.Build, System.Xaml, bis sie ebenfalls fehlschlagen. Ich sehe, dass System.Web nicht auf der Liste der unterstützten Bibliotheken steht, also irgendwelche Ideen?

wBob
quelle

Antworten:

9

Sie können entweder Uri.UnescapeDataString (in System) verwenden. In diesem Fall müssen Sie auch eine Replace('+', ' ')Zeichenfolge ausführen , bevor Sie sie übergeben Uri.UnescapeDataString, oder wenn Sie sich nicht darum kümmern möchten, ist diese Funktion in der kostenlosen Version von SQL # verfügbar (von dem ich der Autor bin).

Das Importieren System.Webist wahrscheinlich mehr Arbeit als es wert ist. Und in der Tat kann es riskant sein. Es gibt einen guten Grund, der System.Webnicht in der Liste "Unterstützte Bibliotheken" enthalten ist, auf die Sie in der Frage verwiesen haben: Es funktioniert nicht garantiert! Es kann vorkommen, dass Sie auf Situationen stoßen, insbesondere wenn Sie mit ASCII-Zeichensätzen außerhalb der USA arbeiten, die sich nicht wie erwartet verhalten, und Microsoft wird dies nicht beheben. Wenn Sie dies nicht unbedingt müssen, sollten Sie vorsichtig sein , wenn Sie nicht unterstützte DLLs hinzufügen. Die DLLs in der Liste "Unterstützt" wurden vollständig getestet und überprüft, um mit SQL Server-Kollatierungen und anderen Umgebungsproblemen zu funktionieren, die sich zwischen der in Windows ausgeführten Standard-CLR und der in SQL Server ausgeführten CLR unterscheiden.

Im Folgenden finden Sie einige zusätzliche Ressourcen von Microsoft zu verschiedenen Fallstricken beim Einbeziehen nicht unterstützter .NET Framework-Bibliotheken:


Ein paar Anmerkungen zu Ihrem Code:

  1. Bitte verwenden Sie keine .NET-Typen für Parameter, Eingabe oder Ausgabe. Daher ändern, um string encodedXMLzu sein SqlString encodedXML.
  2. Diese Funktion ist deterministisch und sollte daher als solche gekennzeichnet werden, da Sie sonst einen Leistungseinbruch erleiden. In IsDeterministic = truean das SqlFunctionAttribut.
Solomon Rutzky
quelle
8

Wie Sie bemerkt haben, System.Webhandelt es sich um eine nicht unterstützte Bibliothek. Um zu referenzieren, müssen System.WebSie einen Anruf tätigen CREATE ASSEMBLY. Es scheint, als hätten Sie das versucht, aber wie haben Sie auf den Standort von verwiesen System.Web.dll? Haben Sie es an einen anderen Ort kopiert / eingefügt? SQL Server versucht, abhängige Assemblys am selben Speicherort zu finden. Mit anderen Worten, wenn Sie auf den Speicherort System.Web.dllaller anderen abhängigen Bibliotheken verweisen, die sich im selben Verzeichnis befinden, sollte dies einwandfrei funktionieren. Hier ist ein Arbeitsbeispiel. Ich konnte sowohl die System.WebBaugruppe als auch Ihre Baugruppe hinzufügen :

create assembly [System.Web]
from 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Web.dll'
with permission_set = unsafe;
go

create assembly SystemWebTest
from 'c:\SqlServer\SystemWebTest.dll'
with permission_set = safe;
go

In den Clientnachrichten können Sie alle anderen Assemblys sehen, die SQL Server lädt. Beachten Sie jedoch, dass SQL Server für jede dieser Funktionen die folgende Warnung anzeigt:

Die Registrierung wird in der von SQL Server gehosteten Umgebung nicht vollständig getestet und nicht unterstützt. Wenn Sie diese Assembly oder das .NET Framework in Zukunft aktualisieren oder warten, funktioniert Ihre CLR-Integrationsroutine möglicherweise nicht mehr. Weitere Informationen finden Sie in den SQL Server-Onlinedokumenten.

System.WebSchauen Sie sich die folgenden hinzugefügten Assemblys an , aber fügen Sie sie hinzu:

select
    name,
    permission_set_desc,
    is_visible
from sys.assemblies
where is_user_defined = 1
order by is_visible desc;

name                                            permission_set_desc is_visible
System.Web                                      UNSAFE_ACCESS       1
SystemWebTest                                   SAFE_ACCESS         1
Microsoft.Build.Framework                       UNSAFE_ACCESS       0
System.Xaml                                     UNSAFE_ACCESS       0
System.ComponentModel.DataAnnotations           UNSAFE_ACCESS       0
System.Runtime.Caching                          UNSAFE_ACCESS       0
System.Web.ApplicationServices                  UNSAFE_ACCESS       0
System.Drawing                                  UNSAFE_ACCESS       0
Microsoft.Build.Utilities.v4.0                  UNSAFE_ACCESS       0
System.DirectoryServices                        UNSAFE_ACCESS       0
System.DirectoryServices.Protocols              UNSAFE_ACCESS       0
System.EnterpriseServices                       UNSAFE_ACCESS       0
System.Runtime.Remoting                         UNSAFE_ACCESS       0
System.Runtime.Serialization.Formatters.Soap    UNSAFE_ACCESS       0
System.Design                                   UNSAFE_ACCESS       0
System.Windows.Forms                            UNSAFE_ACCESS       0
Accessibility                                   UNSAFE_ACCESS       0
System.Drawing.Design                           UNSAFE_ACCESS       0
System.Web.RegularExpressions                   UNSAFE_ACCESS       0
Microsoft.Build.Tasks.v4.0                      UNSAFE_ACCESS       0
System.ServiceProcess                           UNSAFE_ACCESS       0
System.Configuration.Install                    UNSAFE_ACCESS       0
System.Runtime.Serialization                    UNSAFE_ACCESS       0
System.ServiceModel.Internals                   UNSAFE_ACCESS       0
SMDiagnostics                                   UNSAFE_ACCESS       0

Es lohnt sich, sich darüber im Klaren zu sein, was hier tatsächlich passiert, und obwohl die anderen zusätzlichen Assemblys keine Möglichkeiten für T-SQL-Einstiegspunkte haben, sind sie jetzt eine Abhängigkeit. Ich würde die Optionen abwägen, um zu sehen, ob Sie wirklich referenzierenSystem.Web müssen oder ob es einen anderen Weg gibt, um das zu erreichen, was Sie wollen.

Thomas Stringer
quelle
1
Danke Thomas, das hat funktioniert. Ich habe versucht, CREATE ASSEMBLY auf System.Web.dll zu zeigen, das über die GUI geschrieben wurde. Ich habe damit als Antwort auf einen Newsgroup-Beitrag (zuvor verlinkt) experimentiert, also kein brennender Wunsch, ihn selbst zu verwenden.
wBob
1
@wBob: Wenn Sie dies nicht unbedingt müssen, sollten Sie vorsichtig sein, wenn Sie nicht unterstützte DLLs hinzufügen. Es gibt einen guten Grund, der System.Webnicht in der Liste "Unterstützte Bibliotheken" enthalten ist, auf die Sie verlinkt haben: Es funktioniert nicht garantiert! . Es kann vorkommen, dass Sie auf Situationen stoßen, insbesondere wenn Sie mit ASCII-Zeichensätzen außerhalb der USA arbeiten, die sich nicht wie erwartet verhalten, und Microsoft wird dies nicht beheben. Ich werde in meiner Antwort einen Hinweis dazu hinzufügen, um denjenigen klar zu sein, die es vielleicht nicht wissen.
Solomon Rutzky
@ Srutzky Ich stimme zu.
wBob
1
Du bist ein Lebensretter. Ich würde SOL sein, wenn ich diese Bibliothek nicht importieren könnte. (Es ist einer dieser äußerst seltenen Fälle.)
Devinbost
5

Schauen Sie sich diese Antwort an . Sie müssen nicht verwenden Uri.UnescapeDataStringoder System.Web. Es gibt eine Klasse, die WebUtilityinnerhalb von System.Netmit den Funktionen HtmlEncodeund aufgerufen wird HtmlDecode.

Skelett
quelle
Sie sollten darauf hinweisen, dass dies WebUtilitynur für Benutzer mit SQL Server 2012, 2014 oder neuer verfügbar ist. Diejenigen, die sich noch in SQL Server 2005, 2008 und 2008 R2 befinden, können dies aufgrund der Einführung in .NET Framework 4.0 nicht verwenden.
Solomon Rutzky
@srutzky Die Frage ist für 2014, aber es ist wichtig, die Benutzer über diese Einschränkung zu informieren. Haben Sie einen Link, den ich veröffentlichen könnte, der die Beziehung zwischen der .NET Framework-Version und der SQL Server-Version zeigt?
Skelett
Mein Artikel wurde heute veröffentlicht, daher gibt es jetzt ein Diagramm, das die Beziehung zwischen SQL Server-Versionen und SQLCLR-Funktionen (einschließlich Framework- und CLR-Versionen) zeigt: Treppe zu SQLCLR Level 5: Entwicklung (Verwenden von .NET in SQL Server) (kostenlose Registrierung erforderlich) ).
Solomon Rutzky