LENGUAJE DML.

Es posible actualizar registros de una tabla filtrando a trav茅s de una subconsulta. La 煤nica limitaci贸n para actualizar registros depender谩n de los gestores que no permitan realizar cambios en una tabla que se est茅 consultando.

Para las acciones vamos a seguir usando la tabla ALMACEN que te podr谩s bajar en la zona de pr谩cticas de esta clase y en la cual existen una serie de tablas y registros.

La sintaxis es la siguiente:

UPDATE nombre_tabla
SET nombre_Colunma=expresi贸n [nombre_columna2=expresion2 ]...
[WHERE FILTRO]

La actualizaci贸n se produce dando nuevos valores a las columnas que se quieran cambiar asignando el nuevo valor a dichas columnas.

As铆 que partiendo de la anterior base creada Almacen, vamos a continuar actualizando contenido dentro de las tablas asociadas. Escogeremos la tabla de clientes en donde actualizaremos el tel茅fono del primer cliente con Id=1. Para ello abre tu editor/consola, entra en la base de datos y realiza una consulta select gen茅rica para ver a los clientes. Eso lo haces con la instrucci贸n select * from clientes;, como v茅s en la imagen siguiente:

Select general para conocer las filas y registros de una tabla.

Vemos que el campo Telefono del cliente asociado al Id n煤mero 1 es 555555555, y lo queremos cambiar a un n煤mero 918812345. Siguiendo la sintaxis anterior quedar铆a de la forma:

update clientes set Telefono = 9188123345 where Id=1;

Te devolver谩 un Ok y si actualizas la consulta SELECT ver谩s que el nuevo tel茅fono es que has introducido. Siempre en esta sentencia te devolver谩 el estado de la operaci贸n y en caso de producirse un error no realizara la actualizaci贸n y te mostrar谩 el error en pantalla.

confirmaci贸n de la operaci贸n de actualizaci贸n

Hay que tener cuidado con esta operaci贸n en casos gen茅ricos o con filtros espec铆ficos, ya que si, por ejemplo actualizamos valores que empiecen o terminen en un n煤mero o car谩cter concreto, se puede actualizar por error todo el contenido:

Cuidado al usar la cla煤sula de UPDATE porque se puede actualizar contenido multiple

La sentencia DELETE.

SQL utiliza la sentencia DELETE para eliminar filas de una tabla. Su sintaxis es la siguiente:

DELETE from nombre_tabla
[WHERE FILTRO]

El comando DELETE borra los registros seleccionados, por eso es muy importante utilizar la condici贸n WHERE para evitar borrar todos los registros.

Borrado de todos los registros por no utilizar Where

Es posible usar las dos cla煤sulas mencionadas hasta ahora en una 煤nica instrucci贸n de subconsulta con filtros. As铆 por ejemplo si quisieramos borrar un cliente que no ha hecho compras en un a帽o usariamos una sentencia similar a esta:

DELETE from clientes where NIF not in
(Select CLIENTENIF from facturacion) and Fecha > 365;

Observa que dentro de una sentencia estamos llamando a otra sentencia y adem谩s, le pasamos una condici贸n l贸gica de que en el caso de que la fecha sea mayor que 365 d铆as.

Transacciones.

Un SGBD actualiza m煤ltiples datos a trav茅s de las transacciones. Por lo tanto una transacci贸n es un conjunto de sentencias SQL que se tratan como si fuese una 煤nica sentencia.

Una transacci贸n puede ser confirmada (commit), si todas las operaciones individuales se ejecutaron correctamente, o abortada (rollback) si existi贸 alg煤n problema. El rollback es necesario para volver a dejar los datos como se ten铆an antes de la actuaci贸n, ya que SQL va borrando por l铆neas y puede que el error se produjese a mitad del proceso.

En SQL es habitual tambi茅n trabajar con transacciones ya que ayuda a proteger la integridad de los datos ya que si no se produce el commit, se producir谩 el rollback.

Los clientes cuando se conectan a un SGBD, por defecto est谩 activado el modo AUTOCOMMIT = ON, es decir cada comando SQL que se ejecute, ser谩 considerado como una transacci贸n independiente. Para activar las transacciones de m煤ltiples sentencias, hay que establecer el modo AUTOCOMMIT = OFF. A partir de ese momento todos los comandos SQL enviados al SGBD tendr谩n que terminarse con una order COMMIT o una order de ROLLBACK. Esta forma de proceder garantiza un nivel superior de la integridad de los datos.

NOTA: Muchos SGBD necesitan que se inicialice la transacci贸n de la forma que incluyan START TRANSACTION o START WORK (dependiendo del SGBD), aunque la mayor铆a saben que es una transacci贸n m煤ltiple cuando se establece el modo de autocommit=0 como lo hace MySQL.

Iniciar transacci贸n en Mysql

Para terminar una trasacci贸n solo hay que aceptar o rechazar con commit o rollback.

NOTA 2: Si trabajas en modo consola desde tu CMD o un terminal de tu Linux favorito, puede ocurrir que las transacciones no est茅n habilitadas y que tengas que habilitarlas desde la configuraci贸n de MySQL en su archivo de configuraci贸n.

Acceso concurrente a los datos.
Cuando se utlizan transacciones, pueden suceder problemas de concurrencia en el acceso a los datos, es decir, problemas ocasionados por el acceso al mismo dato de dos transacciones distintas. Estos son los problemas del SQL est谩ndar:

Dirty read. Una transacci贸n lee datos escritos por una transacci贸n que no ha hecho COMMIT.
Non repeateable Read Una transacci贸n vuelva a leer datos que ley贸 previamente y encuentra que han sido modificados por otra transacci贸n.
Phantom Read Una transacci贸n lee datos que no exist铆an cuando se inicio la misma.

Al trabajar con transacciones, el SGBD puede bloquear conjunto de datos para evitar que sucedan estos problemas. Pero tambi茅n se pueden permitir seg煤n el nivel de concurrencia deseado, es posible solicitar al SGBD cuatro niveles de aislamiento. Un nivel de aislamiento define c贸mo los cambios hechos por una transacci贸n son visibles a otras transacciones.

Read Uncommited Permite que sucedan los tres problemas anteriores.
Read Commited Los datos leidos por una transacci贸n pueden ser modificados por otras transacciones. Se pueden dar problemas Phantom y Nomn Repeateable Read.
Repeateable Read Tan solo permite el problema del Phantom Read. Ning煤n registro SELECT se puede cambiar en otra transacci贸n.
Serializable Las transacciones ocurren de forma aisladas a otras transacciones. Se bloquean seg煤n ocurren una detr谩s de otra para evitar la concurrencia.

Para que entiendas lo que son las transacciones y los ejemplos de problemas concurrentes, imagina que un usuario accede a la bbdd y hace una consulta para saber el n煤mero de clientes que tiene en su tabla clientes de la forma:

select MAX(Id) from clientes;

Cliente consulta la base de datos

Segundos despu茅s otro usuario se conecta a la BBDD y realiza cambios en la tabla clientes mientras la transacci贸n continua en la sesi贸n del usuario1.

Usuario 2 realiza un cambio mientras el usuario1 est谩 ejecutando la transacci贸n

En esta situaci贸n, la transacci贸n de la sesi贸n 1 no podr谩 reproducir la situaci贸n anterior y no ver谩 el cambio si por defecto se ha establecido un nivel de concurrencia de lectura no repetible (Non Repeateable) y no se actualizar谩n los datos de la transacci贸n en la sesi贸n 1.

Pero imagina que declaramos tambi茅n un nivel de concurrencia de lectura fantasma y el usuario 2 introduce un nuevo cliente:

insert into clientes values(5, "Ambrosio", "Desiderio Rom谩n", 917654323457, "C/Arrabal 5. 1潞 Izq. Villaverde. Madrid", "Ambrisio_1967@hotmail.com", "049787896Y");

El usuario de la sesi贸n 1 ver谩 autom谩ticamente el nuevo registro en su transacci贸n. Es lo que se designa como lectura fantasma.

Pero los problemas se pueden agrandar al utilizar la lectura sucia. En la situaci贸n anterior, si el usuario 2 hubiese hecho un rollback (porque no est谩 seguro de crear correctamente al cliente), el usuario 1 seguir谩 viendo al nuevo cliente y podr铆a trabajar con dichos datos aunque no existan en la base de datos. Eso es lectura s煤cia.

M谩s adelante indagaremos sobre las transacciones en SQL y veremos como utilizarlas en nuestras consultas SQL. Ahora puedes pasar a la pr谩ctica donde empezaremos a hablar sobre el DCL, que es el sublenguaje de SQL que proporciona seguridad a las bases de datos.