2019.01.24



Mike Larsen著

複数メンバーのファイルでSQLを使用する

Pick Up

先日、一定の基準に基づいてファイルのレコードを更新する必要があるプロセスの作業を行いました。よくある要件のように聞こえるかもしれません。ところが、それには一癖ありました。ファイルには複数のメンバーがあり、更新はそれらのすべてを考慮に入れる必要があったのです。「単純な」要件が、突然、難易度の高いものになりました。

複数メンバーのファイルで作業する方法はいくつか知っていましたが、どの方法で処理するかを決める前にすべての選択肢を示しておきたいと思います。検討した方法の1つは、ファイルのオーバーライドを実行することでした(OVRDBFコマンド)。確かにそれでうまく行きますが、プログラム実行のたびにすべてのメンバーをループすることが必要になります。

複数メンバーのファイルで作業できるもうひとつの方法は、SQLエイリアスを使用することです(図1)。

Exec sql
     Create alias qtemp/SalesHist_January
       for SalesHist(January);                  // file name(member name)

   Exec sql
     Select count(*) into :numberOfItems
      from qtemp/SalesHist_January;

   // drop the alias when i'm done

   Exec sql
     Drop alias qtemp/SalesHist_January;

図1: エイリアスを使用してファイルのメンバーにアクセスする

QTEMPにエイリアスを作成し、ファイルとメンバーに指定しました。そうすることにより、SalesHistファイルのJanuaryメンバー内のレコードにアクセスすることができました。エイリアスは削除しました。もう必要でないからです。Januaryメンバーへのアクセスを何度も行う必要があるのだとしたら、エイリアスはそのまま残しておけばよいでしょう。

エイリアスを使用することで、単一のメンバーを直接処理できるようになりました。今回の課題に対してはこの方法も有用ですが、すべてのメンバーのループが必要なことは変わりありません。さらに調べてみると、メンバーそれぞれにエイリアスを作成して、union all演算子を使ってすべてのメンバーにアクセスできることが分かりました。この方法の方が、行いたかったことに近いように思えました。すべてのメンバーを一気に処理したかったからです。ただし、メンバーの数が多い場合、SQLステートメントがかなり長くなる可能性があります。また、これらのどちらの方法を使用する場合でも、メンバーの名前を知っている必要があり、そのための追加作業が生じることにもなります。

もうひとつ、この課題に取り組むために思い付いた方法があります。それは、物理ファイルのすべてのメンバーに対して作成された、論理ファイルを使用するという方法です。その論理ファイルでSQLステートメントを実行すると、一度にすべてのメンバーのレコードにアクセスすることができます。これこそが本当に行いたかったことでした。ループもまったく行う必要はなく、メンバーの名前を知っている必要もありません。ただし、この方法でも注意すべき点があります。それは、新たなメンバーが追加されたら、論理ファイルを作り直す必要があり、そうしないと、新たなメンバーにアクセスすることができないという点です。しかし、この方法を選んだことで、SQLステートメントは次のように単純になりました(図2)。

// I can use the logical file to update records in all members at one
// time.

   Exec sql
     Update SalesHist2
      Set HeOpen = substr(HeOpen,1,10) concat 'Y' concat substr(HeOpen,12,29);

図2: すべてのメンバーでレコードを更新する

また、複数メンバーのファイルでレコードを選択して更新できるだけでなく、特定のメンバーにレコードを挿入することもできます(図3)。

// To insert into a particular member, I can use an Sql alias.

   Exec sql
     Create alias qtemp/saleshist_mike
       for saleshist(mike);

   Exec sql
     Insert into qtemp/saleshist_mike
       values('RT', 1, 20, 18, 09, 15, '000050675305486',
              'open text N 000050675305486', '01', 122.22, 22.22);

   Exec sql
     Drop alias qtemp/saleshist_mike;   

図3: エイリアスを使用してレコードをメンバーに挿入する

これは前述のselectステートメントによく似ています。ただし、こちらでは、エイリアスを使用してSalesHistファイルのMikeメンバーにレコードを挿入しています。

ここでは、複数メンバーのファイルで作業するための方法をいくつか紹介しました。これらの方法はそれぞれ有用だと思いますが、その場でどれを使用するのが適切かは、状況に合わせて判断してください。

ページトップ

ボタン