dポイントプレゼントキャンペーン実施中!

いつもお世話になります。

ORACLE9i・PL/SQL上で複雑!?なUPDATE&INSERTがあり、それぞれを別々に
処理することにはしました。
ただ、UPDATE、INSERTをそれぞれ一回で完了させるSQLが掛けません
(私には複雑すぎるので・・)
どなたか以下の処理を実現する、UPDATE文、INSERT分を教えて頂けないでしょうか?

例)
店舗別の【予算T】があります。
・予算額欄が、ゼロの場合、UPDATEを行う
 (1)【店舗M】の「業種区分」を求める
 (2)「業務区分」より、【業務分類】の「予算G」を求める
 (3)「予算G」より【グループ別予算】の予算額を求める
 (4)求めた予算額で、【予算T】の「予算額」を更新する。

・【予算T】に存在しない店舗の予算レコードのINSERTを行う
 (1)【予算T】に存在しない店舗の「業種区分」を【店舗M】より求める
 (2)「業種区分」より【業務分類】の「予算G」を求める
 (3)「予算G」より【グループ別予算】の予算額を求める
 (4)求めた予算額、店舗の情報を【予算T】にレコード登録する。

【予算T】
│店舗│予算額│
┼──┼───┼
│A店│ 5000 │
│C店│ 0000 │
│D店│ 3500 │

【店舗M】
│店舗│コード│業務区分│
┼──┼───┼────┼
│A店│00001 │001   │
│B店│00002 │001   │
│C店│00003 │003   │
│D店│00004 │003   │
│F店│00030 │002   │

【業務分類】
│業務区分│予算G│
┼────┼───┼
│ 001  │ A │
│ 002  │ A │
│ 003  │ B │
│ 004  │ C │

【グループ別予算】
│予算G│予算額│
┼───┼───┼
│ A │10000 │
│ B │05000 │
│ C │05000 │
│ D │03000 │

ーー結果ーー

・UPDATE
【予算T】
│店舗│予算 │
┼──┼───┼
│A店│ 5000 │
│C店│ 5000 │
│D店│ 3500 │

・INSERT後(最終結果)
【予算T】
│店舗│予算 │
┼──┼───┼
│A店│ 5000 │
│B店│10000 │
│C店│ 5000 │
│D店│ 3500 │
│F店│10000 │

A 回答 (2件)

No.1です。



すみません、質問をきちんと読めていませんでした。
>UPDATE、INSERTをそれぞれ一回で完了させるSQL
UPDATEとINSERTは別々のSQLで処理したいのですね。
なら、それぞれ

--UPDATE
update yosan_t target
set yosan = (
select g_yosan.yosan
from tenpo_m
inner join gyoumu on tenpo_m.kbn = gyoumu.kbn
inner join g_yosan on gyoumu.yosan_g = g_yosan.yosan_g
where target.tenpo = tenpo_m.tenpo
)
where yosan = 0
and exists (
select g_yosan.yosan
from tenpo_m
inner join gyoumu on tenpo_m.kbn = gyoumu.kbn
inner join g_yosan on gyoumu.yosan_g = g_yosan.yosan_g
where target.tenpo = tenpo_m.tenpo
);

--INSERT
insert into yosan_t target
select tenpo_m.tenpo,g_yosan.yosan
from tenpo_m
inner join gyoumu on tenpo_m.kbn = gyoumu.kbn
inner join g_yosan on gyoumu.yosan_g = g_yosan.yosan_g
where not exists (
select *
from yosan_t
where yosan_t.tenpo = tenpo_m.tenpo);

こんな感じでいけると思いますがどうでしょう?
先ほども書きましたがoracle10g XE での確認なので9iでは上手くいかない所があるかもしれません。
    • good
    • 0

create table yosan_T as


select 'A店' tenpo, 5000 yosan from dual
union all select 'C店' tenpo, 0 yosan from dual
union all select 'D店' tenpo, 3500 yosan from dual;

create table tenpo_m as
select 'A店' tenpo, '00001' code, '001' kbn from dual
union all select 'B店' tenpo, '00002' code, '001' kbn from dual
union all select 'C店' tenpo, '00003' code, '003' kbn from dual
union all select 'D店' tenpo, '00004' code, '003' kbn from dual
union all select 'F店' tenpo, '00030' code, '002' kbn from dual;

create table gyoumu as
select '001' kbn, 'A' yosan_g from dual
union all select '002' kbn, 'A' yosan_g from dual
union all select '003' kbn, 'B' yosan_g from dual
union all select '004' kbn, 'C' yosan_g from dual;

create table g_yosan as
select 'A' yosan_g, 10000 yosan from dual
union all select 'B' yosan_g, 5000 yosan from dual
union all select 'C' yosan_g, 5000 yosan from dual
union all select 'D' yosan_g, 3000 yosan from dual;

select * from yosan_t order by tenpo;

merge into yosan_t target
using (
select tenpo_m.tenpo,g_yosan.yosan
from tenpo_m
inner join gyoumu on tenpo_m.kbn = gyoumu.kbn
inner join g_yosan on gyoumu.yosan_g = g_yosan.yosan_g
) src
on (target.tenpo = src.tenpo)
when matched then
update set yosan = case when target.yosan = 0 then src.yosan else target.yosan end
when not matched then
insert (tenpo, yosan) values (src.tenpo, src.yosan);

select * from yosan_t order by tenpo;

MERGE文を使えばいいと思います。oracle9iの環境がないのでoracle10g XEでの動作確認です。
丸投げはよくないと思いますけどね・・・というか全然複雑じゃないですし。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す