0

我编写了一个 Perl 脚本来检查 Oracle 数据库中的数据。因为查询过程很复杂我选择在中间创建一个VIEW。使用这个视图可以大大简化代码。

当我使用 Perl 代码从文件开始查询数据库时,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();
4

2 回答 2

1

你必须

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

  • 在 SQL 语句中使用占位符,并通过调用传递实际参数execute

这是您的 SQL 的全部范围吗?可能不是,但如果是这样,它确实相当简单。

看看这个重构以获得一些想法。注意是使用一个here文件来表达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;
}
于 2012-08-12T19:24:00.990 回答
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

谢谢,迈克

于 2012-08-12T18:39:05.540 回答