안전 모드에서 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.