Estou tentando implantar uma função SQL CLR usando o método HTTPUtility.UrlDecode de System.Web, mas não consigo implantá-la. Erro recebido:
Provedor de Dados .Net SqlClient: Msg 6503, Nível 16, Estado 12, Linha 1 Assembly 'system.web, versão=4.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a.' não foi encontrado no catálogo SQL.
A função (como parte do projeto 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);
}
}
É em relação a este tópico . Sou SQL Server 2014 com VS2012 SSDT e Projeto de Banco de Dados. Já tentei com outros Target Frameworks, por exemplo, 3, 3.5, 4 e 4.5.
Eu também tentei CREATE ASSEMBLY com System.Web, mas depois tenho que adicionar outros assemblies, por exemplo, Microsoft.Build, System.Xaml até que eles também falhem. Vejo que o System.Web não está na lista de bibliotecas com suporte , então alguma ideia?
Você pode usar Uri.UnescapeDataString (em
System
), caso em que também precisará fazer umReplace('+', ' ')
na string antes de passá-la paraUri.UnescapeDataString
, ou se preferir não se preocupar com isso, esta função está disponível na versão gratuita do SQL# (do qual sou o autor).Importar
System.Web
é provavelmente mais trabalho do que vale a pena. E, de fato, pode ser arriscado. Há um bom motivo paraSystem.Web
não estar na lista de "Bibliotecas suportadas" à qual você vinculou na pergunta: não é garantido que funcione! Você pode se deparar com situações, especialmente ao lidar com conjuntos de caracteres ASCII não americanos, que não se comportam conforme o esperado e a Microsoft não corrigirá isso. Portanto, a menos que seja absolutamente necessário, você deve ter cuidado ao adicionar DLLs não suportadas. As DLLs na lista "compatível" foram totalmente testadas e verificadas para funcionar com agrupamentos do SQL Server e quaisquer outros problemas ambientais que sejam diferentes entre o CLR padrão em execução no Windows e o CLR em execução no SQL Server.Aqui estão alguns recursos adicionais da Microsoft sobre várias armadilhas para incorporar bibliotecas .NET Framework sem suporte:
Política de suporte para assemblies .NET Framework não testados no ambiente hospedado no SQL Server CLR
Mensagem de erro ao executar uma rotina CLR ou usar um assembly no SQL Server: "O assembly no armazenamento do host tem uma assinatura diferente do assembly no GAC. (Exceção de HRESULT: 0x80131050)"
Algumas notas sobre o seu código:
string encodedXML
para serSqlString encodedXML
.IsDeterministic = true
aoSqlFunction
atributo.Como você observou,
System.Web
é uma biblioteca sem suporte. Para fazer referênciaSystem.Web
, você precisará fazer uma chamada paraCREATE ASSEMBLY
. Parece que você tentou isso, mas como você referenciou a localização deSystem.Web.dll
? Você copiou / colou em um local diferente? O SQL Server tentará localizar assemblies dependentes no mesmo local. Em outras palavras, se você referenciar a localização deSystem.Web.dll
todas as outras bibliotecas dependentes que vivem no mesmo diretório, deve funcionar bem. Aqui está um exemplo de trabalho. Consegui adicionar tanto oSystem.Web
assembly quanto o seu assembly:Você pode ver nas mensagens do cliente todos os outros assemblies carregados pelo SQL Server. Mas observe que o SQL Server exibe o seguinte aviso para cada um deles:
Da mesma forma, mas adicionando
System.Web
, observe os seguintes assemblies adicionados:Vale a pena estar atento ao que realmente está acontecendo aqui e, embora os outros assemblies adicionais não tenham maneiras de pontos de entrada do T-SQL, eles agora são uma dependência. Eu pesaria as opções para ver se você realmente precisa referenciar
System.Web
, ou se existe outra rota para realizar o que deseja.Confira esta resposta . Você não precisa usar
Uri.UnescapeDataString
ouSystem.Web
. Existe uma classe chamadaWebUtility
dentro deSystem.Net
com as funçõesHtmlEncode
eHtmlDecode
.