bcp 命令 '?' 附近的语法不正确。字符实际上是:“ä”

Hou*_*uri 11 sql-server linux ubuntu bcp sql-server-2017

我 在 Ubuntu (Linux) 上安装了mssql-servermssql-tools。当我尝试使用以下命令行使用bcp命令导出数据时:

bcp DBname.dbo.Täble_Name out Täble_Name -c -k  -S127.0.0.1 -Usa -PpassWord -r ~
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

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 ~
Run Code Online (Sandbox Code Playgroud)

我在对象名称上收到此错误:

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
Run Code Online (Sandbox Code Playgroud)

错误变为:

SQLState = S0002,NativeError = 208
错误 = [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]无效的对象名称“DBname.dbo.T?ble_Name”。

注意:该命令适用于没有这个特殊字符 ä 的表名。

Sol*_*zky 7

我相信这是 shell 和bcp /SQL Server之间的编码问题。SQL Server 需要 UTF-16 Little Endian,但 Linux 不使用它。我的 Linux VM 的默认值是 UTF-8,通过en_GB.UTF-8.

<TL;DR>使用“queryout” bcp命令并指定"SELECT * FROM ..."而不是使用“out”命令并简单地提供表名。

下面是我的测试...


我使用以下方法获得了可用的语言环境/编码列表:

$ locale -a
Run Code Online (Sandbox Code Playgroud)

回来:

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
Run Code Online (Sandbox Code Playgroud)

我通过设置尝试了其中的几个选项:

$ export LC_CTYPE=C.UTF-8
Run Code Online (Sandbox Code Playgroud)

然后再次尝试使用:

$ export LC_ALL=C.UTF-8
Run Code Online (Sandbox Code Playgroud)

似乎没有什么不同。每次我尝试使用方括号的各种组合时,不带-q,然后带-q,然后没有带和不带的方括号-q

我什至尝试注入相当于ävia$'\xe4\x00'和 even的 UTF-16 LE 字符的字节$'\xe4'$'\x00',但没有改进。

然而,

什么的工作是改变BCP从命令out,而不是要queryout,然后更改表名是部分SELECT陈述(我删除了-r ~开关只有在这里,使命令行不滚动水平,但它是在我的测试)。我在其中创建了表[tempdb]并运行了以下命令:

bcp "SELECT * FROM tempdb.dbo.[Täble_Name]" queryout tab -c -k -S127.0.0.1 -Usa -Ppass
Run Code Online (Sandbox Code Playgroud)

没有问题。但有趣的是,我将重音ä改为非重音a

bcp "SELECT * FROM tempdb.dbo.[Table_Name]" queryout tab -c -k  -S127.0.0.1 -Usa -Ppass
Run Code Online (Sandbox Code Playgroud)

并收到以下错误:

SQLState = S1000,NativeError = 0
错误 = [Microsoft][ODBC Driver 13 for SQL Server]无法解析列级排序规则

这是来自bcp的错误,必须指的是元数据,tempdb因为我的测试表中唯一的列使用了该INT数据类型。

现在,我的实例级排序规则是重音敏感的,所以我并不真正期望非重音a能够工作(尽管我确实期望出现“无效对象”错误)。因此,为了测试重音不敏感,我创建了一个排序规则为 的新数据库,在新数据库中Latin1_General_100_CI_AI_KS_WS_CS创建相同的表,并添加了几行。然后我运行了以下两个测试:

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
Run Code Online (Sandbox Code Playgroud)

并且都有效!

让我们回到最初的BCP的只是指定的,而不是一个查询表名的命令,我是能够得到ImportTest.dbo.[Table_Name]ImportTest.dbo.Table_Name工作。但是,我仍然无法获得任何组合的ImportTest.dbo.[Täble_Name]工作;所有变体都出现了与以前相同的错误。