Referencia: Comandos SQL:
- ALTER TABLE: cambiar la definición de una tabla
- ANALYZE: colecta estadísticas sobre una bb.dd.
- CREATE INDEX: define un nuevo índice
- CREATE TABLE: define una nueva tabla
- DELETE: elimina filas de una tabla
- DROP TABLE: elimina una tabla
- EXPLAIN: muestra el plan de ejecución
- INSERT: crea nuevas filas en una tabla
- SELECT: obtiene filas de una tabla o vista
- TRUNCATE: vacía una tabla o un conjunto de ellas
- UPDATE: modifica filas de una tabla
- VACUUM: limpia y opcionalmente analiza una bb.dd.
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.
