Assembly "system.web, version = 4.0.0.0, culture = neutral, publickeytoken = b03f5f7f11d50a3a." non è stato trovato nel catalogo SQL


9

Sto cercando di distribuire una funzione CLR SQL utilizzando il metodo HTTPUtility.UrlDecode di System.Web ma non riesco a farlo distribuire. Errore ricevuto:

.Net SqlClient Data Provider: Msg 6503, Level 16, State 12, Line 1 Assembly 'system.web, version = 4.0.0.0, culture = neutral, publickeytoken = b03f5f7f11d50a3a.' non è stato trovato nel catalogo SQL.

La funzione (come parte del progetto 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);
    }
}

È in relazione a questo thread . Sono SQL Server 2014 con VS2012 SSDT e Database Project. Ho provato con altri Target Frameworks, ad esempio 3, 3.5, 4 e 4.5.

Ho anche provato a CREARE ASSEMBLY con System.Web, ma poi devo aggiungere altri assembly, ad esempio Microsoft.Build, System.Xaml fino a quando non falliscono. Vedo System. Web non è nell'elenco delle librerie supportate, quindi qualche idea?

Risposte:


9

Puoi usare Uri.UnescapeDataString (in System), nel qual caso dovrai anche fare una Replace('+', ' ')stringa prima di passarla a Uri.UnescapeDataString, o se preferisci non disturbarti, questa funzione è disponibile nella versione gratuita di SQL # (di cui sono l'autore).

L'importazione System.Webè probabilmente più lavoro di quanto valga la pena. E in effetti, può essere rischioso. C'è una buona ragione che System.Webnon è nell'elenco "Librerie supportate" a cui sei collegato nella domanda: non è garantito che funzioni! Potresti imbatterti in situazioni, in particolare quando hai a che fare con set di caratteri ASCII non statunitensi, che non si comportano come previsto e Microsoft non lo risolverà. Pertanto, a meno che non sia assolutamente necessario, è necessario prestare attenzione all'aggiunta di DLL non supportate. Le DLL nell'elenco "Supportato" sono state completamente testate e verificate per funzionare con regole di confronto di SQL Server e qualsiasi altro problema ambientale diverso tra CLR standard in esecuzione in Windows e CLR in esecuzione all'interno di SQL Server.

Ecco alcune risorse aggiuntive di Microsoft relative a diverse insidie ​​nell'incorporare librerie .NET Framework non supportate:


Alcune note sul tuo codice:

  1. Non utilizzare i tipi .NET per parametri, input o output. Quindi, cambia string encodedXMLper essere SqlString encodedXML.
  2. Questa funzione è deterministica, quindi dovrebbe essere contrassegnata come tale, altrimenti si subirà un calo delle prestazioni. Aggiungere IsDeterministic = trueal SqlFunctionattributo.

8

Come hai notato, System.Webè una libreria non supportata. Per fare riferimento System.Webdevi fare una chiamata a CREATE ASSEMBLY. Sembra che tu ci abbia provato, ma come hai fatto riferimento alla posizione di System.Web.dll? L'hai copiato / incollato in un'altra posizione? SQL Server tenterà di individuare gli assembly dipendenti nella stessa posizione. In altre parole, se fai riferimento alla posizione di System.Web.dllcon tutte le altre librerie dipendenti che vivono nella stessa directory, dovrebbe funzionare bene. Ecco un esempio funzionante. Sono stato in grado di aggiungere sia l' System.Webassembly che l'assemblaggio:

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

Dai messaggi client è possibile visualizzare tutti gli altri assembly caricati da SQL Server. Ma prendi nota, SQL Server visualizza il seguente avviso per ognuno di questi:

la registrazione non è stata completamente testata nell'ambiente ospitato di SQL Server e non è supportata. In futuro, se si aggiorna o si esegue la manutenzione di questo assembly o .NET Framework, la routine di integrazione CLR potrebbe smettere di funzionare. Per ulteriori dettagli, consultare la documentazione online di SQL Server.

Allo stesso modo, ma aggiungendo System.Web, dai un'occhiata ai seguenti assiemi aggiunti:

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

Vale la pena prestare attenzione a ciò che sta realmente accadendo qui, e anche se gli altri assembly aggiuntivi non hanno modi per i punti di ingresso T-SQL, ora sono una dipendenza. Vorrei soppesare le opzioni per vedere se hai davvero bisogno di fare riferimentoSystem.Web o se esiste un altro percorso per realizzare ciò che desideri.


1
Grazie Thomas, ha funzionato. Stavo provando CREATE ASSEMBLY indicando System.Web.dll tramite script tramite la GUI. Stavo sperimentando questo come una risposta a un post di un newsgroup (precedentemente collegato), quindi nessun desiderio ardente di usarlo da solo.
wBob,

1
@wBob: a meno che non sia assolutamente necessario, è necessario prestare attenzione all'aggiunta di DLL non supportate. C'è una buona ragione che System.Webnon è nell'elenco "Librerie supportate" a cui sei collegato: non è garantito che funzioni! . Potresti imbatterti in situazioni, in particolare quando hai a che fare con set di caratteri ASCII non statunitensi, che non si comportano come previsto e Microsoft non lo risolverà. Aggiungerò una nota al riguardo nella mia risposta solo per essere chiari per coloro che potrebbero non saperlo.
Solomon Rutzky,

@srutzky Sono d'accordo.
wBob,

1
Sei un salvavita. Sarei diventato SOL se non avessi potuto importare questa libreria. (È uno di quei casi estremamente rari.)
Devinbost

5

Dai un'occhiata a questa risposta . Non devi usare Uri.UnescapeDataStringo System.Web. C'è una classe chiamata WebUtilitydentro System.Netcon le funzioni HtmlEncodee HtmlDecode.


È necessario sottolineare che WebUtilityè disponibile solo per coloro che utilizzano SQL Server 2012, 2014 o versioni successive. Quelli ancora su SQL Server 2005, 2008 e 2008 R2 non potranno usarlo a causa dell'introduzione in .NET Framework 4.0.
Solomon Rutzky,

@srutzky La domanda è per il 2014 ma è importante informare gli utenti su questa limitazione. Hai un link che potrei pubblicare che mostra la relazione tra la versione di .NET Framework e la versione di SQL Server?
scheletro

Il mio articolo è stato pubblicato oggi, quindi ora esiste un grafico che mostra la relazione tra le versioni di SQL Server e le funzionalità SQLCLR (comprese le versioni Framework e CLR): Stairway to SQLCLR Level 5: Development (Using .NET in SQL Server) (è richiesta la registrazione gratuita ).
Solomon Rutzky,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.