Oracle SQL DELETE文のレスポンス

このQ&Aのポイント
  • 手前のSQL文においてDELETE文のレスポンスが上がらずに難儀しています。
  • DELETE処理はバッチにて行っていますが、SELECTでは1秒程度で済んだ処理がDELETE文ではレスポンスが返ってこないという状況です。
  • DELETE文の条件はBテーブルに存在するものを削除対象外とし、AテーブルのアイテムIDとCテーブルのアイテムIDが一致し、AテーブルのCREATEDATEとCテーブルのREPYMDが3ヶ月以内のアイテムを削除対象外としています。
回答を見る
  • ベストアンサー

Oracle SQL DELETE文のレスポンス

いつもお世話になっております。 この度は、手前のSQL文において DELETE文のレスポンスが上がらずに難儀しています。 現在DELETE処理はバッチにて行っています。 最初にSELECTにて抽出を行ったものをバックアップにとり、 次は同様の条件でDELETE文で処理しています。 この際に、SELECTでは1秒程度で済んだ処理が、 DELETE文ではレスポンスが返ってこないという状況です。 何がまずいのか、どう工夫すればいいのか 色々変えてみましたがレスポンスは改善されません。 SQLと条件は以下です。 【SQL文】 SELECT 複数の項目 FROM TABLEA A WHERE NOT Exists(SELECT 'X' FROM TABLEB B WHERE A.ITEMNO = B.ITEMNO) AND NOT Exists(SELECT 'X' FROM TABLEC C WHERE A.ITEMNO = C.ITEMNO AND to_char(LAST_DAY(ADD_MONTHS(SYSDATE,-4)),'YYYYMMDD') < C.REPYMD) AND NOT Exists (SELECT 'X' FROM TABLEA2 A2 WHERE A.ITEMNO = A2.ITEMNO AND to_char(LAST_DAY(ADD_MONTHS(SYSDATE,-4)),'YYYYMMDD') < to_char(A2.CREATEDATE,'YYYYMMDD')) AND NOT Exists(SELECT 'X' FROM TABLEC C WHERE A.ITEMNO != C.ITEMNO AND to_char(LAST_DAY(ADD_MONTHS(SYSDATE,-4)),'YYYYMMDD') < to_char(A.CREATEDATE,'YYYYMMDD')) 上記のSELECT文の後に処理されるDELETE文は 「SELECT 複数の項目 FROM TABLEA A」 ⇒ DELETE FROM TABLEA A としたもので、 条件は全てSELECT文と同様のものを使用しています。 ◆条件を言葉で明記すると以下のようになります。 1.Bテーブルに存在するものは削除対象外とする 2.AテーブルのアイテムIDとCテーブルのアイテムIDは一致する。   AテーブルのCREATEDATEとCテーブルのREPYMDのいずれかが3ヶ月以内のアイテムは   削除対象外とする 3.AテーブルもしくはCテーブルにしか存在しない場合は、各日付が3ヶ月以内のアイテムは   削除対象外とする 以上のようになっています。 どなたかアドバイスをいただければ幸いです。 宜しくお願い致します。

  • Oracle
  • 回答数1
  • ありがとう数2

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

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

各テーブルの件数、主キー、索引の有無、SELECT文の実行計画がわからないのでなんとも言えませんが、何らかの理由でSELECTとDELETEで異なる実行計画が採用されている可能性があります。 もし、tableaに主キーがあるなら、そのデータを抽出し、IN句を使ってDELETEを実行してみてください。

axelchk
質問者

お礼

ご回答いただきまして、ありがとうございます。 自己解決ができました。 Exists中の'X'をROWIDで抽出するように変更したところ、 レスポンスが返ってくるようになりました。 速度も上々です。 主キーはアイテムNOや年月日でしたが、 インデックスは覚えていませんが、 その実行計画は異なっていたのかもしれませんね。 SELECT文とDELETE文は条件をあわせないといけないという 制約がありましたので条件を変更できずの苦労でした。 お手数おかけしました。

関連するQ&A

  • SQL : たしかに DELETE したの?

    ありがちな処理かと思いまして質問させていただきます。 SQLで DELETE を行う際、WHERE で絞り込んだ対象行がなくても、  「エラーは返ってこない」 ということですが、NOT FOUND判定はするのでしょうか。 ごく単純に、削除しようとしたデータが実際にあったのかを確認したいのです。 やろうとしている処理は、次のようなものです。 DELETE FROM a_tbl WHERE NOT EXISTS (SELECT row1 FROM b_tbl WHERE row1 = 'input_data' ) AND NOT EXISTS (SELECT row1 FROM c_tbl WHERE row1 = 'input_data' ); ようするに、他のテーブルに、すでにない行であることが前提で、 a_tbl から DELETE したことを確認したいのです。 Pro*C内で実行するのですが、一般に同じだと思います。 キホンのキかもしれませんが、よろしくお教えください。

  • オラクルSQLについて

    初心者です。困っています。 テーブルC 日付_番号_ステータス 1/3____1_____Q 1/5____2_____R 1/6____5_____G 1/7____7_____P 1/20__ 9_____R 2/1___10_____R このようなテーブルを、1.日付順、2.番号順の優先順位で、選択していく為、下記のようなSQLを作成しました。 SELECT 番号 FROM テーブルC WHERE (TO_CHAR([日付],'yyyyMMdd') || [番号]) IN (select MIN((TO_CHAR([日付],'yyyyMMdd') || [番号])) FROM テーブルC WHERE (TO_CHAR([日付],'yyyyMMdd') || [番号]) > (SELECT (TO_CHAR([日付],'yyyyMMdd') || [番号]) FROM テーブルC WHERE [番号]=前回編集した番号)) ユニークなのは番号だけです。 これに、ステータス が RかPの場合 を加えたいだけなのですが、SQLが多くなりすぎて、困難になってしまいました・・・。 どなたかご教授頂ければ幸いです。

  • PL/SQLのDELETE文について

    PL/SQLでDELETE文を書こうとしているのですが、 文法がわかりません。。。 分かる方がおられましたら、教えてくださいm(_ _)m 今、TABLE1を削除したいのですが、条件がいろいろあって、 以下のように書いてみたのですがダメでした。 こういう書き方は、できないんでしょうか・・・。 削除条件は、TABLE2に存在し、かつ、TABLE2のTENSUが0のもので、 TABLE3が存在しないものです。 DELETE TABLE1 FROM TABLE1 ,TABLE2 ,TABLE3 WHERE TABLE1.ID = TABLE2.ID AND TABLE2.TENSU = 0 AND Not Exists (SELECT TABLE3.ID FROM TABLE3 WHERE TABLE3.ID = TABLE2.ID) 説明が下手なので、うまく、伝わっているか、心配なのですが・・・、 よろしくお願いします。

  • DELETE 文とEXISTSの使い方について(Oracle10g)

    DELETE 文とEXISTSの使い方について(Oracle10g) 2つのテーブル(A、B)を外部結合して、B側がNULLとなったレコードを A側から削除する、というDELETE文が作りたいのですが、 EXISTS句を使ってみたもののどうも使い方がわからず苦戦しています。 目的は2つのテーブルを同期させる事で このSQLを実行する時点で、常にA>Bになっています。 目的を達成できるSQLを教えてください。 <削除対象レコードをSELECTするSQL> SELECT * FROM A, B WHERE A.KEY1 = B.KEY1(+) AND A.KEY2 = B.KEY2(+) AND B.KEY1 IS NULL ; <上をDELETE文にしてみたつもりが、削除0件になってしまうSQL> DELETE FROM A WHERE EXISTS( SELECT 1 FROM B WHERE A.KEY1 = B.KEY1(+) AND A.KEY2 = B.KEY2(+) AND B.KEY1 IS NULL ) ;

  • DELETE文とロックについて

    DELETEしようとしているレコードがロックされている場合は、削除せず すぐに処理を戻したいです。イメージ的にNOWAITが最適と思い →DELETE FROM テーブルA WHERE カラムA = 'A' NOWAIT としたいところですが、NOWAITはSELECT文でしか指定できないとのことなのでNGです。 SELECT文で抽出した条件のレコードを削除する場合 →DELETE FROM テーブルA WHERE カラムA =      (SELECT カラムA FROM テーブルA WHERE カラムA = 'A') と出来ます。 又、SELECT文でロック待機時間なしの場合 →SELECT カラムA FROM テーブルA WHERE カラムA = 'A' FOR UPDATE NOWAIT と出来ます。 これらを組み合わせて、ロックされているレコードを削除しようとした場合、 すぐにNGで制御を戻すように、次のように記載してみました。 →DELETE FROM テーブルA WHERE カラムA =    (SELECT カラムA FROM テーブルA WHERE カラムA = 'A' FOR UPDATE NOWAIT) なぜかNGになってしまいます(右カッコがありませんと言われます)。 なぜこの書き方が出来ないのでしょうか? 現在、一度該当のレコードをSELECT文でFOR UPDATE NOWAITをしてから DELETEをしています。 1つレコードを削除したいだけなのに、わざわざSELECT文と DELETE文を発行してしまっています。 こういう場合、他にどのような方法があるのでしょうか? 宜しくお願いします。

  • Oracle データベース SQL

    質問させてください。 SQLについて教えてください。 SELECT文を作っていて、WHERE句で データを追加した日の指定(INSERT_DATE)を本日、というのをしたいと思っているのですが、なかなかできません。 格納するデータ型は、CHAR型なので WHERE INSERT_DATE =  TO_CHAR(SYSDATE, 'YYYYMMDD') で、試したのですができません…。 SQL実行はするのですが、該当なしになります。 教えていただければ、助かります。

  • EXISTSを使ったDELETE文

    「SELECT文の件数」と、 「同じSELECT文を使ったDELETE文の件数」が一致しない現象が起き、困っています。 【SELECT文】※2件返ってきます。 SELECT   a.部署コード,   a.社員コード FROM   社員マスタ a,   組織マスタ b WHERE   a.部署コード = b.部署コード 【DELETE文】※50件 DELETEされます。 DELETE TABLE   社員マスタ WHERE   EXISTS   (   SELECT     a.部署コード,     a.社員コード   FROM     社員マスタ a,     組織マスタ b   WHERE     a.部署コード = b.部署コード   ) 環境はSQLSERVER2005です。 件数はSQLSERVER2005のカウントオプションで表示されているものなので間違いないです。 宜しくお願いします。

  • PLSQLで条件によりSQLを動的に変えたい

    例えば、あらかじめテーブルなどを読み、その内容により、 SQLの文そのものを非常に変えたいとします。 SQLその1 select * from TABLEA where A = 1 SQLその2 select * from TABLEA where A = 1 and B = 2 and C = 3 and D = 4 上記は例ですが、内容などにより複雑な条件式を追加したい。 ベースのSQLは非常に長い為、 例えば 完全に切り分けるのでは無く、共通の部分は共通ソースとしたい。 また、プリプロセッサみたいに、条件式が追加された場合 あたかも、初めからそのSQLのみがあり、他の制御文などをSQL文自身には追加したくない。 動的SQLでは無い方法でそのような事が可能でしょうか? ----- イメージ ----- select * from TABLEA where A = 1 IF (条件がある時のみ) B = 2 and C = 3 and D = 4 END IF; ------------------- 実際には、SQL文の中にPLSQLの制御文をうまく追加できない。

  • Oracle delete文について

    お世話になります。 Oracle初心者です。 delete文の条件で他テーブルの列の値(列名は両方テーブルとも同じ) と同じ所の行を削除したいと思っているのですが、 コンパイルエラーになります。 基本的な書き方が悪いのでしょうか。 どなたかご親切な方、御教示頂きたく宜しくお願い致します。        記 delete from ( select 受注NO from T受注明細 where T受注明細.受注NO = D売上.受注NO)

  • oracle9i 日付データに関して

    お世話になっております。 Oracle9i(9.0.1.0.1) Linux RedHat7.3J JDBC 接続でOracle Type4 ドライバを使用しています。 本日の日付は2003/09/10で、sysdateも2003/09/10です。 この環境で、以下のSQL文を発行すると、 0件が返ってきます。 select count(*) from dual where '20030910' >= sysdate 以下の条件だと1件返ってきます。 select count(*) from dual where '20030911' >= sysdate さらに、sysdateにフォーマットを指定すると select count(*) from dual where '20030910' >= to_char(sysdate,'yyyymmdd') 1件返ってきます。 質問は、sysdateにto_charのフォーマットを指定した場合と 指定しなかった場合との違いについて教えていただきたいのと、 その違いが明文化されているサイトやotnドキュメントが ありましたら教えていただきたいのです。 otnドキュメントの日付データのところを読んだのですが 詳しい事はわかりませんでした。 宜しくお願いいたします。