문자 (0x0000)를 포함하므로 FOR XML에서 데이터를 직렬화 할 수 없습니다.


18

큰 쿼리가 있고 (필요한 경우 여기에 게시 할)이 오류가 발생합니다.

메시지 6841, 수준 16, 상태 1, 줄 1
FOR XML에 'NoName'노드에 대한 데이터를 직렬화 할 수 없습니다. XML에 허용되지 않는 문자 (0x0000)가 포함되어 있기 때문입니다. FOR XML을 사용하여이 데이터를 검색하려면 이진, varbinary 또는 이미지 데이터 유형으로 변환하고 BINARY BASE64 지시문을 사용하십시오.

내가 사용하는 유일한 부분 FOR XML은 다음과 같습니다.

WHERE 
    (CodFuncionario = Results.CodFuncionario) 
FOR XML PATH(''), TYPE).value('(./text())[1]', 
    'VARCHAR(MAX)'), 1, 2, '') AS [Experiencia]

그러나 무엇 node noname입니까? 이 값을 어떻게 찾을 수 있습니까?(0x0000)

이것은 하위 쿼리 중 하나입니다 (내가 FOR XML을 가지고있는 유일한 부분) :

SELECT 
    [CodFuncionario],
    STUFF
    (
        (
            SELECT 
                ' / ' + 
            CAST
            (
                [DescFuncao] + '-' + 
                [DescTempoExperiencia] 
                AS VARCHAR(MAX)
            )...
FROM 
    [Linked_Server].db.dbo.tblFuncionarioExperiencia T0
INNER JOIN
    [Linked_Server].db.dbo.tblFuncao T1 On T0.codFuncao = T1.CodFuncao
INNER JOIN
    [Linked_Server].db.dbo.tblTempoExperiencia T2 ON T0.CodTempoExperiencia = T2.CodTempoExperiencia 
WHERE 
   (CodFuncionario = Results.CodFuncionario) 
   FOR XML PATH(''), TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '') AS [Experiencia]
  FROM 
      [Linked_Server].db.dbo.tblFuncionarioExperiencia Results  
  GROUP BY 
      CodFuncionario) as T2

  On T0.CodFuncionario = T2.CodFuncionario

Left Join...

답변:


10

라인 :

...
SELECT 
    [CodFuncionario],
    STUFF
    (
        (
            SELECT 
                ' / ' + 
                CAST
                (
                    [DescFuncao] + '-' + 
                    [DescTempoExperiencia] 
                    AS VARCHAR(MAX)
                )...

해야한다:

...
SELECT 
    [CodFuncionario],
    STUFF
    (
        (
            SELECT 
                ' / ' + 
                CAST
                (
                    replace -- *** NEW! ***
                    (
                        [DescFuncao] + '-' + 
                        [DescTempoExperiencia],
                        char(0),
                        ''
                    ) 
                    AS VARCHAR(MAX)
                )...

11

이 작업을 수행하면 동일한 오류가 발생합니다.

DECLARE @foo VARCHAR(32) = CHAR(0); -- 0x0000
SELECT @foo FOR XML PATH, TYPE;

따라서 내용이 포함 된 위치 DescFuncao또는의 모든 인스턴스 DescTempoExperiencia(죄송합니다. 테이블 별칭을 사용하지 않으므로 테이블의 출처를 알 수 없습니다)를 찾아 CHAR(0)수정하십시오. 예를 들면 다음과 같습니다.

UPDATE dbo.whatever 
  SET DescFuncao = REPLACE(DescFuncao, CHAR(0), '')
  WHERE DescFuncao LIKE '%' + CHAR(0) + '%';

XML 메소드가 어느 시점에서 작동하는지 알지 못하지만 다음을 시도 할 수도 있기 때문에 쿼리에서 해당 행을 필터링하는 것만으로는 충분하지 않습니다.

STUFF(( SELECT ' / ' + CAST(REPLACE([DescFuncao] + '-' 
  + [DescTempoExperiencia], CHAR(0), '') AS VARCHAR(MAX))

물론 소스 데이터를 한 번 수정하면 매번 이러한 대체 루틴을 실행하는 것보다 훨씬 효율적 입니다.

이 문제를 일으키는 유일한 특정 문자는 아닙니다. 0x0001-> 0x0008도 같은 오류가 발생합니다. 따라서 해당 문자가있는 경우 해당 문자의 출처를 조사하고 소스를 수정해야합니다.


1
이모티콘이 많은 데이터는 어떻습니까?
devinbost

10

ASCII 문자 0-255로 이것을 테스트했으며 문자에 대해이 오류가 발생한다는 것을 알았습니다. 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x000B, 0x000C, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F .

한 가지 해결 방법은 제거하는 것입니다 , TYPE XML 문에서 하는 것입니다.

다른 방법은 select 문에서 해당 문자를 제거하는 것입니다.

REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( 
REPLACE( REPLACE( REPLACE( REPLACE( 
    < YOUR EXPRESSION TO BE CLEANED >
,char(0x0000),'') ,char(0x0001),'') ,char(0x0002),'') ,char(0x0003),'') ,char(0x0004),'') 
,char(0x0005),'') ,char(0x0006),'') ,char(0x0007),'') ,char(0x0008),'') ,char(0x000B),'') 
,char(0x000C),'') ,char(0x000E),'') ,char(0x000F),'') ,char(0x0010),'') ,char(0x0011),'') 
,char(0x0012),'') ,char(0x0013),'') ,char(0x0014),'') ,char(0x0015),'') ,char(0x0016),'') 
,char(0x0017),'') ,char(0x0018),'') ,char(0x0019),'') ,char(0x001A),'') ,char(0x001B),'') 
,char(0x001C),'') ,char(0x001D),'') ,char(0x001E),'') ,char(0x001F),'')

이러한 replace 문으로 함수를 만들 수도 있습니다.


이 해결 방법 아이디어는 큰 복잡한 공통 테이블 식에서 xml 블록에 대해이 오류로 실패한 위치를 찾는 데 도움이되었습니다.
키이스 존 허치슨

2
이 스크립트는 유용하지만 (아주 느리지 만) 이모티콘 문자 (예 : 0xD83D)에서는 작동하지 않으며 적어도 내 데이터에는 많은 문자가있을 것으로 생각됩니다. : '(또는 내가 말해야 할 것 : 0x1F62D
devinbost

1

translate ()를 사용하여 @jumxozizi의 답변을 최적화합니다 (SQL Server 2017 ++). 아래 코드는 해당 문자를 마침표로 바꿉니다.

declare
    @illegalChars nvarchar(4000) = 
        char(0) + char(1) + char(2) + char(3) + char(4) + char(5) + char(6) + char(7) + char(8) + char(11) + 
        char(12) + char(14) + char(15) + char(16) + char(17) + char(18) + char(19) + char(20) + char(21) + char(22) + 
        char(23) + char(24) + char(25) + char(26) + char(27) + char(28) + char(29) + char(30) + char(31);

select translate(input, @illegalChars, replicate('.', len(@illegalChars))) as Result

대신 스트립을 제거하려면 먼저 그들을 char (0)으로 번역 한 다음 replace ()로 래핑하십시오.

아이디어에서 : /programming//a/55906638/538763

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.