perl脚本同时连接两个数据库

ash*_*shu 4 mysql database perl

我试图从1个Perl脚本连接到同一个MySQL实例上的2个数据库.

我在迁移脚本中使用它,我从原始数据库中获取数据并将其插入到新数据库中.

连接到1个数据库,然后尝试启动与同一用户的第二个连接,只需将当前数据库更改为新数据库.

#!/usr/bin/perl

use DBI;
use strict;

my $driver = "mysql";
my $database1 = "db1";
my $dsn1 = "DBI:$driver:database=$database1";
my $userid = "userhead";
my $password = "pwdhead";
my $database2 = "db2";
my $dsn2 = "DBI:$driver:database=$database2";

my $dbh1 = DBI->connect($dsn1, $userid, $password ) or die $DBI::errstr;
my $dbh2 = DBI->connect($dsn2, $userid, $password ) or die $DBI::errstr;

my $sth = $dbh2->prepare("INSERT INTO Persons") $dbh1->prepare("SELECT *FROM Persons");
$sth->execute() or die $DBI::errstr;
print "Number of rows found :" + $sth->rows;
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我试图从一个数据库表复制到另一个数据库表.但我在运行脚本时遇到错误.请帮帮我

Bor*_*din 8

猜测,您尝试使用相同的数据库句柄连接到两个数据库.如果您需要操作两个单独的连接,则需要两个单独的手柄

该程序使用data_sources类方法来发现所有可用的MySQL数据库,并创建与每个数据库的连接,将句柄放在数组中@dbh.例如,您可以正常使用该数组的每个元素

my $stmt = $dbh[0]->prepare('SELECT * FROM table)
Run Code Online (Sandbox Code Playgroud)

您可能希望@databases手动设置阵列,或者两个数据源的用户名和密码可能不同,因此可能需要对此进行一些修改

use strict;
use warnings 'all';

use DBI;

my $user = 'username';
my $pass = 'password';

my @databases = DBI->data_sources('mysql');

my @dbh = map { DBI->connect($_, $user, $pass) } @databases;
Run Code Online (Sandbox Code Playgroud)



更新

您需要从源表中选择数据,一次获取一行,然后每一行插入目标表

这里有一个想法如何可能的工作,但你需要调整的问号数量VALUES的的INSERT声明相匹配的列数

请注意,如果您只是想复制整个数据集,那么有更好的方法可以解决这个问题.特别是,如果您有任何外键约束,那么在它所依赖的表填充之前,您将无法添加数据

#!/usr/bin/perl

use strict;
use warnings 'all';

use DBI;

my $userid   = "userhead";
my $password = "pwdhead";

my ($dbase1, $dbase2) = qw/ db1 db2 /;

my $dsn1 = "DBI:mysql:database=$dbase1";
my $dsn2 = "DBI:mysql:database=$dbase2";

my $dbh1 = DBI->connect($dsn1, $userid, $password ) or die $DBI::errstr;
my $dbh2 = DBI->connect($dsn2, $userid, $password ) or die $DBI::errstr;

my $select = $dbh1->prepare("SELECT * FROM Persons");
my $insert = $dbh2->prepare("INSERT INTO Persons VALUES (?, ?, ?, ?, ?)");

$select->execute;
while ( my @row = $select->fetchrow_array ) {
    $insert->execute(@row);
}
Run Code Online (Sandbox Code Playgroud)

如果需要单独处理源数据中的列,则可以使用命名标量而不是数组@row.像这样

while ( my ($id, $name) = $select->fetchrow_array ) {
    my $lastname = '';
    $insert->execute($id, $name, $lastname);
}
Run Code Online (Sandbox Code Playgroud)