【问题标题】:Perl DBI - Set schema name as bind variable in queryPerl DBI - 在查询中将模式名称设置为绑定变量
【发布时间】:2015-08-12 13:40:59
【问题描述】:

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

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,但是有没有一种合法的方法可以通过查询传递名称?如果是这样,谁能指出这里出了什么问题?

【问题讨论】:

    标签: perl dbi


    【解决方案1】:
    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 ..."
    

    【讨论】:

    • 作为一个小点,不清楚 Oracle 引擎是否在替换标识符上抛出 ORA-00903(在 'DEV'.HOSTGROUPS 上),或者它是否忽略了占位符中的占位符未替换标识符 (:p1.HOSTGROUPS) 上的错误。从错误消息中,我希望是后者。无论如何,错误的架构名称规范。
    • @pilcrow,我从未声称实际发生了替换。我刚刚解释了? 的含义,以及将它放在那里没有任何意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2012-12-26
    • 2011-09-21
    相关资源
    最近更新 更多