web-dev-qa-db-ja.com

bcpコマンド「�」付近の構文が正しくありません。キャラクターは実際には「ä」

mssql-serverおよびmssql-toolsがUbuntu(Linux)にインストールされています。次のコマンドラインを使用して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] [ODBC Driver 13 for SQL Server] [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] [ODBC Driver 13 for SQL Server] [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] [ODBC Driver 13 for SQL Server] [SQL Server]無効なオブジェクト名 'DBname.dbo.T�ble_Name'。

注:コマンドは、この特殊文字äなしでテーブル名と完全に連携します。

11
Houcine Nouri

これはシェルとbcp/SQL Server間のエンコーディングの問題だと思います。 SQL ServerはUTF-16リトルエンディアンを想定していますが、Linuxはそれを使用していません。 LinuxのデフォルトVMはen_GB.UTF-8を介したUTF-8です。

<TL; DR> "queryout" bcpコマンドを使用し、 "out"コマンドを使用してテーブル名を指定する代わりに"SELECT * FROM ..."を指定します。

以下は私のテストです...


私は使用可能なロケール/エンコーディングのリストを取得しました:

$ 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ありとなしの両方の角括弧はありませんでした。

ä$'\xe4\x00'を介して$'\xe4'$'\x00'のUTF-16 LE文字に相当するバイトを注入することも試みましたが、改善はありませんでした。

ただし、

whatdid作業によってbcpコマンドがoutからqueryoutに変更されました、次に、テーブル名をSELECTステートメントの一部になるように変更しました(ここでのみ-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] [ODBC Driver 13 for SQL Server]列レベルの照合順序を解決できません

これはbcpからのエラーであり、テストテーブルの唯一の列がtempdbデータ型を使用しているため、INTのメタデータを参照している必要があります。

現在、インスタンスレベルの照合順序はアクセント記号に敏感なので、アクセント記号のないaが機能することを期待していませんでした(ただし、「無効なオブジェクト」エラーが予期されていました)。そのため、アクセントの区別がないことをテストするために、Latin1_General_100_CI_AI_KS_WS_CSの照合を使用して新しいデータベースを作成し、同じデータベースを新しいDBに作成して、いくつかの行を追加しました。次に、次の2つのテストを実行しました。

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]のどの組み合わせも機能しませんでした。すべてのバリエーションで以前と同じエラーが発生しました。

7
Solomon Rutzky