首页 文章

Perl DBI连接不一致

提问于
浏览
3

背景

我正在开展一个项目,而不是从两个差异数据库中检索数据 . 其中一个数据库使用Microsoft SQL数据库引擎,另一个正在运行MySQL引擎 . 我需要一种从配置角度指定数据源名称(DSN)的简单方法,但由于DSN命名约定不一致, DBI 模块(根据我的经验)无法做到这一点 .

MySQL

请考虑以下连接:

my $dsn = "dbi:mysql:host=$host;database=$db_name";
my $dbh = DBI->connect($dsn, $user, $pass);

假设主机上存在提供的数据库名称,则此连接将成功 . 我已经多次测试过了 . 请随意自行验证 .


MS SQL

现在,我尝试使用相同的DSN连接字符串格式连接到Microsoft SQL服务器,但数据库驱动程序类型除外 .

my $dsn = "dbi:odbc:host=$host;database=$db_name";
my $dbh = DBI->connect($dsn, $user, $pass);

即使数据库存在于提供的主机上,此连接也会失败,并且错误消息如下所示:

DBI connect('host=$host;database=$db_name','$user',...) failed: (mtodbc): Fetching info: [unixODBC][Driver Manager]Connnection does not exist (SQLSTATE:08003) (CODE:0) (SEVERITY:SQLException) DBD: [dbd_db_login6/checkOutConnectionW(login)] RetCode=[-1] at perl_script.pl line X

DBI模块是 Perl 的数据库独立接口,但显然这个问题依赖于数据库..这似乎是一个糟糕的设计决策 . 我错过了什么吗?如果是这样,请提供一些理由说明为什么这种设计是以这种方式完成的 .

2 回答

  • 4

    在Windows中,您可以使用:

    DBI->connect('dbi:ODBC:driver={SQL Server};database=catalog;Server=server\\instance;',$user,$password);
    

    哪里:

    • server是mssql server的ip地址

    • instance是实例名称

    • catalog是数据库名称

    在linux / unix中我建议freetds

    来自DBI documentation

    Connect

    $dbh = DBI->connect($data_source, $username, $password)
              or die $DBI::errstr;
    $dbh = DBI->connect($data_source, $username, $password, \%attr)
              or die $DBI::errstr;
    

    $ data_source值的示例是:

    dbi:DriverName:database_name
    dbi:DriverName:database_name@hostname:port
    dbi:DriverName:database=database_name;host=hostname;port=port
    

    驱动程序名称后面的文本没有标准 . 每个驱动程序都可以自由使用它想要的任何语法 . DBI的唯一要求是所有信息都以单个字符串提供 . 您必须查阅所用驱动程序的文档,以获取所需语法的说明 . 建议驱动程序支持ODBC样式,如上面的上一个示例所示 . 还建议它们支持三个常用名称“host”,“port”和“database”(加上“db”作为数据库的别名) . 这简化了基本DSN的自动构建:“dbi:$ driver:database = $ db; host = $ host; port = $ port” . 当以这种形式给出DSN时,驱动程序应该以“做一些合理的事情”为目标,但如果任何部分对于该驱动程序没有意义(例如Informix的“端口”),如果该部分不为空,则应该生成错误 .

  • 1

    驾驶员所需的参数因驾驶员而异 . DBD :: ODBC文档中的示例是

    DBI->connect('dbi:ODBC:DSN=mydsn', $user, $pass)
    

    根据评论中发布的链接,似乎可以将上述内容缩短为

    DBI->connect('dbi:ODBC:mydsn', $user, $pass)
    

    没有关于其他参数被接受的可能性的信息(例如,指定文件DSN或内联DSN的方法) .

相关问题