Perl DBI - 在查询

时间:2015-05-29 15:46:35

标签: perl dbi

我正在编写一个脚本,它在几个不同的数据库中执行相同的合并语句。表名和列在我连接的每个模式中是相同的,但模式名称本身是不同的。我不想定义两个单独的查询,而是将一个合并语句定义为模式名称设置为“?”的字符串,然后在执行期间传入所需的模式名称:

my $hostgroup_merge = "MERGE INTO ?.HOSTGROUPS .... ";

然后是:

my $dev_schema  = 'DEV';
my $prod_schema = 'PROD';

#do the merge in the dev schema
my $dbh = DBI->connect($dev_server,$user,$pass);
my $sth = $dbh->prepare($hostgroup_merge);
$sth->execute($dev_schema);
$sth->finish();
$dbh->disconnect;

#now do the same merge for the prod schema
$dbh = DBI->connect($prod_server,$user,$pass);
$sth = $dbh->prepare($hostgroup_merge);
$sth->execute($prod_schema);
$sth->finish();
$dbh->disconnect;

此操作因表名错误无效而失败:

DBD::Oracle::st execute failed: ORA-00903: invalid table name (DBD ERROR: error possibly near <*> indicator at char 19 in ' MERGE INTO :p1<*>.HOSTGROUPS ...

然而,它似乎正好接受绑定变量,因为它在查询之后将其吐出:

" with ParamValues: :p1='DEV']

我知道导致问题的绑定变量,因为当我定义单独的合并语句并对模式名称进行硬编码时,它们的工作正常。

由于唯一正在改变的是一开始的变量,我可能通过在字符串中定义语句的不变部分,然后连接其余部分来破解查询:

my $dev_merge = 'MERGE INTO ' . $dev_schema . $merge_statement;

然后只需运行prepare,但有没有合法的方式通过查询传递名称?如果是这样,有人能指出这里出了什么问题吗?

1 个答案:

答案 0 :(得分:2)

SELECT * FROM Table WHERE X = ?

相当于

SELECT * FROM Table WHERE X = 'DEV'

所以

MERGE INTO ?.HOSTGROUPS .... 

相当于

MERGE INTO 'DEV'.HOSTGROUPS ...

,而你想要

MERGE INTO DEV.HOSTGROUPS ...

使用

"MERGE INTO ".$dbh->quote_identifier($schema).".HOSTGROUPS ..."