Tema 4 Manipulación de datos con SQL Índice Tema 4 1. Inserción de registros. Consultas de datos anexados. 2. Modificación de registros. Consultas de actualización. 3. Borrado de registros. Consultas de eliminación. 4. Claúsulas avanzadas de selección. 4.1. Group by y having 4.2. Outer joins. Combinaciones externas. 4.3. Consultas con operadores de conjuntos. 4.4. Subconsultas correlacionadas. 5. Control de transacciones en SQL. Inserción de registros Añadir filas en una tabla. Formato: INSERT INTO nombre_tabla [(colum1 [,(…)]] VALUES (valor1 [, valor2]…); Si no se especifican columnas, se entiende que serán todas las columnas de la tabla. Valor, será el que se dará a cada columna, debe coincidir con el tipo de dato con el que se han definido. Si una columna no está en la lista de valores recibirá NULL. Si está definida como NOT NULL, INSERT fallará. Ejemplos de Inserción de registros INSERT INTO profesores (apellidos, especialidad, cod_centro) VALUES (‘Quiroga Martín, Mª Isabel’,’INFORMATICA’, 45) ; INSERT INTO profesores (apellidos, especialidad, cod_centro) VALUES(‘Seco Jiménez, Ernesto’, ‘LENGUA’); Error.. INSERT INTO profesores VALUES(22, 23444800, ‘Gonzalez Sevilla, Miguel A.’, ‘HISTORIA’); Ejercicio de Inserción de registros • Escribe la orden INSERT anterior de otra forma. • Inserta un profesor con una especialidad de más de 16 caracteres. Consulta de datos anexados Se añaden tantas filas como devuelva la consulta. INSERT INTO nombre_tabla1[(colum1 [, colum2],,,)] SELECT{column [, column]….| *} FROM nombre_tabla_2 [cláusulas de SELECT]; Consulta de datos anexados INSERT INTO emple_30 (empno, ename,…) SELECT empno, ename… FROM emp WHERE deptno = 30; INSERT INTO emple_30 SELECT * FROM emp WHERE deptno = 30; Consultas de datos anexados Insertar un empleado 1111, GARCIA, en el dpto con mayor nº de empleados y fecha ingreso la del sistema. INSERT INTO emp SELECT DISTINCT 1111, ‘GARCIA’, ‘ANALYST’, sysdate, 2000, 120, deptno FROM emp WHERE deptno = (SELECT deptno FROM emp GROUP BY deptno HAVING COUNT(*) = (SELECT MAX(COUNT(*)) FROM EMP GROUP BY deptno) ); DISTINCT es necesario, sino se insertarían tantas filas como empleados hubiese en el depto con mayor nº de empleados. Consulta de datos anexados Inserta un empleado 1112, Quiroga. Los datos restantes serán los de JAMES. INSERT INTO emp SELECT 1112, ‘QUIROGA’, job, mgr, sydate, sal, comm, deptno WHERE ename = ‘JAMES’; Consulta de datos anexados Dadas las tablas, ALUM y NUEVOS, inserta en ALUM los nuevos alumnos. Inserta en EMP, el empleado 2000, SAAVEDRA, fecha de alta la de sistema, el salario el 20% mas que el MILLER y el resto de los datos los de este. Modificación de registros Se usa para modificar columnas de 1 o varias filas que cumplan una condición o no. UPDATE nombre_tabla SET column1 = valor1, ..column = valorn WHERE condicion; Si se omite WHERE se actualizarán todas las filas. Modificación de registros UPDATE centros SET direccion = ‘C/ Pilón 13’, num_plazas = 295 WHERE cod_centro = 22; UPDATE emp SET sal = sal + 100, comm =NVL(comm, 0) + 10 WHERE empno = 7369; Consultas de actualización Podemos incluir una subconsulta en las cláusulas SET o WHERE. Cuando forma parte de SET, debe devolver una fila y el mismo nº de columnas y tipo de datos que las que hay entre paréntesis al lado de SET. Consultas de actualización Formato1: UPDATE nombre_tabla SET colum1 = valor1, ..column = valorn WHERE colum3 = (SELECT….); Consultas de actualización Formato2: UPDATE nombre_tabla SET colum1, ..column = (SELECT col1,..coln…..) WHERE condicion; Consultas de actualización Formato3: UPDATE nombre_tabla SET colum1= (SELECT col1…), colmn = (SELECT coln….) WHERE condicion; Consultas de actualización UPDATE centros SET (direccion, num_plazas)= (SELECT direccion, num_plazas FROM centros WHERE cod_centro = 50) WHERE cod_centro = 10; Consultas de actualización UPDATE emp SET sal = sal * 2, comm = 0 WHERE deptno = (SELECT deptno FROM emp GROUP BY deptno HAVING COUNT (*) = (SELECT MAX(COUNT(*)) FROM emp GROUP BY deptno) ); Consultas de actualización UPDATE emp SET ename = LOWER(ename), sal = (SELECT sal * 2 FROM emp WHERE ename = ‘JAMES’) WHERE deptno = (SELECT deptno FROM dept WHERE dname = 'ACCOUNTING’); Consultas de actualización Modifica el nº de departamento de MILLER con el departamento donde haya mas empleados cuyo oficio sea CLERK UPDATE emp SET deptno = (SELECT deptno FROM emp WHERE job = 'CLERK' GROUP BY deptno HAVING COUNT(*) = (SELECT MAX(COUNT(*)) FROM emp WHERE JOB = 'CLERK' GROUP BY deptno) ) WHERE ename = 'MILLER' Borrado de Registros Permite borrar, una varias o todas las filas de una tabla que cumplan una condición. El espacio usado por las filas borradas no se reutiliza, al menos que se realice un import o export. la condición puede incluir una subconsulta. DELETE [FROM] nombre_tabla WHERE condicion; Borrado de Registros DELETE FROM centros WHERE cod_centro = 50; DELETE centros WHERE cod_centro = 50; DELETE FROM dept WHERE deptno IN (SELECT deptno FROM emp GROUP BY deptno HAVING COUNT(*) < 4); Claúsulas Avanzadas de Selección: GROUP BY y HAVING Cuando necesitemos saber el salario medio por departamento, será necesario realizar un agrupamiento por este. SELECT deptno, AVG(sal) FROM emp GROUP BY deptno; Se puede agrupar por más de una columna, el formato es el siguiente: Claúsulas Avanzadas de Selección: GROUP BY y HAVING Formato: SELECT ….. FROM….. WHERE condicion GROUP BY colum1, colum2… HAVING condicion ORDER BY……; Los datos de SELECT, serán CTE, función de grupo o columna expresada en GROUP BY. Claúsulas Avanzadas de Selección: GROUP BY y HAVING GROUP BY, para calcular propiedades de 1 o más conjuntos de filas, las filas resultantes de la agrupación se almacenan en una tabla temporal. HAVING, condición de búsqueda para grupos de filas. Comprueba que conjuntos de filas cumplen con la condición especificada en HAVING. Se evalúa sobre la tabla temporal, no puede existir sin GROUP BY. Claúsulas Avanzadas de Selección: GROUP BY y HAVING SELECT deptno, COUNT(*) FROM emp GROUP BY deptno; SELECT deptno, COUNT(*) FROM emp GROUP BY deptno HAVING COUNT(*) > 4; SELECT deptno, AVG(sal) FROM emp GROUP BY deptno HAVING AVG(sal) >= (SELECT AVG(sal) FROM emp); Claúsulas Avanzadas de Selección: GROUP BY y HAVING HAVING(grupos filas) es similar a WHERE(filas). Se puede realizar una ordenación: SELECT deptno, COUNT(*) FROM emp GROUP BY deptno HAVING COUNT(*) > 4 ORDER BY COUNT(*); Claúsulas Avanzadas de Selección: GROUP BY y HAVING Orden de evaluación de las Cláusulas de Orden SELECT WHERE selecciona filas GROUP BY agrupa filas HAVING selecciona grupos ORDER BY ordena los grupos Claúsulas Avanzadas de Selección: GROUP BY y HAVING SELECT deptno, TO_CHAR(SUM(sal), '99G999D99') AS suma, TO_CHAR(MAX(sal), '99G999D99') AS Máximo, TO_CHAR(MIN(sal), '99G999D99') AS Mínimo FROM emp GROUP BY deptno; Claúsulas Avanzadas de Selección: GROUP BY y HAVING SELECT deptno, job, COUNT(*) FROM emp GROUP BY deptno, job ORDER BY deptno; Claúsulas Avanzadas de Selección: GROUP BY y HAVING SELECT d.deptno, dname, COUNT(empno) FROM emp e, dept d WHERE e.deptno = d.deptno GROUP BY d.deptno, dname HAVING COUNT(empno) > 4; Claúsulas Avanzadas de Selección: GROUP BY y HAVING SELECT d.deptno, dname, COUNT(empno) FROM emp e, dept d WHERE e.deptno = d.deptno GROUP BY d.deptno, dname HAVING COUNT(empno) >= (SELECT MAX(COUNT(*)) FROM emp GROUP BY deptno); Claúsulas Avanzadas de Selección: Combinaciones Externas Permite combinar tablas y seleccionar filas de estas aunque no tengan correspondencia entre ellas. SELECT tabla1.colum1, ..tabla1.column, tabla2.colum1,…tabla2.column FROM tabla1, tabla2 WHERE tabla1.colum1 = tabla2.colum1(+); Claúsulas Avanzadas de Selección: Combinaciones Externas SELECT d.deptno, d.dname, COUNT(empno) FROM emp e, dept d WHERE e.deptno = d.deptno GROUP BY d.deptno, d.dname; Con OUTER JOIN, se muestran todos los departamentos aunque no tengan empleados, nº empleados estará a NULL. (*), estará donde no exista el dpto. SELECT d.deptno, d.dname, COUNT(empno) FROM emp e, dept d WHERE e.deptno(+) = d.deptno GROUP BY d.deptno, d.dname; Claúsulas Avanzadas de Selección: Combinaciones Externas Analiza que ocurre si COUNT(*) en vez de COUNT(empno) y si en SELECT ponemos e.deptno en vez de d.deptno. SELECT e.deptno, d.dname, COUNT(*) FROM emp e, dept d WHERE e.deptno(+) = d.deptno GROUP BY d.deptno, d.dname; Claúsulas Avanzadas de Selección: Operadores de Conjuntos - Unión Combina los resultados de 2 consultas, las filas duplicadas se reducen a una. SELECT colum1, colum2,..column FROM tabla1 WHERE condicion UNION SELECT colum1, colum2,..column FROM tabla2 WHERE condicion; Claúsulas Avanzadas de Selección: Operadores de Conjuntos - Unión SELECT nombre FROM alum UNION SELECT nombre FROM nuevos; Con ALL aparecen las filas duplicadas. SELECT nombre FROM alum UNION ALL SELECT nombre FROM nuevos; Claúsulas Avanzadas de Selección: Operadores de Conjuntos - Intersección Devuelve las filas que son iguales en ambas consultas. SELECT colum1, colum2,..column FROM tabla1 WHERE condicion INTERSECT SELECT colum1, colum2,..column FROM tabla2 WHERE condicion; Claúsulas Avanzadas de Selección: Operadores de Conjuntos - Intersección SELECT nombre FROM alum INTERSECT SELECT nombre FROM antiguos; También se puede hacer con operador IN SELECT nombre FROM alum WHERE nombre IN (SELECT nombre FROM antiguos); Claúsulas Avanzadas de Selección: Operadores de Conjuntos - Diferencia Devuelve las filas que están en la 1ª SELECT y no en la 2ª. SELECT colum1, colum2,..column FROM tabla1 WHERE condicion MINUS SELECT colum1, colum2,..column FROM tabla2 WHERE condicion; Claúsulas Avanzadas de Selección: Operadores de Conjuntos - Diferencia SELECT nombre, localidad FROM alum MINUS SELECT nombre, localidad FROM antiguos ORDER BY localidad; Claúsulas Avanzadas de Selección: Operadores de Conjuntos - Diferencia Se puede hacer usando NOT IN SELECT nombre, localidad FROM alum WHERE nombre NOT IN (SELECT nombre FROM antiguos) ORDER BY localidad; Reglas para uso de los operadores de conjuntos • Las columnas de ambas tablas se relacionan de izquierda a derecha. • Los nombres de las columnas de ambas SELECTs no tienen que coincidir. • Las SELECTs tienen que tener el mismo nº de columnas. • Los tipos de datos tienen que coincidir, aunque la longitud no tiene que ser la misma. Claúsulas Avanzadas de Selección: Subconsultas Correlacionadas En ocasiones, es necesario relacionar campos de la consulta principal con campos de la subconsulta. Veamos este ejemplo: Mostrar los datos de los empleados cuyos salarios sean iguales al máximo salario de su departamento. Haríamos una subconsulta para ver el máximo salario del departamento del empleado y después lo compararíamos con el salario del empleado. Claúsulas Avanzadas de Selección: Subconsultas Correlacionadas La consulta debe quedar así: SELECT * FROM emp e WHERE sal = (SELECT MAX(sal) FROM emp WHERE deptno = e.deptno); Hacemos referencia desde la subconsulta a una columna o varias de la consulta más externa. A veces el nombre de las columnas coincide, por lo tanto usaremos alias para la tabla más externa. Control de Transacciones en SQL Transacción es una secuencia de una o más ordenes SQL, que juntas forman una unidad de trabajo. ROLLBACK, aborta la transacción, volviendo las tablas a la situación del último COMMIT. ROLLBACK automático, se produce cuando haya algún fallo del sistema y no hayamos validado el trabajo hasta entonces. Control de Transacciones en SQL COMMIT, para validar los cambios que hayamos realizado en la BD. AUTOCOMMIT, parámetro que en SQL*Plus e iSQL*Plus, sirve para validar automáticamente las transacciones en la BD, siempre que esté en ON. Por defecto está en OFF, por tanto INSERT, UPDATE y DELETE no se ejecutan automáticamente, hasta que no hagamos COMMIT SHOW AUTOCOMMIT SET AUTOCOMMIT ON Control de Transacciones en SQL Hay algunas órdenes SQL que fuerzan COMMIT implícito: QUIT EXIT CONNECT DISCONNECT CREATE TABLE DROP TABLE CREATE VIEW DROP VIEW GRANT ALTER REVOQUE AUDIT NOAUDIT