- PR -

バッチ処理でSQLを実行。SELECT→一時テーブル?

投稿者投稿内容
take
大ベテラン
会議室デビュー日: 2004/08/13
投稿数: 177
お住まい・勤務地: 沖縄県北部
投稿日時: 2005-12-14 23:38
いつもお世話になります。

夜間バッチで業務データを変換するのですが、
メインフレームのシェル等を触ったことが
ないので分からないのです。SQLをバッチで
処理する時にSELECTした値は一時テーブルに
保存して次の処理、処理が済んで無用になったら
削除みたいな流れがいいのでしょうか?
それともDBによっては違う方法で処理できたり
するのでしょうか?

ご存知の方がいらっしゃいましたらご教示
いただきたくお願いいたします。
Desmo
大ベテラン
会議室デビュー日: 2004/03/24
投稿数: 149
投稿日時: 2005-12-15 08:36
SQLのバッチでは一体どういう処理をしたいのでしょうか?
内容次第で、一時テーブルが必要かもしれないし、必要ではないかもしれません。
SQLならば RDBMSの種類に関係なく同一の処理方法を取れる可能性がありますが、RDBMS独自の機能を使った方が効率的な場合もあります。それも処理の内容次第でしょう。

> メインフレームのシェル等を触ったことがないので分からないのです。

メインフレームのシェルで処理されたいのですか? それと今回の質問の「SQLのバッチ」とはどういう関係なのでしょう?
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2005-12-15 09:30
おそらく汎用機であれば言語はCOBOL、DBはDB2だと思います。
引用:

SQLをバッチで
処理する時にSELECTした値は一時テーブルに
保存して次の処理、処理が済んで無用になったら
削除みたいな流れがいいのでしょうか?


それでも問題ないですし、ファイルに落とし込んでもかまわないと思います。
引用:

それともDBによっては違う方法で処理できたり
するのでしょうか?


すべての処理をストアドプロシージャーで記述し、COBOLを利用せずにJCLのみで運用するということもできます。
take
大ベテラン
会議室デビュー日: 2004/08/13
投稿数: 177
お住まい・勤務地: 沖縄県北部
投稿日時: 2005-12-15 09:48
Desmoさん、ご返答いただきありがとうございます。
今回のプロジェクトは既存のCOBOLプログラムで
処理してる業務データをRDBに移行するという感じです。
詳しい処理内容はこれから解析しないとわからないのですが、
たとえばこんな感じのがあります。

売り上げテーブルと社員テーブルを社員コードで結合し、---一時テーブル1

商品コードがAのものから入金済みは入金済みテーブルへ。---一時テーブル2

未入金は入金待ちテーブルへ。    ---一時テーブル3

入金待ちテーブルの中で期限が過ぎているものは期限過ぎ
フラグを立てる。           ---一時テーブル4


この処理を長いSQLを書かずに、できるだけ処理が明解なSQLを
連続で書いて処理させたいのです。

************一時テーブル1************

SELECT * FROM T_URI,T_SYAIN WHERE SYAIN_CD=SYAIN_CD

************一時テーブル2************

SELECT * FROM 一時テーブル1 WHERE 入金済み


************一時テーブル3************

SELECT * FROM 一時テーブル1 WHERE 未入金

************一時テーブル4************

UTDATE 一時テーブル4 SET 未入金フラグ=TRUE

作成した一時テーブルを対応するテーブルに
コミットし、いらなくなったデータはDelete
する処理をシェルに実行させるみたいです。
シェルからは一通りのSQLが書かれたSQLファイル
を呼び出して実行するみたいです。

シェルから一時テーブルを変数のような利用が
できるのか、それとも一時テーブルを実態として
作成して、処理が終わったらそのテーブルを削除
する処理が必要なのかが見えずに悩んでいます。

設計自体がおかしというつっこみが予想されますが、そのあたりは
例えですので寛大にお願いいたします。
一般的にバッチでSQLをどのように処理させてるのかが知りたいのです。
よろしくお願いします。




take
大ベテラン
会議室デビュー日: 2004/08/13
投稿数: 177
お住まい・勤務地: 沖縄県北部
投稿日時: 2005-12-15 10:04
Anthyhimeさんご返答ありがとうございます。
ちょっと順番が前後してしまいましたが…。
引用:

Anthyhimeさんの書き込み (2005-12-15 09:30) より:
おそらく汎用機であれば言語はCOBOL、DBはDB2だと思います。
引用:

SQLをバッチで
処理する時にSELECTした値は一時テーブルに
保存して次の処理、処理が済んで無用になったら
削除みたいな流れがいいのでしょうか?


それでも問題ないですし、ファイルに落とし込んでもかまわないと思います。
引用:

それともDBによっては違う方法で処理できたり
するのでしょうか?


すべての処理をストアドプロシージャーで記述し、COBOLを利用せずにJCLのみで運用するということもできます。



ストアドプロシージャを調べてみました。できそうです。ただ、大まかな流れの仕様書
には、シェルからSQLファイルを実行見たいに書いてあって、ストアドプロシージャと
いう言葉はいっさい出てきません。この場合はテーブルを一度作って削除という処理
以外したほうがいいのでしょうか?バッチ処理全体をSQLで表現したいようなので
ファイルに落とし込む方法はあまりとりたくないようです。一度テーブルを作成して
削除という方法よりはストアドプロシージャを使ったほうが処理的にも早そうな感じ
がするのですが、そんなことはないのでしょうか?
いーた
大ベテラン
会議室デビュー日: 2004/07/12
投稿数: 154
お住まい・勤務地: 東京
投稿日時: 2005-12-15 10:24
引用:

売り上げテーブルと社員テーブルを社員コードで結合し、---一時テーブル1

商品コードがAのものから入金済みは入金済みテーブルへ。---一時テーブル2

未入金は入金待ちテーブルへ。    ---一時テーブル3

入金待ちテーブルの中で期限が過ぎているものは期限過ぎ
フラグを立てる。           ---一時テーブル4


テーブルは「売り上げテーブル」「社員テーブル」「入金済みテーブル」「入金待ちテーブル」の4つとして、以下のフローで要件が満たせるかと思います。

1.売り上げテーブルと社員テーブルを社員コードで結合しSELECT。
 (商品コードがAのものから〜とあるので、商品コードでSORTする必要あり?)
2.SELECT結果を取得して、入金済みであれば入金済みテーブルへINSERT。
 未入金であれば入金待ちテーブルへINSERT。但し、期限を超過していた場合は期限過ぎフラグを立ててINSERTを行う。
Desmo
大ベテラン
会議室デビュー日: 2004/03/24
投稿数: 149
投稿日時: 2005-12-15 15:15
takeさんへ
目的はよく判りました。
しかしながら私はメインフレームの知識がないので想像も交えて記述します。
もし外していたらスミマセン。
やりたい事は「レガシーシステムからRDBMSにデータを移行するバッチを作りたい」で、
手順は、
1. RDBMS側に一時テーブルを作成し、そこにレガシーシステムの基本データを書き込む
2. 一時テーブルからRDBMS側の通常テーブルを作成する
3. 最後に不要になった一時テーブルを削除する
といった感じでしょうか?
レガシーシステムからRDBMSへの書き込みができて かつRDBMSへSQLも発行できるのなら、このやり方で良いのではないでしょうか?
一時テーブルを作らないで、最初からレガシー側で最終データと作って吐き出す方法もあるのかもしれませんが、そういった処理はRDBMS側で(2.の部分で)やらせた方が高速でしょう。必要ならばここ(2.の部分で)ストアドプロシジャーを使うことも出来ると思います。

ところでストアドプロシジャーですが、これは「使えば速い」ってものではありません。
SQL文は ストアドプロシジャーの中から発行しても、クライアント側から発行しても大差はありません。
一番大きく差がでるのはループ文などで繰り返しの処理ロジックを組んだ場合です。
そうした処理が無いのであれば、無理にストアドプロシジャーを使う必要はありません。
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2005-12-15 15:20
引用:

takeさんの書き込み (2005-12-15 09:48) より:

売り上げテーブルと社員テーブルを社員コードで結合し、---一時テーブル1

商品コードがAのものから入金済みは入金済みテーブルへ。---一時テーブル2



このように一時テーブルを作る方法で問題ないと考えますが、トランザクション制御が緩いと dirty update(一時テーブル1を作ってから参照するまでの間に売り上げテーブルが更新されてしまう等)や、トランザクションを abort した時に一時テーブルが残ってしまったりという問題が発生します。

SQL99 仕様では、途中の計算結果を一時テーブルの代わりに名前付きのインラインビューとして求めておいてからメインのクエリで参照できるようにし、更にメインクエリまでの処理をアトミックに実行する WITH 句が導入されました。
(他の RDBMS は確認していませんが、Oracle では 9i 以降で利用できます。
DB2 も、
http://www.stefan-wagner.info/cs/trans_clos.php
によると対応しているようです。)

以下のページに解説があるのでご覧ください。

新しい業界標準「SQL99」詳細解説 第一章 高度なデータ操作(2)
http://www.atmarkit.co.jp/fnetwork/tokusyuu/01sql99/sql99_1b.html

スキルアップ/キャリアアップ(JOB@IT)