2017-10-17 9 views
1

Excel에서 가져올 때 가끔 내 데이터에 표시되는 제거 할 수없는 이상한 공백 문자가 있습니다. 시각적으로는 공백 문자로 나타나지만 SQL Server에서는이를 물음표 (ASCII 63)로 간주합니다.SQL Server에서 이상한 Excel 문자를 제거하는 방법은 무엇입니까?

declare @temp nvarchar(255); set @temp = '[email protected]?am.com' 
select @temp 

반환 : 내가 진짜 물음표를 제거하기없이 공백을 제거 할 수 있습니까

[email protected]?am.com 

? 내가 각각의 ASCII 코드를 보면 "?" 캐릭터 실제로 63 개가 진짜 퀘스트 마크 일 때 63 점을 얻습니다.

+0

Ltrim (@ temp)을 수행하면 어떻게됩니까? – Harry

+2

참고 : 어떤 이유에서든 문자열을 그대로 유지하고 싶다면 set @ temp = N'mystring''을 사용합니다 (명시 적으로 문자열을 유니 코드로 선언하면 변수가 NVARCHAR '). 당신이 현재하고있는 것보다. – ZLK

+0

문자 세트가 일치하지 않습니다. – Namphibian

답변

2

비슷한 문제가있는 사람은 this answer입니다. 죄송합니다. 조금 길면 죄송합니다.

SQL Server는 알맞지 않은 문자 (적절한 대체 문자가 없음)를 물음표에 매핑하여 유니 코드를 ASCII로 병합 한 것으로 보입니다. 이를 복제하려면 문자표 Windows 프로그램 (대부분의 컴퓨터에 설치해야 함)을 열어 글꼴로 Arial을 선택하고 U + 034f "Grapheme 결합 자 결합"을 찾으십시오. 그것은 그것을 캐스트 때 비 ASCII 문자를 표시하는 방법을 알고하지 않기 때문에 당신은 물음표를 얻을 것이다

declare @t nvarchar(10) 
set @t = '͏' 
select rtrim(ltrim(@t)) -- we can try and trim it, but by this stage it's already a '?' 

:이 캐릭터를 선택, 클립 보드에 복사하고 아래의 작은 따옴표 사이를 붙여 넣습니다 varchar. 더블 바이트 문자 (nvarchar)로 받아들이도록하려면 이미 언급 한 것처럼 N''을 사용해야합니다. 확실히

declare @t nvarchar(10), 
     @s varchar(10) -- note: single-byte string 
set @t = rtrim(ltrim(N'͏')) -- trimming doesn't work here either 
set @s = @t 
select @s -- still outputs a question mark 

가져온 데이터를 수행 할 수 있습니다 - 위의 따옴표 전에 N을 추가하고 물음표가 사라집니다 (그리고 ltrim 아래 있듯이 rtrim는 제거되지 않지만 원래의 보이지 않는 문자 출력에 보존됩니다) 이것, 나는 전에 그것을 보았습니다. 그리고 위에 보여준 것과 같은 캐릭터는 특히 당신이 그들을 볼 수 없기 때문에 진단하기가 어렵습니다! 이러한 인쇄 할 수없는 문자 (및 그 밖의 다른 정크 문자)를 제거하려면 어떤 종류의 제거 프로세스를 만들어야하며 어디서나 nvarchar을 사용해야합니다. 그렇지 않으면이 문제가 발생합니다. 더욱이 유령 물음표는 합법적 인 물음표와 구별 할 수없는 실질적인 의문이됩니다.

이제
declare @t nvarchar(10) 
set @t = N'͏test?' 
select cast(@t as varbinary) -- returns 0x4F0374006500730074003F00 

-- Returns: 
-- 0x4F03 7400 6500 7300 7400 3F00 
-- badchar t e s t ? 

이 그것을 없애 : 나는를 교환했다

declare @t nvarchar(10) 
set @t = N'͏test?' 
select cast(@t as varbinary) -- bad char 
set @t = replace(@t COLLATE Latin1_General_100_BIN2, nchar(0x034f), N''); 
select cast(@t as varbinary) -- gone! 

참고를 다음과 같이

는 VARBINARY로 캐스트 할 수 있습니다, 당신은 무엇을 다루고 있는지 문자 코드를 확인하려면 0x4f03에서 0x034f까지의 바이트 순서입니다 (동일한 이유 "t"는 이 아니고 0x0074이 아닙니다). 왜 우리가 이진 데이터 정렬을 사용하는지에 대한 일부 참고 사항은 this answer을 참조하십시오.

더러운 문자가 무엇인지 알 수 없기 때문에 이것은 천박합니다. 그리고 수천 가지 가능성 중 하나 일 수 있습니다. 하나의 옵션은 like 또는 심지어 unicode()function을 사용하는 문자열에 반복을 사용하고 허용되는 문자 목록에없는 문자열에서 문자를 버리는 것이지만 느려질 수 있습니다.대부분의 나쁜 문자는 문자열의 시작 또는 끝 부분에있을 수 있습니다.이 문자열이 문자열을 처리 할 수 ​​있다고 생각되는 가정이라면이 과정을 빠르게 진행할 수 있습니다.

가져올 데이터가 많은 경우 SQL Server 외부 또는 위의 내용을 기반으로 SSIS 가져 오기의 일부로 추가 프로세스를 만들어야 할 수 있습니다. 이 작업을 수행하는 가장 좋은 방법이 확실하지 않은 경우 새 질문에서 가장 잘 응답 할 것입니다.

도움이 되었기를 바랍니다.

+0

위대한 설명! 문자 그대로 미쳐 가고있었습니다. 제 경우에는 문자는 "0x0B20"... 제로 - 폭 공간에 대한 유니 코드입니다. WTF는, 나는 모른다. – wgpubs