bcp 명령 ‘ ‘근처의 구문이 잘못되었습니다. 캐릭터는 실제로 : “ä” 잘못되었습니다. 는 �것입니다 ä. Täble_Name대괄호로 둘러싼 경우

나는이 MSSQL 서버MSSQL – 도구 우분투 (리눅스)에 설치합니다. 다음 명령 줄을 사용하여 bcp 명령으로 데이터를 내보내려고 할 때 :

bcp DBname.dbo.Täble_Name out Täble_Name -c -k  -S127.0.0.1 -Usa -PpassWord -r ~

이 오류가 발생합니다.

SQLState = 37000, NativeError = 102
오류 = [Microsoft] [SQL Server 용 ODBC 드라이버 13] [SQL Server] ‘ ‘근처의 구문이 잘못되었습니다.

것입니다 ä.

Täble_Name대괄호로 둘러싼 경우 :

 bcp DBname.dbo.[Täble_Name] out Täble_Name -c -k  -S127.0.0.1 -Usa -PpassWord -r ~

객체 이름 에이 오류가 발생합니다.

SQLState = S0002, NativeError = 208
오류 = [Microsoft] [SQL Server 용 ODBC 드라이버 13] [SQL Server] 잘못된 개체 이름 ‘DBname.dbo.Täble_Name’.

더 나아가 옵션 ''과 함께 작은 따옴표 를 추가했습니다 -q(따옴표 붙은 식별자 사용 가능).

bcp 'DBname.dbo.[Täble_Name]' out Täble_Name -c -k  -S127.0.0.1 -Usa -PpassWord -r ~ -q

오류는 다음과 같습니다.

SQLState = S0002, NativeError = 208
오류 = [Microsoft] [SQL Server 용 ODBC 드라이버 13] [SQL Server] 잘못된 개체 이름 ‘DBname.dbo.T.ble_Name’.

NB : 명령은이 특수 문자 ä없이 테이블 이름과 완벽하게 작동합니다.



답변

나는 이것이 쉘과 bcp / SQL Server 사이의 인코딩 문제라고 생각합니다 . SQL Server는 UTF-16 Little Endian을 기대하지만 Linux에서는 사용하지 않습니다. 내 Linux VM의 기본값은 UTF-8 via en_GB.UTF-8입니다.

<TL; DR> “queryout” bcp 명령 "SELECT * FROM ..."을 사용하고 “out”명령 대신 테이블 이름을 제공하는 대신 지정 하십시오.

다음은 내 테스트입니다 …


다음을 사용하여 사용 가능한 로캘 / 인코딩 목록을 얻었습니다.

$ locale -a

반환 :

C
C.UTF-8
en_AG
en_AG.utf8
en_AU.utf8
en_BW.utf8
en_CA.utf8
en_DK.utf8
en_GB.utf8
en_HK.utf8
en_IE.utf8
en_IN
en_IN.utf8
en_NG
en_NG.utf8
en_NZ.utf8
en_PH.utf8
en_SG.utf8
en_US.utf8
en_ZA.utf8
en_ZM
en_ZM.utf8
en_ZW.utf8
POSIX

설정을 통해 이러한 옵션 중 몇 가지를 시도했습니다.

$ export LC_CTYPE=C.UTF-8

그런 다음 다음을 사용하여 다시 시도하십시오.

$ export LC_ALL=C.UTF-8

차이가있는 것 같지 않았습니다. 그리고 때마다 나는없이 대괄호의 다양한 조합을 시도 -q하고 다음으로 -q다음 더 대괄호 모두와없이 -q.

ävia $'\xe4\x00'및 even 의 UTF-16 LE 문자와 같은 바이트를 주입하려고 시도 $'\xe4'$'\x00'했지만 개선되지 않았습니다.

하나,

어떤 작업이 변경되었다 BCP의 에서 명령을 out수 대신에 queryout, 다음 테이블 이름은의 일부가 변경 SELECT문 (I는 제거 -r ~되지 스크롤 수평으로 명령 줄을 만 여기에 스위치를하지만, 내 테스트에 있었다). 테이블을 [tempdb]만들고 다음을 실행했습니다.

bcp "SELECT * FROM tempdb.dbo.[Täble_Name]" queryout tab -c -k -S127.0.0.1 -Usa -Ppass

문제 없습니다. 그러나 흥미롭게도 액센트 ä를 액센트 가 아닌 것으로 변경했습니다 a.

bcp "SELECT * FROM tempdb.dbo.[Table_Name]" queryout tab -c -k  -S127.0.0.1 -Usa -Ppass

다음과 같은 오류가 발생했습니다.

SQLState = S1000, NativeError = 0
오류 = [Microsoft] [SQL Server 용 ODBC 드라이버 13] 열 수준 데이터 정렬을 확인할 수 없습니다.

그것은 bcp 의 오류 이며 tempdb테스트 테이블의 유일한 열이 INT데이터 유형을 사용하기 때문에 메타 데이터를 참조해야합니다 .

이제 인스턴스 수준 데이터 정렬이 악센트를 구분하므로 악센트가없는 사람이 실제로 a작동 하지 않을 것으로 예상하지 못했습니다 ( “잘못된 개체”오류가 예상되었지만). 따라서 악센트 무감도를 테스트하기 위해 Collation이있는 새 데이터베이스를 Latin1_General_100_CI_AI_KS_WS_CS만들고 새 DB에 동일한 테이블을 만든 다음 몇 개의 행을 추가했습니다. 그런 다음 다음 두 가지 테스트를 실행했습니다.

bcp "SELECT * FROM ImportTest.dbo.[Täble_Name]" queryout tab -c -k  -S127.0.0.1 -Usa -Ppass

bcp "SELECT * FROM ImportTest.dbo.[Table_Name]" queryout tab -c -k  -S127.0.0.1 -Usa -Ppass

그리고 둘 다 일했다!

초기에 돌아가서 BCP의 단지 대신 쿼리의 테이블 이름을 지정하는 명령을, 내가 얻을 수있었습니다 ImportTest.dbo.[Table_Name]ImportTest.dbo.Table_Name작업에. 그러나 나는 여전히 어떤 조합도 ImportTest.dbo.[Täble_Name]일할 수 없었다 . 모든 유사 콘텐츠는 이전과 동일한 오류가 발생했습니다.


답변