我正在测试这个perl脚本,该脚本基本上调用过程并在2个表上运行DELETE。
问题:
我可以在一个程序中使用2个删除吗?
Procedure delete (v_db_id in number) IS BEGIN DELETE from TAB1 where db_id = v_db_id; DELETE from TAB2 where db_id = v_db_id; END delete;
PERL脚本:
sub getdelete {
my $dbID = shift
my $rs;
my $SQL;
$SQL = q{delete (?)};
$rs = executeQuery($SQL,$dbID);
$rs -> fetchrow();
$rs -> finish();
}
PERL脚本调用子程序getdelete如下:
&getdelete ($dbID);
错误:
DBD::Oracle::st execute failed: ORA-00900: invalid SQL statement (DBD Error: OCIStmtExecute)[for statement "delete"]
答案 0 :(得分:0)
DELETE
不会生成导致表ID的表达式;它需要一个表id文字。因此,您无法使用可替换参数。您需要构建表id文字,$dbh->quote_identifier
可以执行。
my $sql = 'DELETE '.$dbh->quote_identifier($dbID);
$dbh->do($sql);
您使用的模块以非常差的方式包装DBI 1 。我无法知道它是否可以访问数据库句柄或句柄的quote_identifier
方法,但至少现在你知道要查找的内容。
注意:
有三种方法可以包装DBI:
添加功能或覆盖现有功能的一些次要方面。
例如,DBI数据库语句没有在数据库句柄上创建的selectrow_ *方法。在不限制访问其余DBI的情况下添加这些内容是完全没问题的。
提供数据库的更高级抽象,例如DBIx::Class之类的ORM。这些是具有数千甚至数万行的大规模系统。
如果你的包装器提供了一个新的数据库接口,并且它的代码适用于两个屏幕,那就是做错了。
通过提供特定于应用程序的函数来集中所有数据库代码,例如create_user
,fetch_daily_report_data
等。不传递SQL
如果你的包装器试图这样做但是提供了期望SQL的函数,它就会出错。
没有意义的是尝试简化DBI,这似乎是你的包装器所做的。 DBI实际上提供了一个非常简单的接口。任何简化它的尝试都必然会遗漏一些关键的东西。