Mysql Perl DBI连接不一致 背景

Mysql Perl DBI连接不一致 背景,mysql,sql-server,database,perl,dsn,Mysql,Sql Server,Database,Perl,Dsn,我正在从事一个项目,涉及从两个不同的数据库检索数据。其中一个数据库使用Microsoft SQL数据库引擎,另一个运行MySQL引擎。我需要一种从配置角度指定数据源名称(DSN)的简单方法,但由于DSN命名约定不一致,这在DBI模块中是不可能的(根据我的经验) MySQL 考虑以下联系: my $dsn = "dbi:mysql:host=$host;database=$db_name"; my $dbh = DBI->connect($dsn, $user, $pas

我正在从事一个项目,涉及从两个不同的数据库检索数据。其中一个数据库使用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 server,但数据库驱动程序类型除外

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);
其中:

  • 服务器是mssql服务器的ip地址
  • instance是实例名
  • catalog是数据库名称
在linux/unix中,我建议

发件人:

$data\u源值的示例如下:

dbi:DriverName:database_name
dbi:DriverName:database_name@hostname:port
dbi:DriverName:database=database_name;host=hostname;port=port
驱动程序名称后面的文本没有标准。每个 驱动程序可以自由使用它想要的任何语法。唯一的要求 DBI的优点是所有信息都在一个单独的数据库中提供 一串您必须查阅您正在使用的驱动程序的文档 用于描述所需的语法

建议驱动程序支持ODBC样式,如中所示 上面的最后一个例子。还建议他们支持这三个方案 常用名称“主机”、“端口”和“数据库”(加上“db”作为 数据库)。这简化了基本DSN的自动构造: “dbi:$driver:database=$db;host=$host;port=$port”。司机应瞄准 在本表中给出DSN时“做一些合理的事情”,但如果有 部分对于驱动程序(比如Informix的“端口”)来说是没有意义的 如果该零件不为空,则应生成错误


mtodbc是什么驱动程序?你是舒尔的吗?这是正确的吗?当更换驱动程序时,保持相同的连接字符串并期望最好的结果很少奏效。有关DSN连接,请参阅:。@frhack我很抱歉。那是个打字错误。我当然是指ODBC驱动程序。在Linux中,我成功地使用了freetds连接权限。我明白这一点。。但是,这与独立于数据库的接口不一致。作为用户,我希望向DBI提供一个通用DSN,并让它将该DSN映射到后端数据库驱动程序所需的适当驱动程序参数。是吗?为什么希望为所有数据库提供相同的连接字符串?为什么您认为提供连接字符串会破坏可移植性?接口(DBI)用于执行查询和语句,而不是用于连接字符串/连接属性,这些属性必须保留在db中dependent@ikegami我不。我希望DSN连接字符串驱动程序类型会改变。作为用户,我希望能够传递一组参数,并让模块本身负责将这些参数转换为特定于驱动程序的连接字符串。例如,我传递
host=localhost
,对于MS SQL连接,它将转换为
SERVER=localhost
。因此,将特定于驱动程序的DSN字符串格式与用户分离。来源:驱动程序名称后面的文本没有标准。每个驱动程序都可以自由使用它想要的任何语法。DBI的唯一要求是所有信息都以单个字符串提供。您必须查阅所使用驱动程序的文档,以了解它们所需的语法说明。这是一个很好的信息。我在阅读之前的文档时没有看到这一点。然而,这留下了更多的讨论空间。不幸的是,由于DBD的子类没有强制执行特定的DSN字符串准则,这就为不同数据库引擎之间的接口差异留下了空间。这是一个糟糕的设计,依我看。@Jonathan DBI的驱动程序种类繁多,包括甚至不是RDBMS的驱动程序,比如DBD::CSV、DBD::DBM和DBD::WMI。与连接到典型RDBMS的方式不同,您无法“连接”到这些数据库,甚至RDBMS也会有所不同(有些使用连接标识符,有些需要数据库名称,有些甚至允许您指定单独的凭据文件)。这很难标准化。@ThisSuitesBlack我不理解为许多系统提供接口的困难。但是,从提供“独立于数据库的接口”的顶级模块来看,这些连接字符串不必绑定到底层数据库引擎的实现细节。不过我明白你的意思。@Jonathan这设计不错。不可能标准化所有数据库连接字符串。在JavaJDBC(相当于PerlDBI的java)中也存在同样的“问题”@frhack听起来不错。谢谢你提供的所有信息。我真的很感激。这是一次很好的讨论。
dbi:DriverName:database_name
dbi:DriverName:database_name@hostname:port
dbi:DriverName:database=database_name;host=hostname;port=port