我写了一个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();
答案 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
感谢, 麦克