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


9

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 à ce fil . 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?

Réponses:


9

Vous pouvez soit utiliser Uri.UnescapeDataString (in System), auquel cas vous devrez également faire un Replace('+', ' ')sur la chaîne avant de le passer 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).

L'importation System.Webest probablement plus de travail qu'elle n'en vaut la peine. Et en fait, cela peut être risqué. Il y a une bonne raison qui System.Webne 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 pouvez rencontrer des situations, en particulier lorsqu'il s'agit de jeux de caractères ASCII non américains, qui ne se comportent pas comme prévu, et Microsoft ne le corrigera pas. Donc, à moins que vous ne deviez absolument le faire, vous devez faire attention à ajouter des 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, changez string encodedXMLpour ê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. Ajoutez IsDeterministic = trueà l' SqlFunctionattribut.

8

Comme vous l'avez noté, System.Webest une bibliothèque non prise en charge. Pour pouvoir System.Webvous y référer, 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é à un autre emplacement? SQL Server essaiera de localiser les assemblys dépendants au même emplacement. En d'autres termes, si vous référencez l'emplacement de System.Web.dlltoutes les autres bibliothèques dépendantes vivant dans le même répertoire, cela devrait fonctionner correctement. Voici un exemple de travail. J'ai pu ajouter à la fois l' System.Webassemblage et votre assemblage:

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. J'évaluerais les options pour voir si vous avez vraiment besoin de faire référenceSystem.Web , ou s'il existe une autre voie pour accomplir ce que vous voulez.


1
Merci Thomas, cela a fonctionné. J'essayais CREATE ASSEMBLY pointant sur System.Web.dll scripté via l'interface graphique. J'expérimentais cela en réponse à un message de groupe de discussion (lié précédemment), donc pas de désir ardent de l'utiliser moi-même.
wBob

1
@wBob: à moins que vous ne deviez absolument le faire, vous devez faire attention à ajouter des DLL non prises en charge. Il y a une bonne raison qui System.Webne figure pas dans la liste "Bibliothèques prises en charge" à laquelle vous avez lié: il n'est pas garanti de fonctionner! . Vous pouvez rencontrer des situations, en particulier lorsqu'il s'agit de jeux de caractères ASCII non américains, qui ne se comportent pas comme prévu, et Microsoft ne le corrigera pas. J'ajouterai une note à ce sujet dans ma réponse pour être clair pour ceux qui ne le savent pas.
Solomon Rutzky

@srutzky, je suis d'accord.
wBob

1
Tu es un sauveur. J'allais être SOL si je ne pouvais pas importer cette bibliothèque. (C'est l'un de ces cas extrêmement rares.)
devinbost

5

Découvrez cette réponse . Vous n'avez pas besoin d'utiliser Uri.UnescapeDataStringou System.Web. Il existe une classe appelée à l' WebUtilityintérieur de System.Netavec les fonctions HtmlEncodeet HtmlDecode.


Vous devez souligner que cette WebUtilityoption n'est disponible que pour ceux qui utilisent SQL Server 2012, 2014 ou une version plus récente. Ceux qui sont encore sur SQL Server 2005, 2008 et 2008 R2 ne pourront pas l'utiliser en raison de son introduction dans .NET Framework 4.0.
Solomon Rutzky

@srutzky La question concerne 2014, mais il est important de faire connaître cette limitation aux utilisateurs. Avez-vous un lien que je pourrais publier qui montre la relation entre la version de .NET Framework et la version de SQL Server?
skeletank

Mon article a été publié aujourd'hui, il existe maintenant un graphique montrant la relation entre les versions de SQL Server et les fonctionnalités SQLCLR (y compris les versions Framework et CLR): Stairway to SQLCLR Level 5: Development (Using .NET within SQL Server) (inscription gratuite est requise ).
Solomon Rutzky
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.