简体   繁体   English

Perl DBI连接不一致

[英]Perl DBI Connection Inconsistencies

Background 背景

I am working on a project than involves the retrieval of data from two difference databases. 我正在开展一个项目,而不是从两个差异数据库中检索数据。 One of the databases is using a Microsoft SQL database engine and the other is running a MySQL engine. 其中一个数据库使用Microsoft SQL数据库引擎,另一个正在运行MySQL引擎。 I need an easy way to specify the Data Source Name (DSN) from a configuration perspective, but due to inconsistencies in the DSN naming conventions, this is not possible with the DBI module (from what I have experienced). 我需要一种从配置角度指定数据源名称(DSN)的简单方法,但由于DSN命名约定不一致, DBI模块(根据我的经验)无法做到这一点。

MySQL MySQL的

Consider the following connection: 请考虑以下连接:

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

Assuming the supplied database name exists at the host, this connection will be succesful. 假设主机上存在提供的数据库名称,则此连接将成功。 I have tested this many times. 我已经多次测试过了。 Feel free to verify this yourself. 请随意自行验证。


MS SQL MS SQL

Now I try to connect to a Microsoft SQL server using the same DSN connection string format, with the exception of the database driver type. 现在,我尝试使用相同的DSN连接字符串格式连接到Microsoft SQL服务器,但数据库驱动程序类型除外。

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

Even if the database exists on the supplied host, this connection fails, and the error message is like that shown below: 即使数据库存在于提供的主机上,此连接也会失败,并且错误消息如下所示:

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

The DBI module is a database independent interface for Perl , yet clearly this problem is database dependent.. This seems like a bad design decision. DBI模块是一个独立于数据库接口Perl ,但显然,这个问题取决于数据库。这似乎是一个不好的设计决策。 Am I missing something? 我错过了什么吗? If so, please provide some reasoning why this design was done in this way. 如果是这样,请提供一些理由说明为什么这种设计是以这种方式完成的。

In windows you can use: 在Windows中,您可以使用:

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

Where: 哪里:

  • server is the ip addres of mssql server server是mssql server的ip addres
  • instance is the instance name instance是实例名称
  • catalog is the database name catalog是数据库名称

In linux/unix I suggest freetds 在linux / unix中我建议freetds

From DBI documentation : DBI文档

Connect

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

Examples of $data_source values are: $ 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. DBI的唯一要求是所有信息都以单个字符串提供。 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. 建议驱动程序支持ODBC样式,如上面的上一个示例所示。 It is also recommended that they support the three common names 'host', 'port', and 'database' (plus 'db' as an alias for database). 还建议它们支持三个常用名称“host”,“port”和“database”(加上“db”作为数据库的别名)。 This simplifies automatic construction of basic DSNs: "dbi:$driver:database=$db;host=$host;port=$port" . 这简化了基本DSN的自动构建:“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. 驱动程序应该以这种形式给出DSN时“做一些合理的事情”,但如果任何部分对于该驱动程序没有意义(例如Informix的“端口”),如果该部分不为空,则应该生成错误。

The parameters required by drivers vary by driver. 驾驶员所需的参数因驾驶员而异。 The example in the DBD::ODBC documentation is DBD :: ODBC文档中的示例是

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

Based on links posted in the comment, it appears possible to shorten the above to 根据评论中发布的链接,似乎可以将上述内容缩短为

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

There's no information on the possibility of other parameters being accepted (eg a means of specifying a file DSN or of inlining a DSN). 没有关于其他参数被接受的可能性的信息(例如,指定文件DSN或内联DSN的方法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM