Zestaw „system.web, wersja = 4.0.0.0, kultura = neutralna, publickeytoken = b03f5f7f11d50a3a.” nie znaleziono w katalogu SQL

9

Próbuję wdrożyć funkcję SQL CLR przy użyciu metody HTTPUtility.UrlDecode z System.Web, ale nie mogę jej zmusić do wdrożenia. Otrzymany błąd:

.Net SqlClient Data Provider: Msg 6503, poziom 16, stan 12, zestaw wiersza 1 „system.web, wersja = 4.0.0.0, kultura = neutralna, publickeytoken = b03f5f7f11d50a3a.” nie znaleziono w katalogu SQL.

Funkcja (w ramach projektu SSDT):

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

Dotyczy to tego wątku . Jestem SQL Server 2014 z VS2012 SSDT i projektem bazy danych. Próbowałem z innymi strukturami docelowymi, np. 3, 3,5, 4 i 4,5.

Próbowałem także UTWÓRZ ASSEMBLY z System.Web, ale potem musiałem dodawać inne zestawy, np. Microsoft.Build, System.Xaml, dopóki one również nie zawiodą. Widzę System.Web nie ma na liście obsługiwanych bibliotek, więc jakieś pomysły?

wBob
źródło

Odpowiedzi:

9

Możesz użyć Uri.UnescapeDataString (in System), w którym to przypadku musisz również wykonać Replace('+', ' ')ciąg przed przekazaniem go Uri.UnescapeDataString, lub jeśli wolisz nie zawracać sobie nim głowy, ta funkcja jest dostępna w darmowej wersji SQL # (którego jestem autorem).

Importowanie System.Webto prawdopodobnie więcej pracy niż jest warte. I w rzeczywistości może być ryzykowne. Istnieje dobry powód, którego System.Webnie ma na liście „Obsługiwanych bibliotek”, do której prowadzi link w pytaniu: nie gwarantuje się, że zadziała! Możesz napotkać sytuacje, szczególnie w przypadku zestawów znaków ASCII spoza USA, które nie zachowują się zgodnie z oczekiwaniami, a Microsoft nie naprawi tego. Tak więc, chyba że jest to absolutnie konieczne, należy zachować ostrożność przy dodawaniu nieobsługiwanych bibliotek DLL. Biblioteki DLL z listy „Obsługiwane” zostały w pełni przetestowane i zweryfikowane pod kątem współpracy z zestawieniami SQL Server i wszelkimi innymi problemami środowiskowymi, które różnią się między standardowym CLR działającym w systemie Windows a CLR działającym w SQL Server.

Oto kilka dodatkowych zasobów firmy Microsoft dotyczących kilku pułapek związanych z włączaniem nieobsługiwanych bibliotek .NET Framework:


Kilka uwag na temat twojego kodu:

  1. Nie używaj typów .NET dla parametrów, danych wejściowych lub wyjściowych. Dlatego zmień się string encodedXMLna SqlString encodedXML.
  2. Ta funkcja jest deterministyczna, dlatego należy ją oznaczyć jako taką, w przeciwnym razie wystąpi spadek wydajności. Dodaj IsDeterministic = truedo SqlFunctionatrybutu.
Solomon Rutzky
źródło
8

Jak zauważyłeś, System.Webjest nieobsługiwaną biblioteką. Aby się odwołać System.Web, musisz zadzwonić do CREATE ASSEMBLY. Wygląda na to, że próbowałeś tego, ale jak odnalazłeś lokalizację System.Web.dll? Czy skopiowałeś / wkleiłeś go w inne miejsce? SQL Server spróbuje zlokalizować zależne zestawy w tej samej lokalizacji. Innymi słowy, jeśli odwołujesz się do lokalizacji System.Web.dllwszystkich pozostałych bibliotek zależnych mieszkających w tym samym katalogu, powinno działać dobrze. Oto działający przykład. Mogłem dodać zarówno System.Webzestaw, jak i twój zestaw:

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

Możesz zobaczyć z komunikatów klienta wszystkie inne zestawy ładowane przez SQL Server. Pamiętaj jednak, że SQL Server wyświetla następujące ostrzeżenie dla każdego z nich:

rejestracja nie jest w pełni przetestowana w środowisku hostowanym SQL Server i nie jest obsługiwana. W przyszłości, jeśli uaktualnisz lub serwisujesz ten zestaw lub platformę .NET Framework, procedura integracji CLR może przestać działać. Więcej informacji można znaleźć w dokumentacji SQL Server Books Online.

Podobnie, ale dodając System.Web, spójrz na następujące dodane zespoły:

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

Warto pamiętać o tym, co faktycznie się tutaj dzieje, i chociaż inne dodatkowe zestawy nie mają możliwości uzyskania punktów wejścia T-SQL, są one teraz zależne. Zastanowiłbym się nad opcjami, aby zobaczyć, czy naprawdę potrzebujesz odniesieniaSystem.Web , czy też istnieje inna droga do osiągnięcia tego, co chcesz.

Thomas Stringer
źródło
1
Dzięki Thomas, to zadziałało. Próbowałem CREATE ASSEMBLY, wskazując skrypt System.Web.dll za pomocą GUI. Eksperymentowałem z tym jako odpowiedzią na post w grupie dyskusyjnej (poprzednio linkowany), więc nie mam ochoty używać go sam.
wBob
1
@wBob: chyba że jest to absolutnie konieczne, należy zachować ostrożność przy dodawaniu nieobsługiwanych bibliotek DLL. Istnieje dobry powód, którego System.Webnie ma na liście „Obsługiwane biblioteki”, do której prowadzisz link: nie gwarantuje się, że będzie działał! . Możesz napotkać sytuacje, szczególnie w przypadku zestawów znaków ASCII spoza USA, które nie zachowują się zgodnie z oczekiwaniami, a Microsoft nie naprawi tego. Dodam notatkę na ten temat w mojej odpowiedzi, aby było jasne dla tych, którzy mogą nie wiedzieć.
Solomon Rutzky
@srutzky Zgadzam się.
wBob
1
Jesteś ratownikiem. Miałem zostać SOL, jeśli nie mogę zaimportować tej biblioteki. (To jeden z tych niezwykle rzadkich przypadków.)
devinbost,
5

Sprawdź tę odpowiedź . Nie musisz używać Uri.UnescapeDataStringlub System.Web. Istnieje klasa wywoływana WebUtilitywewnątrz System.Netz funkcjami HtmlEncodei HtmlDecode.

szkielet
źródło
Należy zauważyć, że WebUtilityjest dostępny tylko dla osób korzystających z SQL Server 2012, 2014 lub nowszych. Ci, którzy nadal korzystają z SQL Server 2005, 2008 i 2008 R2, nie będą mogli tego użyć, ponieważ został wprowadzony w .NET Framework 4.0.
Solomon Rutzky
@srutzky Pytanie dotyczy 2014 r., ale ważne jest, aby poinformować użytkowników o tym ograniczeniu. Czy masz link, który mógłbym opublikować, który pokazuje związek między wersją .NET Framework a wersją SQL Server?
skeletank
Mój artykuł został opublikowany dzisiaj, więc teraz istnieje wykres pokazujący związek między wersjami SQL Server a funkcjami SQLCLR (w tym wersjami Framework i CLR): Schody do SQLCLR Poziom 5: Programowanie (Korzystanie z .NET w SQL Server) (wymagana jest darmowa rejestracja ).
Solomon Rutzky