Perl DBI通过创建VIEW修改Oracle数据库

时间:2012-08-12 17:43:04

标签: sql perl oracle dbi

我写了一个Perl脚本来检查Oracle数据库中的数据。由于查询过程非常复杂,我选择在中间创建一个VIEW。使用此视图可以大大简化代码。

当我使用Perl代码从文件开始查询数据库时运行良好,例如Perl mycode.pl file_a。 Perl代码从file_a读取行并创建/更新视图,直到输入结束。我取得的成果是完全正确的。

当我同时运行时出现问题

perl mycode.pl file_a

perl mycode.pl file_b

访问同一个数据库。根据我的观察,第一个过程使用的VIEW将由第二个过程修改。这两个过程在同一视图上交织在一起。

有没有建议让这两个过程互不冲突?

查询数据库的Perl代码通常是这样的,但每个实际查询中的细节更复杂。

my ($gcsta,$gcsto,$cms) = @t; #(details of @t is read from a line in file a or b)

my $VIEWSS = 'CREATE OR REPLACE VIEW VIEWSS AS SELECT ID,GSTA,GSTO,GWTA FROM TABLEA   WHERE GSTA='.$gcsta.' AND GSTO='.$gcsto.' AND CMS='.$cms;

my $querying = q{ SELECT COUNT(*) FROM VIEWSS WHERE VIEWSS.ID=1};

my $inner_sth = $dbh->prepare($VIEWSS);
my $inner_rv  = $inner_sth->execute();

$inner_sth = $dbh->prepare($querying);
$inner_rv  = $inner_sth->execute();

2 个答案:

答案 0 :(得分:1)

你必须

  • 仅创建一次视图,并在任何地方使用

  • 在SQL语句中使用占位符,并通过调用execute

  • 传递实际参数

这是SQL的全部范围吗?可能不是,但如果是这样,那真的很简单。

看一下这个重构的一些想法。注意,它使用 here document 来表示SQL。文本末尾的END_SQL标记必须在其之前或之后没有空格。

如果您的要求比此要复杂,请向我们描述,以便我们更好地为您提供帮助

my $stmt = $dbh->prepare(<<'END_SQL');
SELECT count(*)
FROM tablea
WHERE gsta = ? AND gsto = ? AND cms= ? AND id = 1
END_SQL

my $rv = $stmt->execute($gcsta, $gcsto, $cms);



如果您必须使用视图,那么您应该像以前一样使用CREATE VIEW中的占位符,并将每组更改都放入事务中,以便其他进程不会干扰。这涉及在您创建数据库句柄AutoCommit时禁用$dbh,并在所有步骤完成时添加对$dbh->commit的调用

use strict;
use warnings;

use DBI;

my $dbh = DBI->connect('dbi:Oracle:mydbase', 'user', 'pass',
        { AutoCommit => 0, RaiseError => 1 } );

my $make_view = $dbh->prepare(<<'END_SQL');
CREATE OR REPLACE VIEW viewss AS
SELECT id, gsta, gsto, gwta
FROM tablea
WHERE gsta = ? AND gsto = ? AND cms= ? AND id = 1
END_SQL

my $get_count = $dbh->prepare(<<'END_SQL');
SELECT count(*)
FROM viewss
WHERE id = 1
END_SQL

while (<>) {

  my ($gcsta, $gcsto, $cms) = split;

  my $rv = $make_view->execute($gcsta, $gcsto, $cms);
  $rv = $get_count->execute;
  my ($count) = $get_count->fetchrow_array;
  $dbh->commit;
}

答案 1 :(得分:0)

视图是相同还是不同?

如果视图完全相同,则只创建一次,或使用all_views表检查它是否存在:http://docs.oracle.com/cd/B12037_01/server.101/b10755/statviews_1202.htm#i1593583

您可以轻松地创建一个包含pid的视图,其中$$变量是pid,但它不会在计算机上唯一,oracle也有一些独特的ID,请参阅http://docs.oracle.com/cd/B14117_01/server.101/b10759/functions150.htm,例如SESSIONID。

但你真的需要这样做吗?为什么不准备一个声明然后执行呢? http://search.cpan.org/dist/DBI/DBI.pm#prepare

感谢, 麦克