SQL Server SQLCMD命名实例登录超时错误

3

当我尝试连接到一个命名实例时,在Linux上的sqlcmd出现错误。我在下面定义的Docker容器中运行所有这些内容。

FROM microsoft/mssql-server-linux:2017-latest
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y krb5-user
RUN apt-get install -y vim-common netcat

CMD ["/bin/bash"]

我接着配置了krb5.conf并运行kinit以使用我想要的账户。这些都很顺利。
我在这里阅读到: https://learn.microsoft.com/en-us/sql/ssms/scripting/sqlcmd-connect-to-the-database-engine?view=sql-server-2017 其中一个应该可以连接到命名实例:
/opt/mssql-tools/bin/sqlcmd -S 'np:\\server\pipe\MSSQLi1\sql\query' -E -C
/opt/mssql-tools/bin/sqlcmd -S 'np:\\server\pipe\MSSQL$i1\sql\query' -E -C
/opt/mssql-tools/bin/sqlcmd -S 'lpc:server\i1' -E -C
/opt/mssql-tools/bin/sqlcmd -S 'server\i1' -E -C

它们都不起作用。所有这些命令的错误都是相同的,即:

Sqlcmd: 错误: Microsoft ODBC Driver 17 for SQL Server : 登录超时。
Sqlcmd: 错误: Microsoft ODBC Driver 17 for SQL Server : MAX_PROVS: 无法打开到远程 SQL Server 实例的共享内存连接 [87]。
Sqlcmd: 错误: Microsoft ODBC Driver 17 for SQL Server : 在建立与 SQL Server 的连接时发生了与网络相关或特定于实例的错误。找不到服务器或无法访问。检查实例名称是否正确以及是否配置了 SQL Server 允许远程连接。有关更多信息,请参见 SQL Server Books Online。

sqlcmd 明显试图连接到错误的端口。

所以,我能够使用:

echo '020000' | xxd -r -p | nc -u server 1434

为了查询SQL Server的命名实例列表,就像我期望sqlcmd自己去做的那样。SQL Server愉快地回复了它的列表,并且在那个列表中我找到了我要找的实例,位于60655端口。
随后,我尝试了以下成功的命令:
/opt/mssql-tools/bin/sqlcmd -S 'server,60655\i1' -E -C

现在,我的问题是:如何让sqlcmd解析命名实例的端口并连接到它?只要我明确提供命名实例的端口,我就能正确连接。
更多信息更新:
我查看了SQL Server Browser的规格,并了解到我可以这样请求实例i1(6931是ascii码'i1'的十六进制):
echo '046931' | xxd -r -p | nc -w 1 -u server 1434

从Docker容器中,这将打印:

RServerName;SERVER;InstanceName;I1;IsClustered;No;Version;13.2.5026.0;tcp;60655;;

所以SQL Server浏览器完美运行。
然后我尝试在主机上运行这个。
nc -l -u 1434

而这是在 Docker 容器中的:

/opt/mssql-tools/bin/sqlcmd -S 'host\i2'

没有任何信息传递到netcat,这意味着sqlcmd甚至没有尝试与sql服务器浏览器通信。

1个回答

2

作为一种解决方法,我现在定义了一个bash函数,用于查询SQL服务器浏览器:

function resolve()
{
  SRV=$(echo $1 | tr '\\' '\n' | head -1)
  INS=$(echo $1 | tr '\\' '\n' | tail -1)
  PORT=`echo -n '04'$(echo -n $INS | xxd -ps -c 200) | xxd -r -p | nc -u $SRV 1434 -w 1 \
  | perl -nle 'm/tcp;(.*?);.*/; print $1'`
  echo ${SRV},${PORT}\\${INS} 
}

那么我可以这样连接:

SRV='Server\i1'
/opt/mssql-tools/bin/sqlcmd -S $(resolve $SRV)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接