-1

我正在测试这个 perl 脚本,它基本上调用过程并在 2 个表上运行 DELETE。

问题:

  1. perl 中的过程或调用过程有什么问题吗?
  2. 我可以在单个过程中使用 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"] 
4

1 回答 1

0

DELETE不采用导致表 id 的表达式;它需要一个表 id 文字。因此,您不能使用可替换参数。您需要构造表 id 文字,这$dbh->quote_identifier可以做到。

my $sql = 'DELETE '.$dbh->quote_identifier($dbID);
$dbh->do($sql);

您正在使用一个以非常糟糕的方式包装 DBI 的模块1。我无法知道它是否可以访问数据库句柄或句柄的quote_identifier方法,但至少现在你知道要查找什么了。


笔记:

  1. 有 3 种包装 DBI 的方法是有意义的:

    1. 添加功能或覆盖现有功能的一些次要方面。

      例如,DBI 数据库语句没有数据库句柄上的 selectrow_* 方法。添加这些而不限制对 DBI 其余部分的访问是非常好的。

    2. 提供更高级别的数据库抽象,例如像DBIx::Class这样的 ORM 。这些是具有数千甚至数万行的庞大系统。

      如果你的包装器提供了一个新的数据库接口并且它的代码适合两个屏幕,那么它做错了。

    3. 通过提供特定于应用程序的函数(如create_userfetch_daily_report_data等)来集中所有数据库代码。不传递 SQL

      如果您的包装器尝试这样做但提供了需要 SQL 的函数,那么它做错了。

    尝试简化 DBI 是没有意义的,这似乎是您的包装器所做的。DBI 实际上提供了一个非常简单的接口。任何简化它的尝试都必然会遗漏一些关键的东西。

于 2013-06-13T21:04:44.117 回答