Perl DBI 连接不一致

Perl DBI Connection Inconsistencies

背景

我正在做一个项目,涉及从两个不同的数据库中检索数据。其中一个数据库使用的是 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 的数据库独立接口,但显然这个问题 数据库相关的。这似乎是一个糟糕的设计决定。我错过了什么吗?如果是这样,请说明为什么以这种方式完成此设计。

驱动需要的参数因驱动而异。 DBD::ODBC 文档中的示例是

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

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

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

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

在windows中你可以使用:

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

其中:

  • server是mssql服务器的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

There is no standard for the text following the driver name. Each driver is free to use whatever syntax it wants. The only requirement the DBI makes is that all the information is supplied in a single string. You must consult the documentation for the drivers you are using for a description of the syntax they require.

It is recommended that drivers support the ODBC style, shown in the last example above. It is also recommended that they support the three common names 'host', 'port', and 'database' (plus 'db' as an alias for database). This simplifies automatic construction of basic DSNs: "dbi:$driver:database=$db;host=$host;port=$port". Drivers should aim to 'do something reasonable' when given a DSN in this form, but if any part is meaningless for that driver (such as 'port' for Informix) it should generate an error if that part is not empty.