- - PR -
バッチ処理でSQLを実行。SELECT→一時テーブル?
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-12-14 23:38
いつもお世話になります。
夜間バッチで業務データを変換するのですが、 メインフレームのシェル等を触ったことが ないので分からないのです。SQLをバッチで 処理する時にSELECTした値は一時テーブルに 保存して次の処理、処理が済んで無用になったら 削除みたいな流れがいいのでしょうか? それともDBによっては違う方法で処理できたり するのでしょうか? ご存知の方がいらっしゃいましたらご教示 いただきたくお願いいたします。 | ||||||||||||
|
投稿日時: 2005-12-15 08:36
SQLのバッチでは一体どういう処理をしたいのでしょうか?
内容次第で、一時テーブルが必要かもしれないし、必要ではないかもしれません。 SQLならば RDBMSの種類に関係なく同一の処理方法を取れる可能性がありますが、RDBMS独自の機能を使った方が効率的な場合もあります。それも処理の内容次第でしょう。 > メインフレームのシェル等を触ったことがないので分からないのです。 メインフレームのシェルで処理されたいのですか? それと今回の質問の「SQLのバッチ」とはどういう関係なのでしょう? | ||||||||||||
|
投稿日時: 2005-12-15 09:30
おそらく汎用機であれば言語はCOBOL、DBはDB2だと思います。
それでも問題ないですし、ファイルに落とし込んでもかまわないと思います。
すべての処理をストアドプロシージャーで記述し、COBOLを利用せずにJCLのみで運用するということもできます。 | ||||||||||||
|
投稿日時: 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をどのように処理させてるのかが知りたいのです。 よろしくお願いします。 | ||||||||||||
|
投稿日時: 2005-12-15 10:04
Anthyhimeさんご返答ありがとうございます。
ちょっと順番が前後してしまいましたが…。
ストアドプロシージャを調べてみました。できそうです。ただ、大まかな流れの仕様書 には、シェルからSQLファイルを実行見たいに書いてあって、ストアドプロシージャと いう言葉はいっさい出てきません。この場合はテーブルを一度作って削除という処理 以外したほうがいいのでしょうか?バッチ処理全体をSQLで表現したいようなので ファイルに落とし込む方法はあまりとりたくないようです。一度テーブルを作成して 削除という方法よりはストアドプロシージャを使ったほうが処理的にも早そうな感じ がするのですが、そんなことはないのでしょうか? | ||||||||||||
|
投稿日時: 2005-12-15 10:24
テーブルは「売り上げテーブル」「社員テーブル」「入金済みテーブル」「入金待ちテーブル」の4つとして、以下のフローで要件が満たせるかと思います。 1.売り上げテーブルと社員テーブルを社員コードで結合しSELECT。 (商品コードがAのものから〜とあるので、商品コードでSORTする必要あり?) 2.SELECT結果を取得して、入金済みであれば入金済みテーブルへINSERT。 未入金であれば入金待ちテーブルへINSERT。但し、期限を超過していた場合は期限過ぎフラグを立ててINSERTを行う。 | ||||||||||||
|
投稿日時: 2005-12-15 15:15
takeさんへ
目的はよく判りました。 しかしながら私はメインフレームの知識がないので想像も交えて記述します。 もし外していたらスミマセン。 やりたい事は「レガシーシステムからRDBMSにデータを移行するバッチを作りたい」で、 手順は、 1. RDBMS側に一時テーブルを作成し、そこにレガシーシステムの基本データを書き込む 2. 一時テーブルからRDBMS側の通常テーブルを作成する 3. 最後に不要になった一時テーブルを削除する といった感じでしょうか? レガシーシステムからRDBMSへの書き込みができて かつRDBMSへSQLも発行できるのなら、このやり方で良いのではないでしょうか? 一時テーブルを作らないで、最初からレガシー側で最終データと作って吐き出す方法もあるのかもしれませんが、そういった処理はRDBMS側で(2.の部分で)やらせた方が高速でしょう。必要ならばここ(2.の部分で)ストアドプロシジャーを使うことも出来ると思います。 ところでストアドプロシジャーですが、これは「使えば速い」ってものではありません。 SQL文は ストアドプロシジャーの中から発行しても、クライアント側から発行しても大差はありません。 一番大きく差がでるのはループ文などで繰り返しの処理ロジックを組んだ場合です。 そうした処理が無いのであれば、無理にストアドプロシジャーを使う必要はありません。 | ||||||||||||
|
投稿日時: 2005-12-15 15:20
このように一時テーブルを作る方法で問題ないと考えますが、トランザクション制御が緩いと 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 |