DELETE文とロックについて

このQ&Aのポイント
  • DELETE文で削除しようとしているレコードがロックされている場合、即座に処理を終了させたいですが、NOWAITは使用できません。
  • SELECT文で抽出した条件のレコードをDELETE文で削除することができます。
  • SELECT文でロック待機時間を設定せずにレコードを取得することができます。
回答を見る
  • ベストアンサー

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
  • 回答数1
  • ありがとう数2

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

  • ベストアンサー
回答No.1

>なぜかNGになってしまいます(右カッコがありませんと言われます)。 >なぜこの書き方が出来ないのでしょうか? できない。 右カッコ云々のエラーは、サブクエリ上であり得ない問い合わせを書くと よく出るモノです。 ロックが獲得できるかどうかで、削除するかどうかが変わるわけで、 削除するかどうか決まっていない時点で、DELETE文の発行は出来ない、 という考え方も出来ますよね.. 条件付き削除として考えれば、SELECT&DELETEは面倒な 書き方ではありますが。

pokopen18
質問者

お礼

回答ありがとうございます。 >ロックが獲得できるかどうかで、削除するかどうかが変わるわけで、 >削除するかどうか決まっていない時点で、DELETE文の発行は出来ない、 >という考え方も出来ますよね.. なるほど。 >条件付き削除として考えれば、SELECT&DELETEは面倒な >書き方ではありますが。 こういう書き方は普通に使われているのですね。 ありがとうございました。

関連するQ&A

  • 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 ) ;

  • 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のカウントオプションで表示されているものなので間違いないです。 宜しくお願いします。

  • 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ヶ月以内のアイテムは   削除対象外とする 以上のようになっています。 どなたかアドバイスをいただければ幸いです。 宜しくお願い致します。

  • SQLServerでのロックについて

    SQLServerであるテーブルを行ロックしています。 (select * from テーブルA with (UPDLOCK) where KEYCD = 1) 行ロック実行時に、他のマシンが既にロックしていた場合、それをエラーとして返す方法はありますでしょうか? (Oracleでいう"nowait"のようなもの) 最近SQLServerをやりはじめたばかりの超初心者です。 よろしくお願いします(T_T)

  • このようなDELETEはできますか?

    こんにちは。DELETE文の削除条件について教えてください。 例えば下記のような2つのテーブルがあったとします。 ATABLE KEY1(ID) KEY2(DATE) ・・・・・・・・・・ ------------------------------------------------ 100000 2004/09/01 ・・・・・・・・・・ 200000 2004/09/01 ・・・・・・・・・・ 300000 2004/09/01 ・・・・・・・・・・ BTABLE KEY1(ID) KEY2(DATE) CODE ・・・・・・・・・・ ------------------------------------------------ 100000 2004/09/01 0 ・・・・・・・・・・ 200000 2004/09/01 0 ・・・・・・・・・・ 300000 2004/09/01 1 ・・・・・・・・・・ この2つのテーブルで、BTABLEのCODEが1のレコードにKEYで関連付くATABLEのレコードを削除したいのです。 プログラムの中では対応できるのですが、SQL1文で実行させることはできるでしょうか? とりあえず下記のように作ってみました(いたずらに長いかもしれませんが)。 DELETE FROM ATABLE WHERE KEY1 IN (SELECT ATABLE.KEY1 FROM ATABLE,BTABLE WHERE ATABLE.KEY1 = BTABLE.KEY1 AND ATABLE.KEY2 = BTABLE.KEY2 AND BTABLE.CODE = 1) AND KEY2 IN (SELECT ATABLE.KEY2 FROM ATABLE,BTABLE WHERE ATABLE.KEY1 = BTABLE.KEY1 AND ATABLE.KEY2 = BTABLE.KEY2 AND BTABLE.CODE = 1) これで良い/悪い、もっと簡潔にできる、などありましたら是非お聞かせ願えますでしょうか? よろしくお願いします。

  • 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) 説明が下手なので、うまく、伝わっているか、心配なのですが・・・、 よろしくお願いします。

  • mysql のテーブルロックについて

    Mysqlにてテーブルをロックしようとして以下2つの方法を試し疑問に思ったので質問します。 1.select for update によるテーブルロック 以下のselect for update(where句にレコードを一意に特定できない条件を指定) をコマンドライン で実行。 select * from test where test_state=0 for update; 別に起動したコマンドラインから下記アップデート文を実行したところ ロックされることが確認できました。 update test set test_official=0 where test_id = 1; しかし、最初に実行した select for update 文を下記のようにしたところ上記update文はロックされず に実行されてしまいました。 select * from test where test_state is null for update; これはなぜでしょうか。

    • ベストアンサー
    • MySQL
  • Oracle delete文について

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

  • 【sqlite3】deleteしても.dbファイルのサイズは減らない?

    DB及びSQLに詳しい方、教えてください。 sqliete3を使ってます。 insertしたレコードをdeleteしても.dbファイルのサイズは小さくならない 様なので、テーブルのカラムに削除フラグを設けて、削除はdeleteコマン ドでレコードを削除する代わりに、フラグのupdateとし、 レコード挿入の場合は、フラグが立ってるレコードを見つけて、そのコー ドを更新(フラグが立ってるレコードが無い場合はinsert)とする仕様に してみようかと考えてます。 もちろんselect時は、フラグの立ってるレコードをwhere句で除外するつも りです。 そこで、質問なのですが、フラグの立ってるレコードを一つselectして該 当レコードをupdateするには、どのようなSQLになるでしょうか? フラグが立つレコードは複数もしくは無い事が考えられるので、例えば、 update table01 set col = 'hogehoge' where flag = 1; では上手く機能しないと考えます。 複数レコードが選択された場合は、任意のレコードを選んで更新、また、 レコードが一つも選択されなかった場合の条件判定(後のinnsert)は、 どのように記述したらよいのでしょうか? ※そもそも、そんな事しなくても他にもっと良い方法があるよ。  といった場合は、その方法を伝授してください。 それでは、ご指導のほど、宜しくお願いいたします。

  • SQL文 この部分はなんていうのでしょう?

    SELECT T_テーブル1.フィールド1 FROM T_テーブル1 ORDER BY T_テーブル1.フィールド1; なら、 ”ORDER BY句” SELECT T_テーブル1.フィールド1 FROM T_テーブル1 WHERE (((T_テーブル1.フィールド1)="A")); なら ”WHERE句” と言いますが、 DELETE Table1.* FROM Table1; や UPDATE テーブル1 Set テーブル1.フィールド1 = "い" WHERE (((テーブル1.フィールド1)=”あ")); や DROP Table Table1; の deleteやupdateやdropの部分は何て言うのでしょうか? そのまま、SELECT句DELETE句などというのでしょうか?