web-dev-qa-db-fra.com

Assembly 'system.web, version = 4.0.0.0, culture = neutre, publickeytoken = b03f5f7f11d50a3a.' est introuvable dans le catalogue SQL

J'essaie de déployer une fonction SQL CLR à l'aide de la méthode HTTPUtility.UrlDecode de System.Web mais je n'arrive pas à la faire déployer. Erreur reçue:

.Net SqlClient Data Provider: Msg 6503, Level 16, State 12, Line 1 Assembly 'system.web, version = 4.0.0.0, culture = neutral, publickeytoken = b03f5f7f11d50a3a.' est introuvable dans le catalogue SQL.

La fonction (dans le cadre du projet 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);
    }
}

C'est par rapport à cela thread . Je suis SQL Server 2014 avec VS2012 SSDT et projet de base de données. J'ai essayé avec d'autres cadres cibles, par exemple 3, 3.5, 4 et 4.5.

J'ai également essayé CREATE Assembly avec System.Web, mais je dois ensuite ajouter d'autres assemblys, par exemple Microsoft.Build, System.Xaml jusqu'à ce qu'ils échouent également. Je vois que System.Web n'est pas sur la liste des Bibliothèques prises en charge donc des idées?

9
wBob

Vous pouvez soit utiliser ri.UnescapeDataString (dans System), auquel cas vous devrez également faire une Replace('+', ' ') sur la chaîne avant en le passant à Uri.UnescapeDataString, ou si vous préférez ne pas vous embêter, cette fonction est disponible dans la version gratuite de SQL # (dont je suis l'auteur).

Importation de System.Web est probablement plus de travail qu'il n'en vaut la peine. Et en fait, cela peut être risqué. Il y a une bonne raison pour que System.Web ne figure pas dans la liste "Bibliothèques prises en charge" à laquelle vous avez lié dans la question: il n'est pas garanti de fonctionner! Vous pourriez rencontrer des situations, en particulier lorsqu'il s'agit de jeux de caractères non américains ASCII, qui ne se comportent pas comme prévu, et Microsoft ne le corrigera pas. Donc, sauf si vous absolument devez , vous devez faire attention à l'ajout de DLL non prises en charge. Les DLL de la liste "Pris en charge" ont été entièrement testées et vérifiées pour fonctionner avec les classements SQL Server et tout autre problème environnemental différent entre le CLR standard exécuté dans Windows et le CLR exécuté à l'intérieur de SQL Server.

Voici quelques ressources supplémentaires de Microsoft concernant plusieurs pièges à l'incorporation de bibliothèques .NET Framework non prises en charge:


Quelques notes sur votre code:

  1. Veuillez ne pas utiliser les types .NET pour les paramètres, les entrées ou les sorties. Par conséquent, modifiez string encodedXML être SqlString encodedXML.
  2. Cette fonction est déterministe et doit donc être marquée comme telle, sinon vous subirez un impact sur les performances. Ajouter IsDeterministic = true à l'attribut SqlFunction.
9
Solomon Rutzky

Comme vous l'avez noté, System.Web est une bibliothèque non prise en charge. Afin de référencer System.Web vous devrez appeler CREATE Assembly. Il semble que vous ayez essayé, mais comment avez-vous référencé l'emplacement de System.Web.dll? L'avez-vous copié/collé vers un autre emplacement? SQL Server essaiera de localiser les assemblys dépendants au même emplacement. En d'autres termes, si vous faites référence à l'emplacement de System.Web.dll avec toutes les autres bibliothèques dépendantes vivant dans le même répertoire, cela devrait très bien fonctionner. Voici un exemple de travail. J'ai pu ajouter à la fois le System.Web Assemblée ainsi que votre Assemblée:

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

Vous pouvez voir dans les messages client tous les autres assemblys que SQL Server charge. Mais prenez note, SQL Server affiche l'avertissement suivant pour chacun d'eux:

que vous enregistrez n'est pas entièrement testé dans l'environnement hébergé SQL Server et n'est pas pris en charge. À l'avenir, si vous mettez à niveau ou réparez cet assembly ou le .NET Framework, votre routine d'intégration CLR peut cesser de fonctionner. Veuillez consulter la documentation en ligne de SQL Server pour plus de détails.

De même, mais en ajoutant System.Web, jetez un œil aux assemblys suivants qui sont ajoutés:

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

Il convient de garder à l'esprit ce qui se passe réellement ici, et même si les autres assemblys supplémentaires n'ont pas de moyen pour les points d'entrée T-SQL, ils sont maintenant une dépendance. Je peserais les options pour voir si vous avez vraiment besoin de référencer System.Web, ou s'il existe un autre itinéraire pour accomplir ce que vous voulez.

8
Thomas Stringer

Découvrez cette réponse . Vous n'êtes pas obligé d'utiliser Uri.UnescapeDataString ou System.Web. Il y a une classe appelée WebUtility à l'intérieur de System.Net avec les fonctions HtmlEncode et HtmlDecode.

5
skeletank