2011-08-25 9 views
9

Aislamiento el problema de una consulta mucho más compleja. Aquí el escenario de pruebaNo se puede SELECCIONAR de la cláusula UPDATE RETURNING en postgres

DROP TABLE test; 
CREATE TABLE test (
    id integer, 
    description varchar(100) 
); 

INSERT INTO test(id, description) VALUES (1,'new'); 
INSERT INTO test(id, description) VALUES (2,'new'); 

Si funciono con la pregunta:

SELECT * FROM test WHERE id IN (UPDATE test set description='test' RETURNING id) 

Estoy recibiendo el siguiente error:

ERROR: error de sintaxis en o por "prueba" cerca LÍNEA 1: SELECT * FROM prueba donde Descripción id (conjunto de prueba ACTUALIZACIÓN = RE 'prueba' ... ^

*** Fehler ** *

ERROR: error de sintaxis en o cerca de "prueba" Estado SQL: 42601 Zeichen: 37

Sin embargo, si yo sólo corro el statemennt

UPDATE test set value='test' RETURNING id 

puedo obtener un resultado con 2 filas:

Si substitude ese resultado que tendría una consulta como:

SELECT * FROM test WHERE id IN (1,2); 

con el resultado:

1; "prueba" 2; "prueba"

¿Por qué no obtengo el mismo resultado con mi declaración inicial?

+1

tienen que ser comunicados separados. El hecho de que se estén actualizando dos filas es probable que cause problemas, nunca intenté DEVOLVER cuando está volviendo más de una fila/valor. –

Respuesta

23

Antes de PostgreSQL 9.1 INSERT/UPDATE/DELETE solo se podía usar como declaraciones de nivel superior. Es por eso que está obteniendo un error de sintaxis.

A partir de 9.1 puede utilizar instrucciones de modificación de datos con expresiones de tabla comunes.Su consulta de ejemplo se vería así:

WITH updated AS (UPDATE test SET description = 'test' RETURNING id) 
SELECT * FROM test WHERE id IN (SELECT id FROM updated); 

Tenga cuidado al seleccionar de la tabla recién modificada. Puede obtener resultados confusos de esa manera. Debido a que las consultas se ejecutan en la misma instantánea, SELECT no verá los efectos de la instrucción UPDATE.

+2

FYI, el enfoque CTE no funciona con INSERT –

+0

Entonces, ¿este 'SELECT' devolvería el ID y el antiguo valor de descripción' 'new'' en lugar del valor actualizado ''test''? – Davos

6

Actualiza dos filas en su consulta UPDATE, agregue una cláusula WHERE para restringir las filas afectadas.

UPDATE test SET description = 'test' WHERE id = 1 RETURNING id 

a regresar una sola fila .

+0

SELECCIONAR * FROM prueba DONDE id IN (ACTUALIZAR prueba SET valor = 'prueba' DONDE id = 1 ID girando) muestra el mismo error – markus

+0

actualizado "valor" a "descripción", mismo problema – markus

3

¿Echas un IN: ... WHERE id IN (UPDATE ...?

However if I only run the statemennt "UPDATE test set value='test' RETURNING id", I get a result with 2 rows. Why is that?

Su UPDATE tiene ninguna cláusula WHERE y por lo tanto se actualiza cada fila, de los cuales hay dos.

+0

sí, recién lo actualizó – markus

+0

El problema es no la actualización EN REGRESO, eso está trabajando con y sin cláusula where. El problema es con la selección a su alrededor. – markus

1

No está limitando su cláusula where. Necesita tener id = (blahblah) o id IN (blahblah)

1
UPDATE test set description='test' RETURNING * 

le daría el conjunto de resultados que espera de la consulta inicial.

¿Pero sospecho que estabas intentando algo más complejo?

0
DROP TABLE IF EXISTS test_tab; 

CREATE TABLE test_tab (
    id integer, 
    description varchar(100) 
); 

INSERT INTO test_tab(id, description) VALUES (1,'new'); 
INSERT INTO test_tab(id, description) VALUES (2,'new'); 

SELECT * from test_tab; 

DO $$ 
DECLARE 
    myID test_tab.id%TYPE; 
    testID test_tab.id%TYPE; 
    cur_IDs CURSOR for select id from test_tab; 
BEGIN 
    OPEN cur_IDs; 
    LOOP 
     FETCH cur_IDs into testID; 
     EXIT WHEN testID is NULL; 

     UPDATE test_tab SET description='test' WHERE id = testID RETURNING id into myID; 
     raise notice 'myID %', myID; 
    END LOOP; 
    CLOSE cur_IDs; 
END$$; 


DROP TABLE IF EXISTS test_tab; 
-1

estoy Además de las hormigas Aasma, si select en una misma mesa, usando:

WITH updated AS (UPDATE test SET description = 'test' RETURNING id, description) 
SELECT * FROM updated; 
Cuestiones relacionadas