OracleでのデータバックアップをSQLにて作成しようとしています。
【処理内容】
売上テーブル(URITBL)から売上累積テーブル(URIRUITBL)へ
※売上年月がシステム日付より12カ月以上前(2010年8月以前) AND 領収済みのものを
売上テーブルから売上累積テーブルへ追加し、
売上テーブルにあったデータは削除する
売上明細テーブル(URIMTBL)と売上明細累積テーブル(URIRUIMTBL)へ
※売上年月システム日付より12カ月以上前(2010年8月以前) AND 領収済みのものを
売上明細テーブルから売上明細累積テーブルへ追加し、
売上明細テーブルにあったデータは削除する
【テーブル内容】
売上テーブル(URITBL)更新前
支店CD、顧客NO、売上年月、氏名、TEL、領収済フラグ(※領収済…'1'、領収未…SPACEです)
STNCOD、KKKNO、URIYM、NAME、TEL、RYOFLG
001 000012 201006 A田太郎 123-1234 1
001 000012 201007 A田太郎 123-1234
001 000012 201008 A田太郎 123-1234 1
001 000012 201009 A田太郎 123-1234 1
001 000012 201010 A田太郎 123-1234 1
002 000101 201006 B田二郎 345-5678
002 000101 201007 B田二郎 345-5678 1
002 000101 201008 B田二郎 345-5678 1
002 000101 201009 B田二郎 345-5678
002 000101 201010 B田二郎 345-5678 1
売上明細テーブル(URIMTBL)更新前
支店CD、顧客NO、売上年月、売上金額
STNCOD、KKKNO、URIYM、URIKIN
001 000012 201006 1,000
001 000012 201007 2,000
001 000012 201008 3,000
001 000012 201009 4,000
001 000012 201010 5,000
002 000101 201006 500
002 000101 201007 1,500
002 000101 201008 2,500
002 000101 201009 3,500
002 000101 201010 4,500
売上テーブル(URITBL)更新後
支店CD、顧客NO、売上年月、氏名、TEL、領収済フラグ
STNCOD、KKKNO、URIYM、NAME、TEL、RYOFLG
001 000012 201007 A田太郎 123-1234
001 000012 201009 A田太郎 123-1234 1
001 000012 201010 A田太郎 123-1234 1
002 000101 201006 B田二郎 345-5678
002 000101 201009 B田二郎 345-5678
002 000101 201010 B田二郎 345-5678 1
売上明細テーブル(URIMTBL)更新後
支店CD、顧客NO、売上年月、売上金額
STNCOD、KKKNO、URIYM、URIKIN
001 000012 201007 2,000
001 000012 201009 4,000
001 000012 201010 5,000
002 000101 201006 500
002 000101 201009 3,500
002 000101 201010 4,500
売上累積テーブル(URIMTBL)更新後
支店CD、顧客NO、売上年月、氏名、TEL、領収済フラグ
STNCOD、KKKNO、URIYM、NAME、TEL、RYOFLG
001 000012 201006 A田太郎 123-1234 1
001 000012 201008 A田太郎 123-1234 1
002 000101 201007 B田二郎 345-5678 1
002 000101 201008 B田二郎 345-5678 1
売上明細累積テーブル(URIMRUITBL)更新後
支店CD、顧客NO、売上年月、売上金額
STNCOD、KKKNO、URIYM、URIKIN
001 000012 201006 1,000
001 000012 201008 3,000
002 000101 201007 1,500
002 000101 201008 2,500
売上テーブル(URITBL)から売上累積テーブル(URIRUITBL)へ追加のSQL、売上テーブル(URITBL)の削除のSQLは以下の2つではないかと思います。
INSERT INTO URIRUITBL SELECT * FROM URITBL WHERE RYOFLG='1' AND ( URIYM < ADD_MONTHS (SYSDATE, -12) ) ;
DELETE FROM URITBL WHERE RYOFLG=1 AND ( URIYM < ADD_MONTHS (SYSDATE, -12) ) ;
ただ、売上明細テーブル(URIMTBL)と売上明細累積テーブル(URIRUIMTBL)へ追加のSQL、売上累積テーブル(URIMTBL)の削除のSQLはどうやってコーディングしたら良いのか悩んでいます。上記と同じように作っていくので大丈夫なのか、それとも別関数を使って作っていくのか、SQLの本などを半日ほど費やして調べてるのですが、いまだ至っておりません。最悪な時は別プログラムでとも考えているのですが、納期間近でできればSQLで解決したいと思いながら苦戦しています。
以前もこちらで教えて頂いてるのでたびたびの質問で恐縮ですが、分かる方がいれば手助けして頂きたいと思い、今回投稿しますのでご教授賜りたく思います。よろしくお願いします。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
・この処理を行うのは毎月第1営業日となるため、月末日で月またがりになることはありません。
ならば、条件2は気にする必要ないですね。
・売上明細テーブルと売上明細累積テーブルのプライマリーキーは、支店CD・顧客NO・売上年月と
先ほどの質問には書かれていない売上区分の4つとなっております。
ということでしたら、
売上区分が異なるだけで、支店CD・顧客NO・売上年月が同一のレコードが複数あった場合の処理は
どうしますか?
例)
STNCOD、KKKNO、URIYM、URIKIN、URIKBN
001 000012 201007 2,000 1
001 000012 201007 100 3
STNCOD、KKKNO、URIYM、NAME、TEL、URIKBN,RYOFLG
001 000012 201007 A田太郎 123-1234 1
001 000012 201007 A田太郎 123-1234 3 1
となっていた場合、
(1)それぞれ1行目は累積へ移動して消したいが、
2行目は消したくないとするのが普通、ですかね。
(2)それとも、領収済フラグはどれか1レコードにしか入らないので、1行目にあっても
2行目にあっても、1,2行目両方累積へ移動して消したいということですか?
また、領収済フラグは、'1','2','3'の3種類とも対象にしたいのでは?
(1)の場合、
INSERT INTO URIMRUITBL SELECT * FROM URIMTBL a
WHERE ( URIYM < ADD_MONTHS (SYSDATE, -12) )
and
(select max(b.RYOFLG) from URITBL b
where a.STNCOD= b.STNCOD
and a.KKKNO = b.KKKNO
and a.URIYM = b.URIYM
and a.URIKBN = b.URIKBN)
in('1','2','3');
または、in('1','2','3')を>' '(スペース)とするなど。
※プライマリキーで一意のレコードが取得できるのでmax()は別に必要ないですが、
ま、習慣的につけていてもいいかも。
(2)の場合は、
INSERT INTO URIMRUITBL SELECT * FROM URIMTBL a
WHERE ( URIYM < ADD_MONTHS (SYSDATE, -12) )
and
(select max(b.RYOFLG) from URITBL b
where a.STNCOD= b.STNCOD
and a.KKKNO = b.KKKNO
and a.URIYM = b.URIYM)
in('1','2','3');
または、in('1','2','3')を>' '(スペース)とするなど。
※max()を使っているので、
スペースと'1'があれば、大きいほうの'1'を取得します。
プライマリキーで取得できていないのでmax()をつけていないと
複数レコードが取得されます。実行時にエラーとなります。
注:スペース、ですよね? Null(なにも入っていない状態)ではないですよね?
Null なら、>' 'ではなく、is not null とか書きます。
なお、
プライマリキーが2件以上存在する構成にはならないようにしています。
プライマリキーとはレコードを一意(ユニーク)に識別するためのキーであり
重複を許すキーはプライマリキーにならないです。
(プライマリキーという用語の意味です。念のため。)
No.1
- 回答日時:
>売上明細テーブル(URIMTBL)と売上明細累積テーブル(URIRUIMTBL)へ追加のSQL、
>売上累積テーブル(URIMTBL)の削除のSQLはどうやってコーディングしたら良いのか悩んでいます。
>上記と同じように作っていくので大丈夫なのか、
まあ、いくつかの条件に合致しなければ大丈夫です。
条件1:売上明細テーブルの処理を先に実行すること。
売上テーブル処理を先に処理してしまうと、
売上明細テーブル処理のInsert時もDelete時も、売上テーブルの領収済フラグを判定できません。
(売上累積テーブルを参照していれば問題ないですが、売上累積テーブルのほうが削除前の
売上テーブルより遥かに件数が多いなら、レスポンスが悪くなるかも。)
条件2:月末日の深夜12時をまたぐタイミングで実行しないこと
片方のテーブルの処理が終わる前に日付が変わると処理する対象の月が変わってしまい、
もう一方のテーブルと整合性がとれなくなります。
あるいは、売上明細テーブル処理時に売上テーブルの領収済フラグ判定方法がわからないということ
でしょうか?
insertもdeleteも
WHERE ( URIYM < ADD_MONTHS (SYSDATE, -12) )
and
(select max(b.RYOFLG) from URITBL b
where a.STNCOD= b.STNCOD
and a.KKKNO = b.KKKNO
and a.URIYM = b.URIYM)
='1';
を使えばいいです。
ただし、STNCOD、KKKNO、URIYMがプライマリキーになっているか、
STNCOD、KKKNO、URIYM、NAME、TEL、RYOFLG
001 000012 201007 A田太郎 123-1234
001 000012 201007 A田太郎 123-1234 1
STNCOD、KKKNO、URIYM、URIKIN
001 000012 201007 2,000
001 000012 201007 1,500
というようなデータが存在できないようになっている前提。
(あるとどうしようもないです。どう考えても、どんな方法でも無理。)
>それとも別関数を使って作っていくのか、
別の方法です。
売上テーブルの処理を先にします。
そして、以下の条件で処理をします。
WHERE
not exist (select * from URITBL b
where a.STNCOD= b.STNCOD
and a.KKKNO = b.KKKNO
and a.URIYM = b.URIYM);
これは、売上テーブルに存在しないレコードを対象に処理します。
(条件は上に同じ)
なお、どちらの方法でも、トランザクションを1つにして、commitかエラー時にrollback
しないと不整合がおきますので気をつけてください。
(別プログラムにするとトランザクションを一緒にできません。)
片方の処理が正常終了して、次の処理が異常終了すると即不整合がでます。。。
御礼が遅くなって失礼しました。
このたびは、ご丁寧に詳細な説明ありがとうございます。
ただいま社内システムの自社開発中で、今回よりSQLを初めて触れるようになったので、
本当に初歩的な構文しか理解できていない旨をご了承ください。
こちらの記載不足で申し訳ありませんが、
・この処理を行うのは毎月第1営業日となるため、月末日で月またがりになることはありません。
・売上明細テーブルと売上明細累積テーブルのプライマリーキーは、支店CD・顧客NO・売上年月と
先ほどの質問には書かれていない売上区分の4つとなっております。
売上区分は、1:通常売上代、2:通常売上消費税、3:リース売上代、4:リース売上消費税で、
プライマリキーが2件以上存在する構成にはならないようにしています。
(例)
STNCOD、KKKNO、URIYM、URIKIN、URIKBN
001 000012 201007 2,000 1
001 000012 201007 100 2
001 000012 201007 500 3
001 000012 201007 25 4
・売上テーブル・売上累積テーブルの領収済フラグの区分の持ち方は、スペース:領収未、
1:現金領収済、2:振込領収済、3:クレジット領収済 となっています。
・売上年月のデータ型はcharです。
以上のような条件となります。
この場合、max関数を使っても大丈夫なのでしょうか?
また、売上年月のデータ型がcharの場合でも大丈夫でしたでしょうか?
もし大丈夫でしたら、一応コーディングしてみたのですが、
INSERT INTO URIMRUITBL SELECT * FROM URIMTBL a
WHERE ( URIYM < ADD_MONTHS (SYSDATE, -12) )
and
(select max(b.RYOFLG) from URITBL b
where a.STNCOD= b.STNCOD
and a.KKKNO = b.KKKNO
and a.URIYM = b.URIYM)
='1';
こんな感じで良いのかな…と作ってみましたが、正直自信がありません。
大変図々しい質問内容となりましたが、
もしよろしければ自分の教養のためにも添削・アドバイスをお願いできたらと思います。
申し訳ありませんが、よろしくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「マスタ」と「テーブル」の違...
-
重複するキーから一番古い年月...
-
2つのテーブルから条件に一致...
-
連番のMin, Maxを取得したい
-
VIEWでテーブルの集計結果...
-
DB2で助けてください!
-
行方向のデータを横に並べる
-
OracleのUnion内でそれぞれのOr...
-
主キーの変更
-
データベースの正規化で、第1正...
-
ACCESS 一つのフィールドに複...
-
Accessにインポートしたら並び...
-
SELECT文でのデッドロックに対...
-
ACCESSのSQLで、NULLかNULLでな...
-
クエリのキャンセルがいつにな...
-
データの二重表示の原因
-
AccessでCSVインポートのゼロサ...
-
ACCESS2007 フォーム 「バリア...
-
3つ以上のテーブルをUNIONする...
-
SELECT時の行ロックの必要性に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「マスタ」と「テーブル」の違...
-
重複するキーから一番古い年月...
-
2つのテーブルから条件に一致...
-
ACCESS 一つのフィールドに複...
-
行方向のデータを横に並べる
-
SQL 2つのテーブルとSUBSTRING...
-
PLSQLの識別子エラー
-
Accessでフィールドを比較した...
-
主キーの変更
-
Accessユニオンクエリーで2つ...
-
請求と入金のテーブルの作成の...
-
続.ORACLEのSELECTのソートに...
-
Inner join と Left joinの明...
-
複数テーブルの不一致クエリに...
-
片方だけ抽出する方法(SQL)
-
自分自身への矢印
-
SQL文について(片方のテーブル...
-
OracleのUnion内でそれぞれのOr...
-
VIEWでテーブルの集計結果...
-
【Access】順位を付けたい
おすすめ情報