UPDATE

Nombre

UPDATE -- modifica filas de una tabla

Sinopsis

UPDATE [ ONLY ] tabla [ [ AS ] alias ]
    SET { columna = { expresión | DEFAULT } |
          ( columna [,  ...] ) = ( { expresión | DEFAULT } [,  ...] ) } [,  ...]
    [ FROM lista_from ]
    [ WHERE condición | WHERE CURRENT OF nombre_cursor ]
    [ RETURNING * | expresión_salida [ [ AS ] nombre_salida ] [,  ...] ]

Descripción

UPDATE modifica los valores de las columnas especificadas en todas las filas que satisfagan la condición. Solamente las columnas a ser modificadas necesitan ser mencionadas en la clausula SET; columnas no modificadas explicitamente mantienen sus valores previos.

Por defecto, UPDATE modificará las filas en la tabla especificada y todas sus tablas hijas. Si desea modificar solamente la tabla mencionada específicamente, debe usar la clausula ONLY.

Hay dos maneras de modificar una tabla usando la información contenida en otras tablas de la base de datos: usando sub-selects, o especificando tablas adicionales en la clausula FROM. Cual técnica es más apropiada depende en las circunstancias específicas.

La clausula opcional RETURNING causa que UPDATE compute y retorne los valores basados en cada fila modificada. Cualquier expresión usando las columnas de la tabla, y/o columnas de otras tablas mencionadas en el FROM, puede ser computado. Son usados los nuevos valores (post-modificación) de las columnas de la tabla. La sintaxis de la lista RETURNING es idéntica a la de la lista de salida del SELECT.

Debe tener privilegios UPDATE sobre la tabla, o al menos sobre la columnas que están listadas para ser modificadas. Debe tener también privilegios de SELECT sobre cualquier columna cuyo valor es leido en las expresiones o condición.

Parámetros

tabla
El nombre de la tabla a modificar (opcionalmente calificado por el esquema).
alias
Un nombre sustituto para la tabla destino- Cuando un alias es provisto, completamente oculta el nombre real de la tabla. Por ejemplo, dado UPDATE foo AS f, el resto de la sentencia UPDATE debe referirse a esta tabla como f y no foo.
columna
El nombre de una columna de la tabla. Si es necesario, el nombre de una columna puede estar calificado con el nombre de un subcampo o subíndice de arreglo. No incluir el nombre de la tabla en la especificación de una columna destino - por ejemplo, es inválido UPDATE tab SET tab.col = 1.
expresión
Una expresión para asignar a una columna. La expresión puede usar valores viejos de esta u otras columnas de la tabla.
DEFAULT
Establecer la columna a su valor predeterminado (que será NULL si no se asigno una expresión por defecto específica).
lista_from
Una lista de expresiones de tabla, permitiendo que columnas de otras tablas aparezcan en la condición del WHERE y expresiones de actualización. Esto es similar a la lista de tablas que pueden ser especificadas en la Clausula FROM de una sentencia SELECT. Note que la tabla destino no debe aparecer en la lista_from, salvo que tenga la intención de hacer una junta con si misma (en cuyo caso debe aparecer con un alias en la lista_from).
condición
Una expresión que devuelve un valor del tipo boolean. Solo filas para las cuales la expresión devuelve true serán modificadas.
nombre_cursor
El nombre del cursor para usar en una condición WHERE CURRENT OF. La fila a ser modificada es la más recientemente traída del cursor. El cursor debe ser una consulta no agrupada en la tabla destino del UPDATE. Note que WHERE CURRENT OF no puede ser especificado junto con una condición Booleana. Ver  DECLARE para mayor información sobre el uso de cursores con WHERE CURRENT OF.
expresión_salida
Una expresión a ser computada y retornada por el comando UPDATE luego de que cada fila es actualizada. La expresión puede usar cualquier nombre de columna de la tabla o las tablas listadas en el FROM. Escribir * para retornar todas las columnas.
nombre_salida
Un nombre para usar para la columna retornada.

Salidas

Al completarse exitosamente, un comando UPDATE devuelve una etiqueta de comando de la forma

UPDATE cantidad

La cantidad es el número de filas modificadas. Si cantidad es 0, ninguna fila coincidió con la condición (esto no es considerado un error).

Si el comando UPDATE contiene una clausula RETURNING, el resultado será similar al de una sentencia SELECT conteniendo las columnas y valores definidos en la lista RETURNING, computado sobre las filas modificadas por el comando.

Notas

Cuando una clausula FROM está presente, lo que esencialmente sucede es que la tabla destino es juntada a las tablas mencionadas en la lista_from, y cada fila de salida de la junta representa una operación de modificación para la tabla destino. Al usar FROM debería asegurarse que la junta produzca al menos ua fila de salida por cada fila a ser modificada. En otras palabras, una fila destino no debería juntarse con más de una fila de las otras tabla(s). Si lo hace, solamente una de las filas juntadas será usada para actualizar la fila destino, pero cual será usada no es predecible.

Dado esta indeterminación, referenciar otras tablas solamente con sub-selects es más seguro, aunque a veces sea más difícil de leer y más lento que usar una junta.

Ejemplos

Cambiar la palabra Drama a Dramático en la columna genero de la tabla peliculas:

UPDATE peliculas SET genero = 'Dramático' WHERE genero = 'Drama';

Ajustar las entradas de temperatura y volver precipitación a su valor predeterminado en una fila de la tabla clima:

UPDATE clima SET temp_min = temp_min+1, temp_max = temp_max+15, prcp = DEFAULT
  WHERE ciudad = 'San Francisco' AND fecha = '2003-07-03';

Realizar la misma operación y retornar las entradas actualizadas:

UPDATE clima SET temp_min = temp_min+1, temp_max = temp_max+15, prcp = DEFAULT
  WHERE ciudad = 'San Francisco' AND fecha = '2003-07-03';
  RETURNING temp_min, temp_max, prcp;

Usar la sintaxis alternativa de listado de columna para hacer la misma actualización:

UPDATE clima SET (temp_min, temp_max, prcp) = (temp_min+1, temp_max+15, DEFAULT)
  WHERE ciudad = 'San Francisco' AND fecha = '2003-07-03';

Incrementar la cuenta de ventas de un vendedor que administra la cuenta de Acme Corporation, usando la clausula FROM:

UPDATE empleados SET cuenta_venta = cuenta_venta + 1 FROM cuentas
  WHERE cuentas.nombre = 'Acme Corporation'
  AND empleados.id = cuentas.vendedor;

Realizar la misma operación, usando un sub-select en la clausula WHERE:

UPDATE empleados SET cuenta_venta = cuenta_venta + 1 WHERE id =
  (SELECT vendedor FROM cuentas WHERE nombre = 'Acme Corporation');

Intentar insertar un nuevo artículo y al mismo tiempo la cantidad en existencia. Si actualmente existe el artículo, actualizar la cantidad en existencia. Para hacer esto sin fallar la transacción completa, usar puntos de almacenamiento:

BEGIN;
-- otra operación
SAVEPOINT sp1;
INSERT INTO vinos VALUES('Chateau Lafite 2003', '24');
-- Asumir que lo de arriba falló dado a una violación de clave única,
-- por lo que enviamos el comando:
ROLLBACK TO sp1;
UPDATE vinos SET stock = stock + 24 WHERE nombre_vino = 'Chateau Lafite 2003';
-- continuar con otras operaciones, eventualmente:
COMMIT;

Modificar la columna genero de la tabla peliculas en la fila en que el cursor c_peliculas esta actualmente posicionado:

UPDATE peliculas SET genero = 'Dramático' WHERE CURRENT OF c_peliculas;

Compatibilidad

Este comando se ajusta al estándar SQL, exceptuando las clausulas FROM y RETURNING que son extensiones PostgreSQL.

De acuerdo al estándar, la sintaxis de lista de columnas debería permitir que sean asignadas desde un expresión individual que devuelva el valor de una fila, como un sub-select:

UPDATE cuentas SET (apellido_contacto, nombre_contacto) =
    (SELECT apellido, nombre FROM vendedores
     WHERE vendedores.id = cuentas.ventas_id);

Esto actualmente no esta implementado - el origen debe ser una lista de expresiones independientes.

Algunos otros sistemas de base de datos ofrecen una opción FROM en la cual se supone que la tabla destino sea listada nuevamente dentro del FROM. Eso no es como PostgreSQL interpreta FROM. Sea cuidadoso al portar aplicaciones que usen esta extensión.