복붙노트

[SQL] ISO 8859-1에 UTF8에서 SQL Server의 텍스트 값을 변환

SQL

ISO 8859-1에 UTF8에서 SQL Server의 텍스트 값을 변환

나는 UTF8 SQL_Latin1_General_CP1_CI_AS 데이터 인코딩 SQL Server에서 열 수 있습니다. 어떻게 변환하고 ISO 8859-1 인코딩의 텍스트를 저장할 수 있습니까? 나는 SQL 서버에 대한 쿼리에서 일을하고 싶습니다. 모든 팁?

해결법

  1. ==============================

    1.나는 VARCHAR 필드에 저장되어 수리 UTF-8 텍스트 함수를 작성했습니다.

    나는 VARCHAR 필드에 저장되어 수리 UTF-8 텍스트 함수를 작성했습니다.

    고정 된 값을 확인하려면 다음과 같이 사용할 수 있습니다 :

    CREATE TABLE #Table1 (Column1 varchar(max))
    
    INSERT #Table1
    VALUES ('Olá. Gostei do jogo. Quando "baixei" até achei que não iria curtir muito')
    
    SELECT *, NewColumn1 = dbo.DecodeUTF8String(Column1)
    FROM Table1
    WHERE Column1 <> dbo.DecodeUTF8String(Column1)
    

    산출:

    Column1
    -------------------------------
    Olá. Gostei do jogo. Quando "baixei" até achei que não iria curtir muito
    
    NewColumn1
    -------------------------------
    Olá. Gostei do jogo. Quando "baixei" até achei que não iria curtir muito
    

    코드:

    CREATE FUNCTION dbo.DecodeUTF8String (@value varchar(max))
    RETURNS nvarchar(max)
    AS
    BEGIN
        -- Transforms a UTF-8 encoded varchar string into Unicode
        -- By Anthony Faull 2014-07-31
        DECLARE @result nvarchar(max);
    
        -- If ASCII or null there's no work to do
        IF (@value IS NULL
            OR @value NOT LIKE '%[^ -~]%' COLLATE Latin1_General_BIN
        )
            RETURN @value;
    
        -- Generate all integers from 1 to the length of string
        WITH e0(n) AS (SELECT TOP(POWER(2,POWER(2,0))) NULL FROM (VALUES (NULL),(NULL)) e(n))
            , e1(n) AS (SELECT TOP(POWER(2,POWER(2,1))) NULL FROM e0 CROSS JOIN e0 e)
            , e2(n) AS (SELECT TOP(POWER(2,POWER(2,2))) NULL FROM e1 CROSS JOIN e1 e)
            , e3(n) AS (SELECT TOP(POWER(2,POWER(2,3))) NULL FROM e2 CROSS JOIN e2 e)
            , e4(n) AS (SELECT TOP(POWER(2,POWER(2,4))) NULL FROM e3 CROSS JOIN e3 e)
            , e5(n) AS (SELECT TOP(POWER(2.,POWER(2,5)-1)-1) NULL FROM e4 CROSS JOIN e4 e)
        , numbers(position) AS
        (
            SELECT TOP(DATALENGTH(@value)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
            FROM e5
        )
        -- UTF-8 Algorithm (http://en.wikipedia.org/wiki/UTF-8)
        -- For each octet, count the high-order one bits, and extract the data bits.
        , octets AS
        (
            SELECT position, highorderones, partialcodepoint
            FROM numbers a
            -- Split UTF8 string into rows of one octet each.
            CROSS APPLY (SELECT octet = ASCII(SUBSTRING(@value, position, 1))) b
            -- Count the number of leading one bits
            CROSS APPLY (SELECT highorderones = 8 - FLOOR(LOG( ~CONVERT(tinyint, octet) * 2 + 1)/LOG(2))) c
            CROSS APPLY (SELECT databits = 7 - highorderones) d
            CROSS APPLY (SELECT partialcodepoint = octet % POWER(2, databits)) e
        )
        -- Compute the Unicode codepoint for each sequence of 1 to 4 bytes
        , codepoints AS
        (
            SELECT position, codepoint
            FROM
            (
                -- Get the starting octect for each sequence (i.e. exclude the continuation bytes)
                SELECT position, highorderones, partialcodepoint
                FROM octets
                WHERE highorderones <> 1
            ) lead
            CROSS APPLY (SELECT sequencelength = CASE WHEN highorderones in (1,2,3,4) THEN highorderones ELSE 1 END) b
            CROSS APPLY (SELECT endposition = position + sequencelength - 1) c
            CROSS APPLY
            (
                -- Compute the codepoint of a single UTF-8 sequence
                SELECT codepoint = SUM(POWER(2, shiftleft) * partialcodepoint)
                FROM octets
                CROSS APPLY (SELECT shiftleft = 6 * (endposition - position)) b
                WHERE position BETWEEN lead.position AND endposition
            ) d
        )
        -- Concatenate the codepoints into a Unicode string
        SELECT @result = CONVERT(xml,
            (
                SELECT NCHAR(codepoint)
                FROM codepoints
                ORDER BY position
                FOR XML PATH('')
            )).value('.', 'nvarchar(max)');
    
        RETURN @result;
    END
    GO
    
  2. ==============================

    2.제이슨 페니는 나를 위해 간단한 예에 근무 유니 코드 (MIT 라이센스)에 UTF-8 변환하는 SQL 함수를 작성했습니다 :

    제이슨 페니는 나를 위해 간단한 예에 근무 유니 코드 (MIT 라이센스)에 UTF-8 변환하는 SQL 함수를 작성했습니다 :

    CREATE FUNCTION dbo.UTF8_TO_NVARCHAR(@in VarChar(MAX))
       RETURNS NVarChar(MAX)
    AS
    BEGIN
       DECLARE @out NVarChar(MAX), @i int, @c int, @c2 int, @c3 int, @nc int
    
       SELECT @i = 1, @out = ''
    
       WHILE (@i <= Len(@in))
       BEGIN
          SET @c = Ascii(SubString(@in, @i, 1))
    
          IF (@c < 128)
          BEGIN
             SET @nc = @c
             SET @i = @i + 1
          END
          ELSE IF (@c > 191 AND @c < 224)
          BEGIN
             SET @c2 = Ascii(SubString(@in, @i + 1, 1))
    
             SET @nc = (((@c & 31) * 64 /* << 6 */) | (@c2 & 63))
             SET @i = @i + 2
          END
          ELSE
          BEGIN
             SET @c2 = Ascii(SubString(@in, @i + 1, 1))
             SET @c3 = Ascii(SubString(@in, @i + 2, 1))
    
             SET @nc = (((@c & 15) * 4096 /* << 12 */) | ((@c2 & 63) * 64 /* << 6 */) | (@c3 & 63))
             SET @i = @i + 3
          END
    
          SET @out = @out + NChar(@nc)
       END
       RETURN @out
    END
    GO
    

    쳤다 더 나에게 안토니 "외모"로 대답하지만, 어쩌면 변환을하는 경우 모두 실행하고의 불일치 조사!

    또한 우리는 UCS-16로 변환 할 수 있습니다 UTF-8로 인 코드 된 후 NVARCHAR 필드에 VARCHAR로 변환 된 BMP 페이지 유니 코드 문자를 감지하는 아래의 매우 추한 코드를 사용했다.

    LIKE (N'%[' + CONVERT(NVARCHAR,(CHAR(192))) + CONVERT(NVARCHAR,(CHAR(193))) + CONVERT(NVARCHAR,(CHAR(194))) + CONVERT(NVARCHAR,(CHAR(195))) + CONVERT(NVARCHAR,(CHAR(196))) + CONVERT(NVARCHAR,(CHAR(197))) + CONVERT(NVARCHAR,(CHAR(198))) + CONVERT(NVARCHAR,(CHAR(199))) + CONVERT(NVARCHAR,(CHAR(200))) + CONVERT(NVARCHAR,(CHAR(201))) + CONVERT(NVARCHAR,(CHAR(202))) + CONVERT(NVARCHAR,(CHAR(203))) + CONVERT(NVARCHAR,(CHAR(204))) + CONVERT(NVARCHAR,(CHAR(205))) + CONVERT(NVARCHAR,(CHAR(206))) + CONVERT(NVARCHAR,(CHAR(207))) + CONVERT(NVARCHAR,(CHAR(208))) + CONVERT(NVARCHAR,(CHAR(209))) + CONVERT(NVARCHAR,(CHAR(210))) + CONVERT(NVARCHAR,(CHAR(211))) + CONVERT(NVARCHAR,(CHAR(212))) + CONVERT(NVARCHAR,(CHAR(213))) + CONVERT(NVARCHAR,(CHAR(214))) + CONVERT(NVARCHAR,(CHAR(215))) + CONVERT(NVARCHAR,(CHAR(216))) + CONVERT(NVARCHAR,(CHAR(217))) + CONVERT(NVARCHAR,(CHAR(218))) + CONVERT(NVARCHAR,(CHAR(219))) + CONVERT(NVARCHAR,(CHAR(220))) + CONVERT(NVARCHAR,(CHAR(221))) + CONVERT(NVARCHAR,(CHAR(222))) + CONVERT(NVARCHAR,(CHAR(223))) + CONVERT(NVARCHAR,(CHAR(224))) + CONVERT(NVARCHAR,(CHAR(225))) + CONVERT(NVARCHAR,(CHAR(226))) + CONVERT(NVARCHAR,(CHAR(227))) + CONVERT(NVARCHAR,(CHAR(228))) + CONVERT(NVARCHAR,(CHAR(229))) + CONVERT(NVARCHAR,(CHAR(230))) + CONVERT(NVARCHAR,(CHAR(231))) + CONVERT(NVARCHAR,(CHAR(232))) + CONVERT(NVARCHAR,(CHAR(233))) + CONVERT(NVARCHAR,(CHAR(234))) + CONVERT(NVARCHAR,(CHAR(235))) + CONVERT(NVARCHAR,(CHAR(236))) + CONVERT(NVARCHAR,(CHAR(237))) + CONVERT(NVARCHAR,(CHAR(238))) + CONVERT(NVARCHAR,(CHAR(239)))
        + N'][' + CONVERT(NVARCHAR,(CHAR(128))) + CONVERT(NVARCHAR,(CHAR(129))) + CONVERT(NVARCHAR,(CHAR(130))) + CONVERT(NVARCHAR,(CHAR(131))) + CONVERT(NVARCHAR,(CHAR(132))) + CONVERT(NVARCHAR,(CHAR(133))) + CONVERT(NVARCHAR,(CHAR(134))) + CONVERT(NVARCHAR,(CHAR(135))) + CONVERT(NVARCHAR,(CHAR(136))) + CONVERT(NVARCHAR,(CHAR(137))) + CONVERT(NVARCHAR,(CHAR(138))) + CONVERT(NVARCHAR,(CHAR(139))) + CONVERT(NVARCHAR,(CHAR(140))) + CONVERT(NVARCHAR,(CHAR(141))) + CONVERT(NVARCHAR,(CHAR(142))) + CONVERT(NVARCHAR,(CHAR(143))) + CONVERT(NVARCHAR,(CHAR(144))) + CONVERT(NVARCHAR,(CHAR(145))) + CONVERT(NVARCHAR,(CHAR(146))) + CONVERT(NVARCHAR,(CHAR(147))) + CONVERT(NVARCHAR,(CHAR(148))) + CONVERT(NVARCHAR,(CHAR(149))) + CONVERT(NVARCHAR,(CHAR(150))) + CONVERT(NVARCHAR,(CHAR(151))) + CONVERT(NVARCHAR,(CHAR(152))) + CONVERT(NVARCHAR,(CHAR(153))) + CONVERT(NVARCHAR,(CHAR(154))) + CONVERT(NVARCHAR,(CHAR(155))) + CONVERT(NVARCHAR,(CHAR(156))) + CONVERT(NVARCHAR,(CHAR(157))) + CONVERT(NVARCHAR,(CHAR(158))) + CONVERT(NVARCHAR,(CHAR(159))) + CONVERT(NVARCHAR,(CHAR(160))) + CONVERT(NVARCHAR,(CHAR(161))) + CONVERT(NVARCHAR,(CHAR(162))) + CONVERT(NVARCHAR,(CHAR(163))) + CONVERT(NVARCHAR,(CHAR(164))) + CONVERT(NVARCHAR,(CHAR(165))) + CONVERT(NVARCHAR,(CHAR(166))) + CONVERT(NVARCHAR,(CHAR(167))) + CONVERT(NVARCHAR,(CHAR(168))) + CONVERT(NVARCHAR,(CHAR(169))) + CONVERT(NVARCHAR,(CHAR(170))) + CONVERT(NVARCHAR,(CHAR(171))) + CONVERT(NVARCHAR,(CHAR(172))) + CONVERT(NVARCHAR,(CHAR(173))) + CONVERT(NVARCHAR,(CHAR(174))) + CONVERT(NVARCHAR,(CHAR(175))) + CONVERT(NVARCHAR,(CHAR(176))) + CONVERT(NVARCHAR,(CHAR(177))) + CONVERT(NVARCHAR,(CHAR(178))) + CONVERT(NVARCHAR,(CHAR(179))) + CONVERT(NVARCHAR,(CHAR(180))) + CONVERT(NVARCHAR,(CHAR(181))) + CONVERT(NVARCHAR,(CHAR(182))) + CONVERT(NVARCHAR,(CHAR(183))) + CONVERT(NVARCHAR,(CHAR(184))) + CONVERT(NVARCHAR,(CHAR(185))) + CONVERT(NVARCHAR,(CHAR(186))) + CONVERT(NVARCHAR,(CHAR(187))) + CONVERT(NVARCHAR,(CHAR(188))) + CONVERT(NVARCHAR,(CHAR(189))) + CONVERT(NVARCHAR,(CHAR(190))) + CONVERT(NVARCHAR,(CHAR(191)))
        + N']%') COLLATE Latin1_General_BIN
    

    위 :

  3. ==============================

    3.난 SQL 서버 2017 및 2019에서, 새로운 문자열 집계 함수의 string_agg를 사용하여 약간의 수정을 추가

    난 SQL 서버 2017 및 2019에서, 새로운 문자열 집계 함수의 string_agg를 사용하여 약간의 수정을 추가

    SELECT @result=STRING_AGG(NCHAR([codepoint]),'') WITHIN GROUP (ORDER BY position ASC) 
    FROM codepoints
    

    이 일에 드 @result 부분을 변경합니다. XML은 여전히 ​​구식 방법으로 작동합니다. 2019 년, string_agg는 XML 버전보다 더 빨리 극단적 인 작동 (분명 ... string_agg은 이제 기본이고, 공정한 비교되지 않음)

  4. ==============================

    4.나는 아직 내가해야 할 쿼리, 그냥 인코딩을 발견했다.

    나는 아직 내가해야 할 쿼리, 그냥 인코딩을 발견했다.

    ALTER TABLE dbo.MyTable ALTER COLUMN CharCol
            varchar(10)COLLATE Latin1_General_CI_AS NOT NULL;
    
  5. from https://stackoverflow.com/questions/28168055/convert-text-value-in-sql-server-from-utf8-to-iso-8859-1 by cc-by-sa and MIT license