SQL para principiantes (Parte 9): La Declaración UPDATE

Esta es la novena parte de una serie de artículos que muestran los conceptos básicos de SQL. En este artículo, echamos un vistazo a algunas de las variaciones de la declaración UPDATE.

  • Preparar
  • COMMIT y ROLLBACK
  • UPDATE Básico
  • UPDATE vía View
  • Sub-Consultas Escalar
  • 0 Rows Updated

Preparar

Puede realizar todas estas consultas en línea de forma gratuita utilizando SQL Fiddle.

Los ejemplos de este artículo requieren que estén presentes las siguientes tablas.

--DROP TABLE employees PURGE;
--DROP TABLE departments PURGE;

CREATE TABLE departments (
  department_id   NUMBER(2) CONSTRAINT departments_pk PRIMARY KEY,
  department_name VARCHAR2(14),
  location        VARCHAR2(13)
);
INSERT INTO departments VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO departments VALUES (20,'RESEARCH','DALLAS');
INSERT INTO departments VALUES (30,'SALES','CHICAGO');
INSERT INTO departments VALUES (40,'OPERATIONS','BOSTON');
COMMIT;

CREATE TABLE employees (
  employee_id   NUMBER(4) CONSTRAINT employees_pk PRIMARY KEY,
  employee_name VARCHAR2(10),
  job           VARCHAR2(9),
  manager_id    NUMBER(4),
  hiredate      DATE,
  salary        NUMBER(7,2),
  commission    NUMBER(7,2),
  department_id NUMBER(2) CONSTRAINT emp_department_id_fk REFERENCES departments(department_id)
);
INSERT INTO employees VALUES (7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20);
INSERT INTO employees VALUES (7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);
INSERT INTO employees VALUES (7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);
INSERT INTO employees VALUES (7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);
INSERT INTO employees VALUES (7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30);
INSERT INTO employees VALUES (7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30);
INSERT INTO employees VALUES (7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10);
INSERT INTO employees VALUES (7788,'SCOTT','ANALYST',7566,to_date('13-JUL-87','dd-mm-rr')-85,3000,NULL,20);
INSERT INTO employees VALUES (7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10);
INSERT INTO employees VALUES (7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30);
INSERT INTO employees VALUES (7876,'ADAMS','CLERK',7788,to_date('13-JUL-87', 'dd-mm-rr')-51,1100,NULL,20);
INSERT INTO employees VALUES (7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30);
INSERT INTO employees VALUES (7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20);
INSERT INTO employees VALUES (7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10);
COMMIT;

Estas tablas son una variante de las tablas EMP y DEPT del esquema SCOTT. Verá muchos ejemplos de Oracle en Internet utilizando las tablas del esquema de SCOTT. Puede encontrar las definiciones de la tabla original en el script «$ORACLE_HOME/rdbms/admin/utlsampl.sql».

COMMIT y ROLLBACK

Todos los cambios en el lenguaje de manipulación de datos (DML) se realizan como parte de una transacción. No son permanentes hasta que se confirman mediante la declaración COMMIT. Una vez comprometido, la única forma de revertir un cambio es emitir una nueva declaración DML para alterar los datos. Se pueden agrupar varios extractos para formar una sola transacción.
Los comandos del lenguaje de definición de datos (DDL) realizan una confirmación implícita, que también confirma todos los cambios de DML pendientes en la sesión actual.
Si decide que no desea mantener algunos cambios sin confirmar, puede deshacerse de ellos usando la instrucción ROLLBACK. Muchos de los ejemplos de este artículo emitirán declaraciones ROLLBACK después de la prueba, para revertir los datos a su estado original.
Algunas herramientas y lenguajes de programación se comprometen automáticamente de forma predeterminada, por lo que emiten automáticamente una declaración COMMIT después de cada declaración DML que procesan. No dejes que esto te engañe haciéndote pensar que es un comportamiento predeterminado. No lo es.

UPDATE Básico

La instrucción UPDATE se usa para alterar los valores de columna en una fila existente. Sin una cláusula WHERE, todas las filas de la tabla se actualizan mediante una única declaración.
La siguiente consulta enumera todos los valores de SALARIO en la tabla EMPLOYEES.

SELECT e.salary
FROM   employees e
ORDER BY e.salary;

    SALARY
----------
       800
       950
      1100
      1250
      1250
      1300
      1500
      1600
      2450
      2850
      2975
      3000
      3000
      5000

14 rows selected.

SQL>

Actualicémoslos todos agregando 1 a ellos.

UPDATE employees
SET    salary = salary + 1;

14 rows updated.

SQL>

SELECT e.salary
FROM   employees e
ORDER BY e.salary;

    SALARY
----------
       801
       951
      1101
      1251
      1251
      1301
      1501
      1601
      2451
      2851
      2976
      3001
      3001
      5001

14 rows selected.

SQL>

La cláusula WHERE se utiliza para limitar el alcance de la declaración. Es posible que deseemos actualizar una pequeña cantidad de filas, o incluso una sola fila mediante el uso de un filtro en las columnas de clave principal de la tabla.

UPDATE employees
SET    salary = salary - 1
WHERE  salary >= 2000;

6 rows updated.

SQL>SELECT e.salary
FROM   employees e
ORDER BY e.salary;

    SALARY
----------
       801
       951
      1101
      1251
      1251
      1301
      1501
      1601
      2450
      2850
      2975
      3000
      3000
      5000

14 rows selected.

-- Revertir todos los cambios.
SQL> ROLLBACK;

Se pueden modificar varios valores de columna en una sola instrucción UPDATE.

UPDATE employees
SET    salary     = 9999,
       commission = 1000,
       manager_id = 7566
WHERE  employee_id = 7369;

1 row updated.

SQL> ROLLBACK;

UPDATE vía View

Es posible actualizar la tabla base asociada con una vista. Hay algunas restricciones asociadas con esto, pero están un poco fuera del alcance de un artículo de nivel principiante. En el siguiente ejemplo, creamos una vista simple en la tabla EMPLOYEES y luego la actualizamos a través de ella.

CREATE OR REPLACE VIEW employees_v AS
SELECT * FROM employees;

UPDATE employees_v
SET    salary = 1000
WHERE  employee_id = 7369;

1 row updated.

SQL> ROLLBACK;

No lo verá con mucha frecuencia, pero también puede actualizar a través de vistas en línea. Esto se puede usar para controlar el número de filas actualizadas, en lugar de usar un filtro en la cláusula WHERE de la propia instrucción UPDATE.

UPDATE (SELECT employee_id, salary
        FROM   employees
        WHERE  department_id = 20)
SET    salary = 4000;

5 rows updated.

SQL> ROLLBACK;

Sub-Consulta Escalar

El valor actualizado puede provenir de una subconsulta escalar. La siguiente ACTUALIZACIÓN establece el SALARIO del empleado 7369 en el del empleado mejor pagado.

UPDATE employees
SET    salary = (SELECT MAX(salary) FROM employees)
WHERE  employee_id = 7369;

1 row updated.

SQL> ROLLBACK;

0 Rows Updated

Una actualización de cero filas es una actualización válida y no genera un error. Esto puede resultar bastante confuso para los principiantes.

UPDATE employees
SET    salary = 10000
WHERE  employee_id = 9999;

0 rows updated.

SQL>

Como resultado, no puede probar si no se actualizan las filas utilizando la excepción NO_DATA_FOUND en PL/SQL, ya que no se genera.

SET SERVEROUTPUT ON
BEGIN
  UPDATE employees
  SET    salary = 10000
  WHERE  employee_id = 9999;

  DBMS_OUTPUT.put_line('NO_DATA_FOUND Not Raised');
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.put_line('NO_DATA_FOUND Raised');
END;
/
NO_DATA_FOUND Not Raised

PL/SQL procedure successfully completed.

SQL>

En su lugar, debe probar manualmente el número de filas actualizadas mediante SQL%ROWCOUNT.

SET SERVEROUTPUT ON
BEGIN
  UPDATE employees
  SET    salary = 10000
  WHERE  employee_id = 9999;

  IF SQL%ROWCOUNT = 0 THEN
    -- Manually raise the NO_DATA_FOUND exception.
    RAISE NO_DATA_FOUND;
  END IF;
  DBMS_OUTPUT.put_line('NO_DATA_FOUND Not Raised');
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.put_line('NO_DATA_FOUND Raised');
END;
/
NO_DATA_FOUND Raised

PL/SQL procedure successfully completed.

SQL>

1 comentario en “SQL para principiantes (Parte 9): La Declaración UPDATE”

  1. Pingback: Introducción a SQL - DBandTech.com

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *