Ensamblado 'system.web, versión = 4.0.0.0, cultura = neutral, publickeytoken = b03f5f7f11d50a3a'. no se encontró en el catálogo SQL

9

Estoy tratando de implementar una función CLR de SQL utilizando el método HTTPUtility.UrlDecode de System.Web pero no consigo que se implemente. Error recibido:

.Net SqlClient Data Provider: Msg 6503, Level 16, State 12, Line 1 Assembly 'system.web, version = 4.0.0.0, culture = neutral, publickeytoken = b03f5f7f11d50a3a.' no se encontró en el catálogo de SQL.

La función (como parte del proyecto 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);
    }
}

Está en relación con este hilo . Soy SQL Server 2014 con VS2012 SSDT y Proyecto de base de datos. He intentado con otros marcos de destino, por ejemplo, 3, 3.5, 4 y 4.5.

También probé CREATE ASSEMBLY con System.Web, pero luego tuve que agregar otros ensamblados, por ejemplo, Microsoft.Build, System.Xaml hasta que también fallaran. Veo System.Web no está en la lista de Bibliotecas compatibles, ¿ alguna idea?

wBob
fuente

Respuestas:

9

Puede usar Uri.UnescapeDataString (in System), en cuyo caso también necesitará hacer una Replace('+', ' ')en la cadena antes de pasarla Uri.UnescapeDataString, o si prefiere no molestarse con ella, esta función está disponible en la versión gratuita de SQL # (del cual soy autor).

Importar System.Webes probablemente más trabajo de lo que vale. Y de hecho, puede ser arriesgado. Hay una buena razón por la que System.Webno está en la lista de "Bibliotecas compatibles" a la que se vinculó en la pregunta: ¡ no se garantiza que funcione! Puede encontrarse con situaciones, especialmente cuando se trata de juegos de caracteres ASCII no estadounidenses, que no se comportan como se esperaba, y Microsoft no lo solucionará. Por lo tanto, a menos que sea absolutamente necesario , debe tener cuidado al agregar archivos DLL no compatibles. Las DLL en la lista "Compatible" se han probado y verificado completamente para que funcionen con las intercalaciones de SQL Server y cualquier otro problema ambiental que sea diferente entre el CLR estándar que se ejecuta en Windows y el CLR que se ejecuta dentro de SQL Server.

Aquí hay algunos recursos adicionales de Microsoft con respecto a varias dificultades para incorporar bibliotecas .NET Framework no compatibles:


Algunas notas sobre su código:

  1. No utilice tipos .NET para parámetros, entrada o salida. Por lo tanto, cambiar string encodedXMLpara ser SqlString encodedXML.
  2. Esta función es determinista, por lo que debe marcarse como tal, de lo contrario sufrirá un impacto en el rendimiento. Añadir IsDeterministic = trueal SqlFunctionatributo.
Solomon Rutzky
fuente
8

Como ha notado, System.Webes una biblioteca no compatible. Para hacer referencia System.Web, deberá llamar a CREATE ASSEMBLY. Parece que lo intentaste, pero ¿cómo hiciste referencia a la ubicación de System.Web.dll? ¿Lo copió / pegó en una ubicación diferente? SQL Server intentará ubicar ensamblados dependientes en la misma ubicación. En otras palabras, si hace referencia a la ubicación de System.Web.dlltodas las demás bibliotecas dependientes que viven en el mismo directorio, debería funcionar bien. Aquí hay un ejemplo de trabajo. Pude agregar tanto el System.Webensamblaje como tu ensamblaje:

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

Puede ver desde los mensajes del cliente todos los demás ensamblados que carga SQL Server. Pero tenga en cuenta que SQL Server muestra la siguiente advertencia para cada uno de estos:

no está completamente probado en el entorno alojado de SQL Server y no es compatible. En el futuro, si actualiza o da servicio a este ensamblado o .NET Framework, su rutina de integración CLR puede dejar de funcionar. Consulte los Libros en pantalla de SQL Server para obtener más detalles.

Del mismo modo, pero agregando System.Web, eche un vistazo a los siguientes conjuntos que se agregan:

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 tener en cuenta lo que realmente está sucediendo aquí, y aunque los otros ensamblados adicionales no tienen formas para los puntos de entrada T-SQL, ahora son una dependencia. Consideraría las opciones para ver si realmente necesita hacer referenciaSystem.Web , o si hay otra ruta para lograr lo que desea.

Thomas Stringer
fuente
1
Gracias Thomas, eso ha funcionado. Intenté CREAR ENSAMBLAJE apuntando a System.Web.dll con script a través de la GUI. Estaba experimentando con esto como una respuesta a una publicación de un grupo de noticias (vinculado anteriormente), por lo que no tengo un gran deseo de usarlo yo mismo.
wBob
1
@wBob: a menos que sea absolutamente necesario, debe tener cuidado al agregar archivos DLL no compatibles. Hay una buena razón por la que System.Webno está en la lista de "Bibliotecas compatibles" a la que se vinculó: ¡ no se garantiza que funcione! . Puede encontrarse con situaciones, especialmente cuando se trata de juegos de caracteres ASCII no estadounidenses, que no se comportan como se esperaba, y Microsoft no lo solucionará. Agregaré una nota sobre esto en mi respuesta solo para que quede claro para aquellos que quizás no lo sepan.
Solomon Rutzky
@srutzky Estoy de acuerdo.
wBob
1
Eres un salvavidas. Iba a ser SOL si no podía importar esta biblioteca. (Es uno de esos casos extremadamente raros.)
devinbost
5

Mira esta respuesta . No tienes que usar Uri.UnescapeDataStringo System.Web. Hay una clase llamada WebUtilitydentro de System.Netcon las funciones HtmlEncodey HtmlDecode.

skeletank
fuente
Debe señalar que WebUtilitysolo está disponible para aquellos que usan SQL Server 2012, 2014 o posterior. Aquellos que todavía usan SQL Server 2005, 2008 y 2008 R2 no podrán usar esto debido a que se introdujo en .NET Framework 4.0.
Solomon Rutzky
@srutzky La pregunta es para 2014, pero es importante informar a los usuarios sobre esta limitación. ¿Tiene un enlace que podría publicar que muestre la relación entre la versión de .NET Framework y la versión de SQL Server?
skeletank
Mi artículo se publicó hoy, así que ahora existe un gráfico que muestra la relación entre las versiones de SQL Server y las características de SQLCLR (incluidas las versiones Framework y CLR): Escalera a SQLCLR Nivel 5: Desarrollo (Uso de .NET en SQL Server) (se requiere registro gratuito )
Solomon Rutzky