2011-08-04 18 views
22

Tengo un problema con la obtención de subconsultas seleccionadas para trabajar en un UPDATE. Estoy intentando algo como lo siguiente:Actualización de MYSQL con WHERE SELECT error de subconsulta

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

Dónde foo es el nombre de la tabla con clave primaria fooID. bar y baz son de tipo INT. Cuando se ejecuta esta me sale el siguiente error:

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

posible duplicado de [SQL Eliminar: no se puede especificar tabla de destino para la actualización de cláusula] (http://stackoverflow.com/questions/45494/sql-delete-cant-specify-target- table-for-update-in-from-clause) – ajreal

+0

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

Respuesta

47

A partir de aquí: web article "La razón de este error es que MySQL no permite cambios a una tabla cuando también está utilizando esa misma tabla en una selección interna como sus criterios de actualización ". El artículo continúa para proporcionar una solución, que es usar una tabla temporal.

Usando este ejemplo, su actualización debe ser la siguiente:

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

Esto lo hizo! :) Muchas gracias !! – Erik

+1

Pero debo decir, estoy sorprendido de que esto no se admite más limpiamente ... – Erik

+0

Voy a volver a visitar esto tan pronto como tenga la oportunidad, pero solo una idea no probada que pensé que arrojaría allí: wouldn ¿Una forma más limpia de evitar el error del PO es no usar las subselecciones * any * y, en su lugar, UNIRSE a foo consigo mismo en la consulta de ACTUALIZACIÓN? Las instrucciones SELECT anidadas aquí funcionan, y son la solución que siempre he usado para esta situación desde que vi su respuesta, pero son bastante extravagantes; si el JOIN funciona, se siente como la solución "correcta". –

4

debido a un error 1093 error 1093 (ER_UPDATE_TABLE_USED) SQLSTATE = HY000. La solución alternativa es crear una tabla temporal.

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

Sí, traté de nombrar todo, pero no tuve suerte ... parece que no puedes usar el mismo tabla en la subconsulta ... que me parece un poco tonto. – Erik

+0

Sí, si no recuerdo mal, PostgreSQL lo permite. La solución de Dwb es mucho más limpia. – ace

+0

¡Funciona para mí usando mysql 5.6! ¡Gran respuesta! –

0

Por lo que sé, al actualizar una tabla, Mysql la bloquea para realizar una actualización segura. No puede seleccionar datos y actualizar la misma tabla mientras intenta.

Estos textos deben ayudarle a

+0

¿Pero no se supone que las consultas secundarias no están correlacionadas? (es decir, la consulta interna se ejecuta primero, la consulta externa se ejecuta después) ... Esta es una consulta muy útil para poder ejecutar, parece extraño que no se permita. :( – Erik

0

En algunos casos, también puede tomar ventaja de la variable de MySQL. por ejemplo:

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