【问题标题】:tsql connects to ODBC but Perl DBI gets an errorsql 连接到 ODBC 但 Perl DBI 出错
【发布时间】:2015-09-28 03:37:58
【问题描述】:
  • 客户端是 Ubuntu 14.04.1 LTS 与 MS SQL Server 2005 通信。Ubuntu 没有注册域。它与 MS SQL Server 一样位于本地网络中。
  • Perl 5.18.2 使用 DBI 1.63 和 DBD::ODBC 1.52。
  • 已安装 FreeTDS 0.92(带有 TDS v4.2)和 unixODBC 2.2.14。
  • 命令行中的isql DSN USERNAME PASSWD 也不起作用。也许我应该从那开始。我仍然收到相同的错误,即Unable to connect to data source (SQL-08001).

我的相关配置文件:

2015-07-09 11:55:14 AM
NOTE: TDS version from tsql -C must go into freetds.conf and odbc.ini files

=========================================
/etc/odbcinst.ini:
[FreeTDS]
Description = FreeTDS 0.91 for Microsoft SQL Server 2005
#Driver = /usr/lib/odbc/libtdsodbc.so
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so
UsageCount = 1
#Threading = 2
fileusage = 1
dontdlclose = 1

=========================================
/etc/odbc.ini:
[ODBC Data Sources]
ResponseBDO = Response database desc in /etc/odbc/ini

[FreeTDS]
Description = FreeTDS 0.91 driver
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so

[responsebdo]
Driver = FreeTDS
Description = Response MSSQL 2005 ODBC driver
SERVER = sqlsvr.mydomain.com
PORT = 1433
USER = 'domain\domainuser'
Password = mypasswd
Database = r4w_004
# TDS_VERSION should be same as reported by 'tsql -C'.
TDS_Version = 4.2

[Default]
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Description = Default FreeTDS ODBC driver
SERVER = 10.20.30.40
USER = "domain\domainuser"
Database = r4w_4

=========================================
Relevant part of /etc/freetds/freetds.conf:
#   $Id: freetds.conf,v 1.12 2007/12/25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same 
# name is found in the installation directory.  
#
# For information about the layout of this file and its settings, 
# see the freetds.conf manpage "man freetds.conf".  
# 
[responsetds]
    #host = 10.20.30.40
    host = sqlsvr.mydomain.com
    port = 1433
    tds version = 4.2
    connect timeout = 20
    timeout = 20
    dump file = /tmp/freetds-resp.log
    instance = MSSQLSERVER  
    use ntlmv2 = yes


=========================================
tsql -C:
Compile-time settings (established with the "configure" script)
                            Version: freetds v0.91
             freetds.conf directory: /etc/freetds
     MS db-lib source compatibility: no
        Sybase binary compatibility: yes
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 4.2
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: yes

=========================================
odbcinst --version:
unixODBC 2.2.14


Perl 连接信息:
$respdsn="dbi:ODBC:Driver={SQL Native Client};Server=10.20.30.40;".
"UID=$respdbuser;PWD=$respdbpw;Database=r4w_004";
$respdbh=DBI->connect($respdsn);

我可以在命令行使用 tsql 连接到数据库。 但是使用 Perl 我得到这个错误:

DBI connect('Driver={SQL Native Client};Server=10.19.1.3;UID=gilson\mwreports;PWD=MR4gilson;Database=r4w_004','',...) failed:
[unixODBC][Driver Manager]Data source name not found, and no default 
driver specified (SQL-IM002) at /home/chuck/perl/gilson/jimv/fedex/fedex.pl line 1557.
 at /usr/lib/perl5/DBI.pm line 691.
        DBI::__ANON__[/usr/lib/perl5/DBI.pm:744](undef, undef) called at /usr/lib/perl5/DBI.pm line 747


我的问题:
  • Perl 连接字符串中的“{SQL Native Client}”是否正确?它是指 odbc.ini 或 freetds.conf 文件中的条目吗?
  • 我在这里缺少什么?

谢谢。

【问题讨论】:

  • 您的连接字符串中似乎缺少服务器端口或实例。您只需指定 SQL Server 本身。其他连接是否在您的机器上工作?顺便说一句,如果您使用 Linux 尝试禁用 SELinux,我通常会有 SELinux + Freetds 根本无法正常工作的经验。 :-D
  • 要在DSN字符串中指定实例和端口,我是否使用这种格式? "Server=10.20.30.40\\instance;port=1433"。注意使用双引号和转义的反斜杠,因为我在 DSN 字符串中使用了其他变量。来源:connectionstrings.com/sql-native-client-9-0-odbc-driver
  • 这是我的 dsn $respdsn="dbi:ODBC:Driver={SQL Native Client};Server=10.20.30.40\\MSSQLSERVER;". "UID=$respdbuser;PWD=$respdbpw;Database=r4w_004;Port=1433";,我遇到了同样的错误。它试图从哪里获取数据源名称?
  • 尝试:$respdsn="dbi:ODBC:Driver={SQL Native Client};Server=10.20.30.40,1443;". "UID=$respdbuser;PWD=$respdbpw;Database=r4w_004"; 另外尝试禁用 SELinux。
  • 什么是 SELinux,如何禁用它?

标签: sql-server perl odbc dbi freetds


【解决方案1】:

我遇到了同样的问题,当我使用 tsql 正常工作但使用 perl 和 dbi 时却没有。我花了很多时间试图找出问题所在,所以我看到了 Adaptive Server 的局限性:

  • 名称长度不能超过 30 个字符
  • 第一个字符必须是字母(ASCII a 到 z、A 到 Z)。
  • 后面的字符必须是字母、数字或下划线 (_)。

...所以我尝试将 32 个字符长的密码更改为 30 个字符,它可以工作。

tsql 接受长密码,但 perl dbi sybase 只接受 30 个字符。

在端口 1433 上连接到默认实例的命令:

perl -e 'use DBI;DBI->connect("dbi:Sybase:server=10.0.0.1","sa","max_30_characters_longpassword");'

连接命名实例的命令(使用端口 udp 1434 发现端口):

perl -e 'use DBI;DBI->connect("dbi:Sybase:server=10.0.0.1\\SQL2014","sa","max_30_characters_longpassword");'

当您知道 sqlserver 正在侦听的端口时连接到命名实例的命令:

perl -e 'use DBI;DBI->connect("dbi:Sybase:server=10.0.0.1:60036","sa","max_30characters_long_password");'

我使用 tcpdump 监控到 sqlserver 的连接:

tcpdump -qn dst host 10.0.0.1 &

也许它可以帮助某人。谢谢

【讨论】:

    【解决方案2】:

    如果您使用的是 FreeTDS,那么您的驱动程序是 FreeTDS 而不是“Sql Native Client”。

    试试这一行来获取你的数据库句柄:

    my $dbh = DBI->connect("dbi:ODBC:Driver=FreeTDS;Server=10.20.30.40;database=r4w_004", $respdbuser, $respdbpw);
    

    【讨论】:

    • 驱动名称'FreeTDS'是否设置在/etc/odbcinst.ini中,还是系统查找的固定字符串?
    • 在 odbcinst.ini 中设置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    • 2011-05-12
    • 2023-03-24
    • 1970-01-01
    • 2014-12-24
    • 2017-01-20
    • 2011-06-19
    相关资源
    最近更新 更多