linux 上的 BCP 实用程序:NativeError = 18456 错误 = [unixODBC][Microsoft][SQL 服务器的 ODBC 驱动程序 17][SQL 服务器] 用户登录失败

BCP utility on linux: NativeError = 18456 Error = [unixODBC][Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Login failed for user

按照 BCP 示例(通过 https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-tools?view=sql-server-2017#a-idrhelainstall-tools-on-rhel-7 with the msodbcsql driver from https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017) for importing flatfile from linux to a MSSQL Server (https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-migrate-bcp?view=sql-server-2017#import-data-from-the-source-data-file 安装在 CentOS7 上),尝试使用 运行 基本命令将平面文件从本地计算机 (CentOS7) 写入远程 (Windows 服务器 2012) 主机数据库。 此处用于测试的脚本如下所示:

[me@mapr001 examples]$ cat simple-bcp-tsv2mssql.sh
#!/bin/bash

TO_SERVER_ODBCDS="-D -S 'ODBC Driver 17 for SQL Server'"
TO_SERVER_IP="-S 172.17.9.29"
DB="DB_ML"
TABLE="bcp_test"
USER=""
PASSWORD=""
DATAFILE="./data/simple-rows.headless.tsv"

read -r -p "Enter username: " USER
read -r -s -p "Enter user password: " PASSWORD

echo -e "\nConnecting with BCP utility as $USER..."

/opt/mssql-tools/bin/bcp "$TABLE" in "$DATAFILE" \
        "$TO_SERVER_DNS" \
        -U "$USER" \
        -P "$PASSWORD" \
        -d "$DB" \
        -c \
        -t "'\t'"

并且正在抛出(看似误导的)错误

[me@mapr001 examples]$ ./simple-bcp-tsv2mssql.sh
Enter username: me
Enter user password:
Connecting with BCP utility as me...
/opt/mssql-tools/bin/bcp:  unknown option
usage: /opt/mssql-tools/bin/bcp {dbtable | query} {in | out | queryout | format} datafile
  [-m maxerrors]            [-f formatfile]          [-e errfile]
  ...

尽管我在脚本中似乎遵循了这种使用格式。通过命令行 运行ning 时的结果是我认为我 应该真正关注的结果 :

[me@mapr001 examples]$ bcp bcp_test in ./data/simple-rows.headless.tsv -D -S MyMSSQLServer -U me -P mypassword -d DB_ML -c -t '\t'

SQLState = 28000, NativeError = 18456
Error = [unixODBC][Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Login failed for user 'me'.

这台机器上的/etc/odbc/odbc个文件看起来像

# Referencing some of the ODBC setup steps here: https://github.com/mkleehammer/pyodbc/wiki/Connecting-to-SQL-Server-from-RHEL-6-or-Centos-7
# Prepare a temp file for defining the DSN to your database server
vi /home/user/odbcadd.txt

[MyMSSQLServer]
Driver      = ODBC Driver 17 for SQL Server
Description = My MS SQL Server
Trace       = No
Server      = 172.17.9.29

# register the SQL Server database DSN information in /etc/odbc.ini
sudo odbcinst -i -s -f /home/me/odbcadd.txt -l

[me@mapr001 examples]$ cat /etc/odbc.ini
[MyMSSQLServer]
Driver=ODBC Driver 17 for SQL Server    ------------
Description=My MS SQL Server                       |
Trace=No                                           |
Server=172.17.9.29                                 |
                                                   |
[MyMSSQLServer_ML]                                 |
Driver=ODBC Driver 17 for SQL Server               |
Description=My SQL Server (ML DB)                  |
Tracec=No                                          |
Server=172.17.9.29                                 |
Database=DB_ML                                     |
                                                   |
                                                   |
[me@mapr001 examples]$ cat /etc/odbcinst.ini       |
[PostgreSQL]                                       |
Description=ODBC for PostgreSQL                    |
Driver=/usr/lib/psqlodbcw.so                       |
Setup=/usr/lib/libodbcpsqlS.so                     |
Driver64=/usr/lib64/psqlodbcw.so                   |
Setup64=/usr/lib64/libodbcpsqlS.so                 |
FileUsage=1                                        |
                                                   |
[MySQL]                                            |
Description=ODBC for MySQL                         |
Driver=/usr/lib/libmyodbc5.so                      |
Setup=/usr/lib/libodbcmyS.so                       |
Driver64=/usr/lib64/libmyodbc5.so                  |
Setup64=/usr/lib64/libodbcmyS.so                   |
FileUsage=1                                        |
                                                   |
[ODBC Driver 17 for SQL Server]    <---------------- 
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.2.so.0.1
UsageCount=1


[me@mapr001 ~]# odbcinst -q -d -n "ODBC Driver 17 for SQL Server"
[ODBC Driver 17 for SQL Server]
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.2.so.0.1
UsageCount=1


[me@mapr001 ~]# odbcinst -j
unixODBC 2.3.1
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /etc/odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

问题似乎与我如何设置 ODBC 驱动程序和配置或我的凭据有关(这是 Active Directory 我用来登录远程 Windows 主机的凭据SQL 服务器,我正在尝试连接到这里),但是我对设置这种东西的经验为零,此时我有点不知所措(将继续研究和调试) .任何关于如何进一步调试或修复问题的建议都将不胜感激。

问题似乎是 bcp 实用程序需要 SQL 服务器的凭据(请参阅 https://docs.microsoft.com/en-us/sql/tools/bcp-utility?view=sql-server-2017#U and https://docs.microsoft.com/en-us/sql/tools/bcp-utility?view=sql-server-2017#T), 而不是主机的凭据SQL 服务器在 上 运行。

在我原来的 post 中,使用的是域 Active Directory 信用。我通常会用它来登录机器(这又是错误的(这里进一步支持:https://www.sqlservercentral.com/Forums/FindPost1565871.aspx))。在命令中使用一组单独的 SQL 服务器凭据解决了我的问题。 (仍然不明白为什么脚本会抛出 "unknown option" 错误,所以如果有人有猜测,请发表评论)。


更新:经过一些 "binarysearch debugging" (https://www.codelord.net/2012/04/10/using-binary-search-for-debugging/), found that the problem was that the field_term option (https://docs.microsoft.com/en-us/sql/tools/bcp-utility?view=sql-server-2017#t) 的格式化导致了一些问题。原本在脚本中写的代码为-t "'\t'"。将其更改为 -t "\t"(无内部单引号)可解决问题。请注意,这很难立即捕捉到,因为当 echo 打印到 控制台的命令的两个版本完全相同时 .