안전 모드에서 mysql 삭제


94

테이블 강사가 있고 급여가 일정 범위에있는 레코드를 삭제하고 싶습니다. 직관적 인 방법은 다음과 같습니다.

delete from instructor where salary between 13000 and 15000;

하지만 안전 모드에서는 기본 키 (ID)를 제공하지 않으면 레코드를 삭제할 수 없습니다.

그래서 다음 SQL을 작성합니다.

delete from instructor where ID in (select ID from instructor where salary between 13000 and 15000);

그러나 오류가 있습니다.

You can't specify target table 'instructor' for update in FROM clause

내가 쓸 때 혼란스러워

select * from instructor where ID in (select ID from instructor where salary between 13000 and 15000);

오류가 발생하지 않습니다.

내 질문은 :

  1. 이 오류 메시지는 실제로 무엇을 의미하며 코드가 잘못된 이유는 무엇입니까?
  2. 이 코드를 안전 모드에서 작동하도록 다시 작성하는 방법은 무엇입니까?

감사!


안전 모드를 사용하고 싶습니까? mySql 워크 벤치를 사용하고 있습니까?
— 글쓰기

두 질문에 대한 답은 모두 '예'입니다. 그리고 jdbc를 사용하여 PK없이 mysql 데이터베이스의 레코드를 삭제할 때 오류가 발생하지 않는다는 사실에 놀랐습니다. 그래서 안전 모드는 mysql 워크 벤치 전용입니까?
— roland luo

1
아니요-mySQL 워크 벤치에서이 기능을 끄고 싶다면 어떻게해야하는지 물어 봤습니다. 개인적으로 저는 그것으로 작업합니다 ... ID를 가지고 있어야하는 것은 안전에 매우 현명합니다.하지만 개발 측면에서는 그것이 고통
— 스러움

답변:


235

인터넷 검색을하면 인기있는 대답은 "안전 모드를 끄십시오"입니다 .

SET SQL_SAFE_UPDATES = 0;
DELETE FROM instructor WHERE salary BETWEEN 13000 AND 15000;
SET SQL_SAFE_UPDATES = 1;

솔직히 말하면 안전 모드로 달리는 습관을 들였다고 말할 수 없습니다. 그래도 문제가 발생할 때마다 데이터베이스 구성을 변경해야한다고 가정하기 때문에이 답변에 전적으로 익숙하지 않습니다.

따라서 두 번째 쿼리가 표시에 더 가깝지만 또 다른 문제가 발생합니다. MySQL은 하위 쿼리에 몇 가지 제한을 적용하고 그중 하나는 하위 쿼리에서 테이블을 선택하는 동안 테이블을 수정할 수 없다는 것입니다.

MySQL 매뉴얼, Restrictions on Subqueries 에서 인용 :

일반적으로 테이블을 수정하고 하위 쿼리의 동일한 테이블에서 선택할 수 없습니다. 예를 들어,이 제한은 다음 형식의 문에 적용됩니다.

DELETE FROM t WHERE ... (SELECT ... FROM t ...);
UPDATE t ... WHERE col = (SELECT ... FROM t ...);
{INSERT|REPLACE} INTO t (SELECT ... FROM t ...);

예외 : FROM 절에서 수정 된 테이블에 대한 하위 쿼리를 사용하는 경우 앞의 금지 사항이 적용되지 않습니다. 예:

UPDATE t ... WHERE col = (SELECT * FROM (SELECT ... FROM t...) AS _t ...);

여기서 FROM 절의 하위 쿼리 결과는 임시 테이블로 저장되므로 t에 대한 업데이트가 수행 될 때 t의 관련 행이 이미 선택되었습니다.

그 마지막 부분이 답입니다. 임시 테이블에서 대상 ID를 선택한 다음 해당 테이블의 ID를 참조하여 삭제합니다.

DELETE FROM instructor WHERE id IN (
  SELECT temp.id FROM (
    SELECT id FROM instructor WHERE salary BETWEEN 13000 AND 15000
  ) AS temp
);

SQLFiddle 데모 .


6
설명해 주셔서 감사합니다! 그러나 mysql 워크 벤치에서 코드를 시도했지만 여전히 "안전 업데이트 모드를 사용하고 있으며 KEY 열을 사용하는 WHERE없이 테이블을 업데이트하려고했습니다"라고 말했습니다.
— roland luo

그것은 예상치 못한 일입니다. 기본 키가 다른 이름으로되어 있습니까? 귀하의 질문은 이름이임을 나타내는 것으로 보이지만 ID내 대답은 id.
— rutter 2014

예, ID로 변경했는데 작동하지 않습니다. ID = '1'인 강사에서 삭제를 시도했는데 ID가 기본 키가되도록 작동합니다
— roland luo

1
@rolandluo 오랜 시간이 지났다는 것을 알고 있지만 해결 방법을 알아 낸 적이 있는지 궁금합니다. 분명히이 방법은 다른 상황에서도 효과가 있었으므로 귀하의 사례가 다른 이유가 궁금합니다. 서버 또는 버전에 특정한 것이 있습니까?
— rutter 2015-04-17

19

MySQL을 속여 실제로 기본 키 열을 지정하고 있다고 생각할 수 있습니다. 이를 통해 안전 모드를 "무시"할 수 있습니다.

자동 증가 숫자 기본 키가있는 테이블이 있다고 가정하면 다음을 수행 할 수 있습니다.

DELETE FROM tbl WHERE id <> 0

12

Mysql Workbench 6.3.4.0에서 안전 모드 끄기

편집 메뉴 => 기본 설정 => SQL 편집기 : 기타 섹션 : "안전한 업데이트"를 클릭하십시오 ... 옵션을 선택 해제하려면

워크 벤치 환경 설정


2
" 안전 모드에서 작동하도록이 코드를 다시 작성하는 방법은 무엇입니까?" ==> 당신의 대답은 어떻게 해제 안전 모드로 알려줍니다)
— ByteHamster

2
죄송합니다. 질문을 완전히 오해했습니다. 이 주제는 Mysql Workbench로 테이블에서 삭제할 수 없었고 mysql Workbench로 주석에 비슷한 질문이 있었지만 주석을 만들 수 없을 때 발견되었습니다. 나중에 참조 할 수 있도록 여기에 적어
— Peter B

0

나는 훨씬 더 간단한 해결책을 가지고 있으며 그것은 나를 위해 일하고 있습니다. 또한 해결 방법이지만 사용할 수 있으며 설정을 변경할 필요가 없습니다. 절대 존재하지 않는 값을 사용할 수 있다고 가정하고 WHERE 절에서 사용합니다.

MyField IS_NOT_EQUAL AnyValueNoItemOnMyFieldWillEverHave에서 MyTable에서 삭제

나는 그 해결책을 너무 좋아하지 않기 때문에 내가 여기에있는 이유이지만 작동하며 대답 된 것보다 더 좋아 보입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.