2015-01-31 9 views
5

Mam następujące rekordy w jednym z moich tabeliCzy istnieje sposób na dekodowanie HTML w SQL Server?

CD&M Communications 
auburndale oil & propane inc 
C F La Fountaine #7561 
Laramie County Fire District # 2 
AmeriGas Propane LP #2250 

Czy istnieje sposób, aby usunąć znaki jak „&”, # 7561, # 2250 itp

„&” należy zastąpić & zgodnie z funkcją C# HTMLDECODE

+2

Funkcja CLR może pracować dla ciebie, ale ogólnie zrobiłbym coś takiego poza bazą danych – Madison

+0

[this] (http://stackoverflow.com/questions/3833229/sql-server-url-decoding) pomóżcie .. –

+0

* Dlaczego * jest kodowany kod HTML w bazie danych? – Tomalak

Odpowiedz

8

Następująca funkcja SQL działałaby w Twoim przypadku lub byłby to dobry punkt wyjścia do jej przedłużenia. Należy jednak pamiętać, że manipulacje ciągami w bazie danych [SQL Server] będą wolniejsze w porównaniu do manipulacji łańcuchami w warstwie aplikacji.

GO 

IF OBJECT_ID('dbo.MyHTMLDecode') IS NOT NULL BEGIN DROP FUNCTION dbo.MyHTMLDecode END 

GO 
CREATE FUNCTION dbo.MyHTMLDecode (@vcWhat VARCHAR(MAX)) 
RETURNS VARCHAR(MAX) 
AS 
BEGIN 
    DECLARE @vcResult VARCHAR(MAX) 
    DECLARE @siPos INT 
     ,@vcEncoded VARCHAR(7) 
     ,@siChar INT 

    SET @vcResult = RTRIM(LTRIM(CAST(REPLACE(@vcWhat COLLATE Latin1_General_BIN, CHAR(0), '') AS VARCHAR(MAX)))) 

    SELECT @vcResult = REPLACE(REPLACE(@vcResult, ' ', ' '), ' ', ' ') 

    IF @vcResult = '' 
     RETURN @vcResult 

    SELECT @siPos = PATINDEX('%&#[0-9][0-9][0-9];%', @vcResult) 

    WHILE @siPos > 0 
    BEGIN 
     SELECT @vcEncoded = SUBSTRING(@vcResult, @siPos, 6) 
      ,@siChar = CAST(SUBSTRING(@vcEncoded, 3, 3) AS INT) 
      ,@vcResult = REPLACE(@vcResult, @vcEncoded, NCHAR(@siChar)) 
      ,@siPos = PATINDEX('%&#[0-9][0-9][0-9];%', @vcResult) 
    END 

    SELECT @siPos = PATINDEX('%&#[0-9][0-9][0-9][0-9];%', @vcResult) 

    WHILE @siPos > 0 
    BEGIN 
     SELECT @vcEncoded = SUBSTRING(@vcResult, @siPos, 7) 
      ,@siChar = CAST(SUBSTRING(@vcEncoded, 3, 4) AS INT) 
      ,@vcResult = REPLACE(@vcResult, @vcEncoded, NCHAR(@siChar)) 
      ,@siPos = PATINDEX('%&#[0-9][0-9][0-9][0-9];%', @vcResult) 
    END 

    SELECT @siPos = PATINDEX('%#[0-9][0-9][0-9][0-9]%', @vcResult) 

    WHILE @siPos > 0 
    BEGIN 
     SELECT @vcEncoded = SUBSTRING(@vcResult, @siPos, 5) 
      ,@vcResult = REPLACE(@vcResult, @vcEncoded, '') 
      ,@siPos = PATINDEX('%#[0-9][0-9][0-9][0-9]%', @vcResult) 
    END 

    SELECT @vcResult = REPLACE(REPLACE(@vcResult, NCHAR(160), ' '), CHAR(160), ' ') 

    SELECT @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vcResult, '&amp;', '&'), '&quot;', '"'), '&lt;', '<'), '&gt;', '>'), '&amp;amp;', '&') 

    RETURN @vcResult 
END 

GO 

Ilustracja:

DECLARE @S VARCHAR(MAX)='CD&amp;amp;amp;M Communications 
    auburndale oil &amp;amp;amp; propane inc 
    C F La Fountaine #7561 
    Laramie County Fire District # 2 
    AmeriGas Propane LP #2250' 

    SELECT dbo.MyHTMLDecode (@s) 

WYJŚCIE:

CD&M Communications 
auburndale oil & propane inc 
C F La Fountaine 
Laramie County Fire District # 2 
AmeriGas Propane LP 
+0

Ten skrypt działał świetnie, ale pominął niektóre znaki. Musiałem dodać 'REPLACE (@vcResult, '"', '"') ',' REPLACE (@vcResult, '&', '&') ',' REPLACE (@vcResult, '*', '*') ',' REPLACE (@vcResult, '+', '+') 'i' REPLACE (@vcResult, '/', '/') '. –

4

Poprzednia wersja nie współpracuje z Japonii, koreański, ... Tutaj ustalona wersja:

GO 
IF OBJECT_ID('dbo.fn_HTMLDecode') IS NOT NULL BEGIN DROP FUNCTION dbo.fn_HTMLDecode END 
GO 
CREATE FUNCTION dbo.fn_HTMLDecode(
    @vcWhat NVARCHAR(MAX) 
    ,@toDecodeMainISOSymbols bit = 1 
    ,@toDecodeISOChars bit = 1 
) 
RETURNS NVARCHAR(MAX) 
AS 
BEGIN 
    DECLARE @vcResult NVARCHAR(MAX); 
    DECLARE @siPos INT ,@vcEncoded NVARCHAR(9) ,@siChar INT; 
    SET @vcResult = RTRIM(LTRIM(CAST(REPLACE(@vcWhat COLLATE Latin1_General_BIN, CHAR(0), '') AS NVARCHAR(MAX)))); 
    SELECT @vcResult = REPLACE(REPLACE(@vcResult, '&#160;', ' '), '&nbsp;', ' '); 
    IF @vcResult = '' RETURN @vcResult; 

    declare @s varchar(35); 
    declare @n int; set @n = 6; 
    declare @i int; 

    while @n > 2 
    begin 
     set @s = ''; 
     set @i=1; 
     while @i<[email protected] 
     begin 
      set @s = @s + '[0-9]'; 
      set @i = @i + 1; 
     end 
     set @s = '%&#' + @s + '%'; 
     SELECT @siPos = PATINDEX(@s, @vcResult); 
     WHILE @siPos > 0 
     BEGIN 
      SELECT @vcEncoded = SUBSTRING(@vcResult, @siPos, @n+3) 
       ,@siChar = CAST(SUBSTRING(@vcEncoded, 3, @n) AS INT) 
       ,@vcResult = REPLACE(@vcResult, @vcEncoded, NCHAR(@siChar)) 
       ,@siPos = PATINDEX(@s, @vcResult); 
     END 
     set @n = @n - 1; 
    end 

    if @toDecodeMainISOSymbols=1 
    begin 
     select @vcResult = REPLACE(REPLACE(@vcResult, NCHAR(160), ' '), CHAR(160), ' '); 
     select @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vcResult, '&amp;', '&'), '&quot;', '"'), '&lt;', '<'), '&gt;', '>'), '&amp;amp;', '&'),'&rdquo;','”'),'&bdquo;','„'),'&ndash;','–'),'&mdash;','—'); 
     select @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vcResult,'&lsquo;','‘'),'&rsquo;','’'),'&bull;','•'),'&hellip;','…'),'&permil;','‰') COLLATE Latin1_General_BIN,'&prime;','′') COLLATE Latin1_General_BIN,'&Prime;','″'),'&circ;','ˆ'),'&tilde;','˜'),'&nbsp;',' '); 
    end 

    if @toDecodeISOChars=1 
    begin 
     select @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(@vcResult COLLATE Latin1_General_BIN,'&Scaron;','Š') COLLATE Latin1_General_BIN,'&scaron;','š') COLLATE Latin1_General_BIN,'&Ccedil;','Ç') COLLATE Latin1_General_BIN,'&ccedil;','ç'); 
     select @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vcResult,'&Agrave;','À') COLLATE Latin1_General_BIN,'&agrave;','à') COLLATE Latin1_General_BIN,'&Aacute;','Á') COLLATE Latin1_General_BIN,'&aacute;','á') COLLATE Latin1_General_BIN,'&Acirc;','Â') COLLATE Latin1_General_BIN,'&acirc;','â') COLLATE Latin1_General_BIN,'&Atilde;','Ã') COLLATE Latin1_General_BIN,'&atilde;','ã') COLLATE Latin1_General_BIN,'&Auml;','Ä') COLLATE Latin1_General_BIN,'&auml;','ä') COLLATE Latin1_General_BIN,'&Aring;','Å') COLLATE Latin1_General_BIN,'&aring;','å') COLLATE Latin1_General_BIN,'&AElig;','Æ') COLLATE Latin1_General_BIN,'&aelig;','æ'); 
     select @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vcResult COLLATE Latin1_General_BIN,'&Egrave','È') COLLATE Latin1_General_BIN,'&egrave','è') COLLATE Latin1_General_BIN,'&Eacute;','É') COLLATE Latin1_General_BIN,'&eacute;','é') COLLATE Latin1_General_BIN,'&Ecirc;','Ê') COLLATE Latin1_General_BIN,'&ecirc;','ê') COLLATE Latin1_General_BIN,'&Euml;','Ë') COLLATE Latin1_General_BIN,'&euml;','ë'); 
     select @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vcResult COLLATE Latin1_General_BIN,'&Igrave;','Ì') COLLATE Latin1_General_BIN,'&igrave;','ì') COLLATE Latin1_General_BIN,'&Iacute;','Í') COLLATE Latin1_General_BIN,'&iacute;','í') COLLATE Latin1_General_BIN,'&Icirc;','Î') COLLATE Latin1_General_BIN,'&icirc;','î') COLLATE Latin1_General_BIN,'&Iuml;','Ï') COLLATE Latin1_General_BIN,'&iuml;','ï'); 
     select @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vcResult COLLATE Latin1_General_BIN,'&Ograve;','Ò') COLLATE Latin1_General_BIN,'&ograve;','ò') COLLATE Latin1_General_BIN,'&Oacute;','Ó') COLLATE Latin1_General_BIN,'&oacute;','ó') COLLATE Latin1_General_BIN,'&Ocirc;','Ô') COLLATE Latin1_General_BIN,'&ocirc;','ô') COLLATE Latin1_General_BIN,'&Otilde;','Õ') COLLATE Latin1_General_BIN,'&otilde;','õ') COLLATE Latin1_General_BIN,'&Ouml;','Ö') COLLATE Latin1_General_BIN,'&ouml;','ö') COLLATE Latin1_General_BIN,'&Oslash','Ø') COLLATE Latin1_General_BIN,'&oslash','ø'); 
     select @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vcResult COLLATE Latin1_General_BIN,'&Ugrave;','Ù') COLLATE Latin1_General_BIN,'&ugrave;','ù') COLLATE Latin1_General_BIN,'&Uacute;','Ú') COLLATE Latin1_General_BIN,'&uacute;','ú') COLLATE Latin1_General_BIN,'&Ucirc;','Û') COLLATE Latin1_General_BIN,'&ucirc;','û') COLLATE Latin1_General_BIN,'&Uuml;','Ü') COLLATE Latin1_General_BIN,'&uuml;','ü'); 
     select @vcResult = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vcResult COLLATE Latin1_General_BIN,'&ETH;','Ð') COLLATE Latin1_General_BIN,'&eth;','ð') COLLATE Latin1_General_BIN,'&Ntilde;','Ñ') COLLATE Latin1_General_BIN,'&ntilde;','ñ') COLLATE Latin1_General_BIN,'&Yacute;','Ý') COLLATE Latin1_General_BIN,'&yacute;','ý') COLLATE Latin1_General_BIN,'&THORN;','Þ') COLLATE Latin1_General_BIN,'&thorn;','þ') COLLATE Latin1_General_BIN,'&szlig;','ß'); 
    end 
    RETURN @vcResult; 
END 
-- test: 
-- select dbo.fn_HTMLDecode(N'A fine example of man and nature co-existing is Slovenia&#8217;s ecological tourist farms.',1,1) 
-- select dbo.fn_HTMLDecode(N'm0 &#50752;&#51064;&#48516;&#50556;&#50640;&#49436; m1 &#44032;&#51109; m2 &#50689;&#54693;&#47141; m3&#51080;&#45716;m10',1,1) 
1

Tam jest o wiele prostsze rozwiązanie ...

SQL Server obsługuje typ danych XML i obsługuje dekodowanie encji zakodowanych w formacie XML/HTML. Jeśli po prostu rzucisz ciąg znaków na typ danych XML, możesz użyć wbudowanej funkcji dekodowania.

To będzie wyglądać następująco:

select cast('Q &amp; A' as XML).value('.[1]','nvarchar(max)'); 

Aby włączyć go do funkcji, łatwy w użyciu:

create function dbo.xmlDecode (@string nvarchar(max)) 
returns varchar(max) 
begin 
    return cast(@string as XML).value('.[1]','nvarchar(max)') 
end; 

pamiętać, że w przykładzie OP, łańcuch wydaje się być zakodowane 3 razy z rzędu. & został przekształcony w &amp;, a następnie w &amp;amp;, a następnie w &amp;amp;amp;. W rezultacie, aby odzyskać "oryginalny" ciąg, musisz użyć funkcji dekodowania 3 razy.

Powiązane problemy