2011-08-04 7 views
22

UPDATE에서 작동하도록 하위 쿼리를 선택하는 데 문제가 있습니다. 나는 다음과 같은 일을 시도하고있다 : foo가 기본 키 fooID와 테이블 이름입니다WHERE SELECT 하위 쿼리 오류가있는 MYSQL 업데이트

UPDATE foo 
    SET bar=bar-1 
WHERE baz= 
     (
     SELECT baz 
     FROM foo 
     WHERE fooID='1' 
    ) 

. barbaz은 INT 유형입니다. 이 작업을 실행할 때 나는 다음과 같은 오류가 발생합니다 :

Error: A query failed. You can't specify target table 'foo' for update 
in FROM clause 
+0

가능한 중복 [SQL 삭제 : FROM 절에 업데이트를 목표 테이블을 지정할 수 없습니다 (http://stackoverflow.com/questions/45494/sql-delete-cant-specify-target- table-for-update-from-clause) – ajreal

+0

http://stackoverflow.com/search?q=specify+target+table – ajreal

답변

47

을 도움이 될 것입니다 web article는 "이 오류의 원인은 MySQL의이 업데이트를 허용하지 않는다는 것입니다 당신이 업데이트 기준으로 내부 선택에서 같은 테이블을 사용하고있을 때 " 이 기사에서는 임시 테이블을 사용하는 솔루션을 제공합니다.

이 예제를 사용하여 업데이트는이 있어야한다 : 당신은 또한 MySQL의 변수를 활용할 수있는 몇 가지 경우에

update foo 
set bar = bar - 1 
where baz in 
(
    select baz from 
    (
    select baz 
    from foo 
    where fooID = '1' 
) as arbitraryTableName 
) 
+0

이것은 그것을했다! :) 고마워요! – Erik

+1

하지만 나는 이것이 더 깨끗하게 지원되지 않는다는 것에 놀랐다 ... – Erik

+0

나는 기회를 얻 자마자 이것을 다시 방문 할 것이지만, 나는 그곳에 버릴 것이라고 생각했다. OP의 오류를 해결하는 더 깔끔한 방법은 * 모든 * subselects를 사용하지 말고 UPDATE 쿼리에서 foo를 대신 사용하십시오. 여기에 중첩 된 SELECT 문이 작동하며, 나는 당신의 답을보고 나서 항상이 상황에서 사용한 해결책이지만, 꽤 해킹이됩니다. JOIN이 작동하면 '올바른'해결책이라고 느껴집니다. –

4

때문에 오류 1093 오류 1093 (ER_UPDATE_TABLE_USED) SQLSTATE = HY000의. 해결 방법은 임시 테이블을 만드는 것입니다. 테이블을 업데이트 할 때

CREATE TEMPORARY table foo_bak (SELECT baz from foo WHERE fooID='1'); 

UPDATE foo 
    SET foo.bar=foo.bar-1 
WHERE foo.baz = 
    (
    SELECT baz 
    FROM foo_bak 
); 

DROP TABLE foo_bak; 
+0

네,하지만 운명은 다 지정했는데 같은 것을 사용할 수없는 것처럼 보입니다. 하위 쿼리에서 테이블 ... 나는 약간 바보를 찾습니다. – Erik

+0

예, 올바르게 기억하면 PostgreSQL이 허용합니다. Dwb의 솔루션은 훨씬 깨끗합니다. – ace

+0

그것은 나를 위해 MySQL 5.6을 사용하여 작동합니다! 좋은 대답! –

0

지금까지 내가 아는 한, MySQL은 안전한 갱신을하기 위해 그것을 잠급니다. 데이터를 선택하고 같은 테이블을 업데이트 할 수 없습니다.

그 텍스트는 당신에게

+0

하지만 상관 관계가없는 하위 쿼리는 아닌가요? (즉, 내부 질의가 먼저 실행되고, 외부 질의가 실행 됨) ... 이것은 실행할 수있는 매우 유용한 질의이며, 허용되지 않는 이상한 것처럼 보입니다. : ( – Erik

0

합니다. 예 :

SET @id1 = (SELECT id FROM foo WHERE name = 'parent'); 
UPDATE foo SET parent_id = @id1 WHERE name = 'emails';