0

OracleデータベースのデータをチェックするPerlスクリプトを作成しました。クエリプロセスは非常に複雑なので、途中でVIEWを作成することにしました。このビューを使用すると、コードを大幅に簡略化できます。

Perlコードを使用して、のようなファイルからデータベースをクエリした場合、Perlコードは適切に実行されますPerl mycode.pl file_a。Perlコードfile_aは、入力の最後までビューから行を読み取り、ビューを作成/更新します。私が達成した結果は完全に正しいです。

同時に走ると問題が発生しました

perl mycode.pl file_a

perl mycode.pl file_b

同じデータベースにアクセスします。私の観察によると、最初のプロセスで使用されるVIEWは、2番目のプロセスで変更されます。これらの2つのプロセスは、同じビューで絡み合っていました。

これらの2つのプロセスが互いに競合しないようにするための提案はありますか?

データベースをクエリするための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

絶対です

  • ビューを1回だけ作成し、どこでも使用できます

  • SQLステートメントでプレースホルダーを使用し、次の呼び出しで実際のパラメーターを渡します。execute

これはSQLの全範囲ですか?おそらくそうではありませんが、そうであれば、それは本当にかなり単純です。

いくつかのアイデアについては、このリファクタリングをご覧ください。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 テーブルで存在するかどうかを確認してください

$$変数を使用してpidを含むビューを簡単に作成できますが、コンピューター間で一意になることはありません。オラクルには一意の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 に答える