PL/SQL 条件アップデートについての質問

このQ&Aのポイント
  • PL/SQLを使用して、他のテーブルを参照しながら条件に合致するレコードのみをアップデートする方法が知りたいです。
  • トランTとマスタTというテーブルがあり、トランTのフィールド「店舗区分1」を前年同月に休業日が発生している店舗の「店舗区分1」に変更する方法はありますか?
  • PL/SQL初心者で、このようなケースのサンプルがなかなか見つからないため、詳しい方に教えていただきたいです。
回答を見る
  • ベストアンサー

PL/SQL 条件アップデートについて

PL/SQLを使用して、条件に合致するレコードのみをアップデートしようとした場合 この条件が他のテーブルを参照しなければいけない時どのようなロジックで実現できるでしょうか? 例えば下記のようなアップデート対象テーブルがあります。 トランT 取引先| 年月 |店舗区分1 |売上  AAA   201105     1     10000 マスタT 取引先| 開始日 | 終了日  AAA   20100501  20110608 トランTは月別店舗別の売上を管理しているテーブルで マスタTは店舗の休業日数を管理いているマスタテーブルになります。 更新を行いたいのはトランTのフィールド「店舗区分1」でその条件は 前年同月に休業日が発生している店舗の「店舗区分1」を'2'に変更したい場合どのようにすれば これを実現できるでしょうか? やり方は複数あると思うのですがPL/SQLで実現できればと思っています。 しかし、PL/SQL初心者の為これに必要なコマンドや関数などがわかりません。 調べてみてもこのようなケースのサンプルなどが無く困っています。 どなたか詳しい方がいればご教示頂きたく存じます。 よろしくお願いします。

  • Oracle
  • 回答数3
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

なぜPL/SQLでやろうとしたのでしょうか? UPDATE トランT SET 店舗区分1 = 2 WHERE EXISTS ( SELECT 1 FROM マスタT WHERE トランT.取引先=マスタT.取引先 AND トランT.年月 BETWEEN SUBSTR(マスタT.開始日,1,6) AND SUBSTR(マスタT.終了日,1,6) ) ではダメですか。

anman0201
質問者

補足

ご回答ありがとうございます。 大変参考になります。 なぜPL/SQLで実現しようとしたかというと自分の勉強のためと 当質問の内容は要件の一部であり 全処理概要は 1.日次で売上明細Tより月店別に売上集計を行いトランTにインサート 2.インサートしたデータの店舗区分の判定と更新 これらの処理をストアドプロシージャとして同DBに格納。 それを日次でShell等からcallするという仕様にしたいと思っております。 これを考えた時にメンテナンスのことを考えるPL/SQLを使用して ストアドプロシージャを作成したほうが良いかと考えました。 もっと良い方法などがあれば是非教えていただきたいです。 よろしくお願いします。

その他の回答 (2)

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.3

http://www.shift-the-oracle.com/plsql/update-where-current-of.html の「WHERE CURRENT OF による UPDATE 処理」をサンプルに組んでみられては? ここの cursor cur is select id, txt from insert_sample for update; を cursor cur is select t.年月,t.店舗区分1,t.売上取引先,m.開始日,m.終了日 from トランT t,マスタT m for update of t.店舗区分; とすればよいと思います(未確認)。 この形で、t.年月とm.開始日,m.終了日を判定してもいいし(遅いし負荷が高いけど)、 このfrom句の次にwhere句でt.年月とm.開始日,m.終了日に関する条件を設定してもいい (早いし負荷が軽いのでこちらをお勧め。) 注:for update of について OF句で指定した表のSELECTしたレコードがロックされますが、OF句で指定してない表はロックされません。

  • yorozu_ya
  • ベストアンサー率54% (76/140)
回答No.2

テーブルの説明に休業日も休業日数もありませんが、 どういうことでしょう。 説明不足です。 あと、日付項目のデータ型は何でしょう。

anman0201
質問者

補足

説明不足すみません。 トランTの前年同月と マスタTの開始日と終了日の間の日付がその月に該当していれば その取引先の店舗区分を変更したいということです。 また、開始終了日フィールドのデータ型はVACHAR2でyyyymmdd形式です。 よろしくお願いします。

関連するQ&A

  • ORACLE UPDATE文の書き方について

    いつもお世話になっています。 SQLのUPDATEについて、教えてください。 (例) 売上実績には、売上日を過去3回前まで保存しており、 売上トランの売上区分が”1”の情報を元に、売上実績の売上日情報を更新しています。 【売上実績】 │店舗│今 回│前 回│前々回│ ┼──┼───┼───┼───┼ │A店│12/05 │10/25 │10/01 │ │B店│11/15 │10/18 │09/05 │ │C店│11/30 │10/05 │09/15 │ │D店│12/01 │12/01 │11/01 │ │E店│12/07 │11/07 │10/07 │ │F店│11/18 │10/17 │08/11 │ 【売上トラン】 │店舗│売上日│売上区分│ ┼──┼───┼────┼ │A店│12/08 │ 1 │ ※繰越対象 │A店│12/08 │ 2 │ │B店│12/08 │ 2 │ │C店│12/08 │ 1 │ ※繰越対象 │D店│12/08 │ 2 │ │F店│12/08 │ 2 │ ーー結果ーー 【売上実績】 │店舗│今 回│前 回│前々回│ ┼──┼───┼───┼───┼ │A店│12/08 │12/05 │10/25 │ ※繰り越される │B店│11/15 │10/18 │09/05 │ │C店│12/08 │11/30 │10/05 │ ※繰り越される │D店│12/01 │12/01 │11/01 │ │E店│12/07 │11/07 │10/07 │ │F店│11/18 │10/17 │08/11 │ ※Keyは”店舗”  UPDATE 売上実績   Set 売上実績.今回 =        (Select 売上トラン.売上日 From 売上トラン           Where 売上トラン.店舗 = 売上実績.店舗 AND 売上トラン.売上区分= 1 ),     前回 = 今回,     前々回 = 前回       Where Exists ( Select 売上トラン.* From 売上トラン              Where 売上トラン.店舗 = 売上実績.店舗               AND 売上トラン.売上区分= 1 ) 上記処理をPL/SQLで行いたいのですが、正しい処理結果が作成されるのでしょうか? よろしくお願いします。 ※ORACLE環境がなく、ACCESSではうまく動作しなった為、質問させて頂きました・・・

  • SQLのUPDATE文(WHERE)で教えて下さい

    SQLのUPDATE文(WHERE)で教えて下さい SQL初心者なのですが、どなたか教えて頂けないでしょうか・・・。 Oracle10gにSqlPlusで接続してテーブルをUPDATEしようとしています。 【テーブル1】 品番、 規格、 取引先、 日付 A1   XXX  T001   2010/01/01 A1   YYY  T002   (空白) B1   XXX  T001   (空白) C1   ZZZ  T003   (空白) 【テーブル2】 品番、 規格、 取引先、 備考 A1   XXX  T001   あああ A1   YYY  T002   いいい B1   XXX  T001   ううう テーブル1の「日付」が(空白)のレコードを対象に、 テーブル1の「品番+規格+取引先」とテーブル2の「品番+規格+取引先」が同じな場合、 テーブル1の「日付」項目に今日の日付をUPDATEしたいと考えています。 結果を以下のようにしたいです。 【テーブル1】 品番、 規格、 取引先、 日付 A1   XXX  T001   2010/01/01 A1   YYY  T002   2010/03/19 B1   XXX  T001   2010/03/19 C1   ZZZ  T003   (空白) これが実現できるSQL文を教えて下さい。 宜しくお願い致します。

  • PL/SQLでUPDATE別テーブル条件を付加する

    PL/SQLでUPDATEする際、別のテーブルからの条件も付加し更新を行いたいのですが、可能でしょうか? 教えて下さい。 どうぞよろしくお願い致します。 テーブル名T_NAMEのSEI='1'の時以下のロジック処理を行いたいのです。 UPDATE T_ADRS SET DLT_FLG = '1' , USER_ID = inUSER_ID , TNMT_ID = inCOMP_ID , UPD_DT = SYSDATE WHERE RTRIM(ADR_CD) = RTRIM(strADR_CD) AND RTRIM(DATA_SY) = RTRIM(strDATA_SY) AND RTRIM(IMP_NO ) = RTRIM(strIMP_NO );

  • CASE文の集計について

    ORACLE10g EXISTS文について質問があります。 まず次のようなTBLが存在します。 休業MT 店舗CD | 休業区分 |  開始日  |  終了日 | AAA     09     20110311  20110311 AAA     09     20110313  20110325 AAA     03     20110330  20110330 月売上TR 店舗CD |  年月  |  客数  |  売上数 | 稼動タイプ AAA    201103   100     300    特殊 AAA    201104   200     400    フル 月売上TRの稼動タイプの判別を行う場合 以下の条件があります。 ・休業MTに同月、同店舗のレコードが存在しない場合にフルを適用 ・休業MTの休業区分 = 09 且つ その休業日合計が同月内で7日以内場合に稼動タイプにフルを適用。 ・休業MTの休業区分 = 03 である限り、同月に何回休業してもフルを適用 上記の条件をCASE文ですべて実現しようしたとき、 2番目の条件の休業日合計が7以下のものをうまく抽出できません。 CASE文やEXISTS文で集計項目に対して条件をつけることは可能でしょうか? できれば、サンプルSQLを教えていただきたいです。 よろしくお願いします。

  • ORACLE UPDATEについて

    いつもお世話になっています。 SQLのUPDATEについて、教えてください。 (例) 各店舗の売上累積ファイルに、日ごとの売上トランの情報を累計する。 処理日が12月31日の場合、年次繰越を行う。 売上実績ファイル │店舗│当年売上│前年売上│ ┼──┼────┼────┼ │A店│ 50000 │ 60000 │ │B店│ 25000 │ 32000 │ 売上トラン │店舗│本日売上│ ┼──┼────┼ │A店│ 25000 │ │B店│ 14000 │ ーー結果(12月31日の処理の場合)ーー 売上実績ファイル │店舗│当年売上│前年売上│ ┼──┼────┼────┼ │A店│   0 │ 75000 │ │B店│   0 │ 39000 │ ーー結果(12月31日以外の場合)ーー 売上実績ファイル │店舗│当年売上│前年売上│ ┼──┼────┼────┼ │A店│ 75000 │ 60000 │ │B店│ 39000 │ 32000 │ ※Keyは”店舗”、実績とトランの関係は1:1 UPDATE 売上実績ファイル SET 前年売上 = CASE ( WHEN WK-処理日 = 12/31        THEN 売上実績ファイル.当年売上 + 売上トラン.本日売上        ELSE 売上実績ファイル.前年売上 ) SET 当年売上 = CASE ( WHEN WK-処理日 = 12/31        THEN 0        ELSE 売上実績ファイル.当年売上 + 売上トラン.本日売上 ) WHERE 売上実績ファイル.店舗 = 売上トラン.店舗 上記処理をPL/SQLで行いたいのですが、正しい処理結果は求まるのでしょうか? よろしくお願いします。 ※環境がなく、動作検証が出来ない為、質問させて頂きました・・・

  • ORACLEのUPDATEについて教えてください

    いつもお世話になっています。 以下の処理を実現するUPDATEの記述を教えて頂けないでしょうか? よろしくお願い致します。 (ORACLE9i、PL/SQLを想定しています) 【店舗T】に、【売上T】の売上区分が”2”のレコードを対象に、予定日が指定日より近い順に 最大5日分設定する。 ※対象となる【売上T】のレコードは、予定日が指定日以降のみ対象とする ※【売上T】は各店舗毎に、0件から数十件まで存在する。 ※【店舗T】の売上履歴は毎回クリアし、売上Tより求める 【店舗T】 │  │   売 上 予 定 情 報     │ │店舗│直近1│直近2│直近3│直近4│直近5│ ┼──┼───┼───┼───┼───┼───┼ │A店│   │   │   │   │   │ │B店│   │   │   │   │   │ │C店│   │   │   │   │   │ │D店│   │   │   │   │   │ 【売上T】 │店舗│予定日│売上区分│ ┼──┼───┼────┼ │A店│12/10 │ 2 │○対象 │A店│12/20 │ 2 │○対象 │A店│12/30 │ 1 │※売上区分が”1”の為、対象外 │A店│12/31 │ 2 │○対象 │  │   │    │ │C店│12/01 │ 2 │※指定日(12/10)より前の為、対象外 │C店│12/05 │ 2 │※指定日(12/10)より前の為、対象外 │C店│12/11 │ 2 │○対象 │C店│12/11 │ 1 │※売上区分が”1”の為、対象外 │C店│12/15 │ 2 │○対象 │C店│12/21 │ 2 │○対象 │C店│12/25 │ 2 │○対象 │C店│12/30 │ 2 │○対象 │C店│12/31 │ 2 │※5件を超えた為、対象外 │  │   │    │ │D店│12/15 │ 1 │※売上区分が”1”の為、対象外 │D店│12/18 │ 1 │※売上区分が”1”の為、対象外 ---12月11日の結果--- 【店舗T】 │  │   売 上 予 定 情 報     │ │店舗│直近1│直近2│直近3│直近4│直近5│ ┼──┼───┼───┼───┼───┼───┼ │A店│12/20 │12/31 │ │   │   │ │B店│   │   │   │   │   │ │C店│12/11 │12/15 │12/21 │12/25 │12/30 │ │D店│   │   │   │   │   │

  • UPDATE文を教えて頂けないでしょうか

    いつもお世話になっています。 以下の処理を実現するUPDATE文を教えて頂きたく、質問にあげさせて頂きました。 ※現在、処理を「実績登録用UPDATE」と「予定登録用UPDATE」のそれぞれ作成すれば  いけそうなのですが、1つのUPDATE文では実現出来ないでしょうか?  ・・・実績登録用は作成したので、最後に付けています 以上、よろしくお願いします。 【処理】 トランより店マスタの更新を行う。 ・トランの区分が”1"の場合は、店マスタの実績欄へトランの日付情報をセットする。  ※店マスタの実績日は過去3日分を累積している為、 実績2を実績3へ、実績1を実績2へ   移してから、トランの日付を実績1欄にセットする  ※区分”1”のレコードは、店コード毎に1件しか存在しない ・トランの区分が”2"の場合は、店マスタの予定欄へトランの日付情報をセットする。  ※店マスタの予定日は、当処理が実行される時点では既にクリアされており、毎回トランに存在する   直近3日分を予定欄へセットする  ※区分”2”のレコードは、店コード毎に複数件存在する) 例) トラン(キー:店CD・日付)  店CD 日 付 区分  ┼───┼───┼──┼ │ 0001 │01/10 │ 1 │→マスタの実績1に登録されます │ 0001 │01/15 │ 2 │ │ 0002 │01/20 │ 2 │→マスタの予定1に登録されます │ 0002 │01/30 │ 2 │→マスタの予定2に登録されます │ 0003 │01/10 │ 1 │→マスタの実績1に登録されます │ 0005 │01/10 │ 1 │→マスタの実績1に登録されます │ 0005 │01/20 │ 2 │→マスタの予定1に登録されます │ 0005 │01/30 │ 2 │→マスタの予定2に登録されます │ 0005 │02/10 │ 2 │→マスタの予定3に登録されます │ 0005 │02/20 │ 2 │→マスタにはMAX3件までしか登録出来ないのでスキップ │ 0005 │03/01 │ 2 │→マスタにはMAX3件までしか登録出来ないのでスキップ マスタ(キー:店CD)  店CD│実績1 実績2 実績3│予定1 予定2 予定3│ ┼───┼───┼───┼───┼───┼───┼───┼ │ 0001 │01/05 │12/30 │12/25 │ │ │ │ │ 0002 │12/30 │12/15 │11/30 │ │ │ │ │ 0003 │01/01 │12/20 │12/10 │ │ │ │ │ 0004 │01/07 │01/06 │01/05 │   │ │ │ │ 0005 │01/01 │12/20 │12/10 │ │ │ │ 【希望する結果】  店CD│実績1 実績2 実績3│予定1 予定2 予定3│ ┼───┼───┼───┼───┼───┼───┼───┼ │ 0001 │01/10 │01/05 │12/30 │01/15 │ │ │ │ 0002 │12/30 │12/15 │11/30 │01/20 │01/30 │ │ │ 0003 │01/10 │01/01 │12/20 │01/07 │ │ │ │ 0004 │01/07 │01/06 │01/05 │   │ │ │ │ 0005 │01/10 │01/01 │12/20 │01/20 │01/30 │02/10 │ ■実績更新用UPDATE UPDATE マスタ SET ( 実績1,実績2,実績3 )=( SELECT 日付,MAX(TRN.実績1),MAX(TRN.実績2),MAX(TRN.実績3) FROM マスタ LEFT JOIN トラン TRN ON 店CD = 店CD WHERE 区分 = 1 GROUP BY トラン.店CD, トラン日付) WHERE EXISTS( SELECT 'TRUE' FROM マスタ WHERE マスタ.店CD = トラン.店CD AND マスタ.日付  = トラン.日付 AND トラン.店CD = 1 );

  • PL/SQLのカーソルについて

    すみません。 PL/SQLにて以下のようなカーソルがあるのですが、 引数のpJYOKENをWHERE条件に追加することはできないでしょうか。 pJYOKENには(属性 = 0)のような条件が入っています。 条件はその都度違ったものが入ってくるイメージです。 cursor CURテスト (pJYOKEN IN VARCHAR2) IS SELECT 社員コード FROM テストマスタ WHERE 会社ID = '001' AND 区分 = 1; rcテスト CURテスト%rowtype; よろしくお願い致します。

  • SQLの書き方(UPDATE文)

    SQLの書き方の質問です。 売上Tと商品Mというテーブルがあったとして、 売上Tには商品コード、数量、金額という項目が 商品Mには商品コード、単価という項目が それぞれあったとします。 売上Tの金額=売上T.数量×商品M.単価 この売上Tの金額を更新するのに、update文でできるだけシンプルに高速に動くSQL文を作成したいのですが、どのような書き方がよいと思いますか? 件数は例えば売上が100万件、商品が10万件あった場合を想定して。 以上よろしくお願いいたします。

  • PL/SQLトリガー機能

    PL/SQLでトリガーを使って下記処理をしたいのですが教えてください。 処理内容 a在庫数テーブルの在庫数がUPDATE(After UPDATE)するたびに b在庫数テーブルにa在庫数の店CD(KEY1)と商品CD(KEY2)と取引日と当日売上日と在庫数を追加(INSERT) この時、 b在庫数テーブルのkey店CD(KEY1)と商品CD(KEY2)と取引日(KEY3)が同じ場合、在庫数のみを更新(UPDATE)する。 上記の事柄のトリガー機能・処理分を教えてください。 よろしくお願いします。