Post on 02-Jun-2018
8/10/2019 Actualizacion de Datos SQL
1/22
Unidad 7. Actualizacin de datos (I)
7.1. Introduccin
Hasta ahora hemos trabajado con tablas que tenan datos introducidos y cuando nos ha hecho falta
hemos aadido nuevos datos en las mismas y hemos modificado algn dato directamente desde elentorno de SSMS, en este tema veremos cmo hacerlo con instrucciones de Transact-SQL.
Seguimos en el DML porque las instrucciones que veremos actan sobre los datos de la base de datos
no sobre su definicin y tenemos tres tipos de operaciones posibles:
Insertar nuevas filas en una tabla.
Modificar datos ya almacenados.
Eliminar filas de una tabla.
7.2. Insertar creando una nueva tabla
Una forma de insertar datos es crear una tabla que incluya los datos de otra. Esta es la sentencia
SELECT... INTO.
SELECT ...
INTO nb_NuevaTabla
FROM ...
nb_NuevaTablaes el nombre de la tabla que se va a crear, si en la base de datos ya hay una tabla con
ese nombre, el sistema genera un error y no se ejecuta la sentencia.
En la nueva tabla las columnas tendrn el mismo tipo y tamao que las columnas del resultado de la
SELECT, se llamarn con el nombre de alias de la columna o en su defecto con el nombre de la
columna, pero no se transfiere ninguna otra propiedad del campo o de la tabla como por ejemplo las
claves e ndices.
Si retomamos el ejemplo del punto anterior:
CREATE TABLE trabajo (col1 INT, col2 VARCHAR(20), col3 MONEY);
INSERT INTO trabajo SELECT oficina, ciudad, ventas
FROM oficinas
WHERE region = 'Centro';
Se podra obtener el mismo resultado con una sola instruccin:
SELECT oficina AS col1, ciudad AS col2, ventas AS col3
8/10/2019 Actualizacion de Datos SQL
2/22
INTO trabajo
FROM oficinas
WHERE region = 'Centro'
Si se tiene poca experiencia en esta instruccin, lo mejor es primero escribir la SELECT que permite
obtener las filas a insertar y una vez la tenemos aadir la clusula INTO destino delante de FROM.
Objetivo
Crear una tabla a partir de los datos de otra, con SELECT ... INTO.
Ejercicio paso a paso
Crear una copia de empleados con el nombre Nuevaempleados, lo mismo para la tabla de oficinas
(Nuevaoficinas), la de clientes (Nuevaclientes), la de productos (Nuevaproductos) y la de pedidos
(Nuevapedidos). A partir de este momento estas tablas servirn para tener una copia original de lastablas que vamos a modificar. Las tablas creadas slo se utilizarn en el ltimo ejercicio del tema.
SELECT * INTO Nuevaempleados FROM empleados;
SELECT * INTO Nuevaoficinas FROM oficinas;
SELECT * INTO Nuevaclientes FROM clientes;
SELECT * INTO Nuevaproductos FROM productos;
SELECT * INTO Nuevapedidos FROM pedidos;
Crear una tabla (Oeste) con todas las oficinas del Oeste, la tabla tendr los mismos datos queoficinas. (3 filas afectadas)
SELECT * INTO Oeste
FROM oficinas
WHERE region = 'Oeste';
7.3. Insertar en una tabla existente INSERT INTO
La insercin de nuevos datos en una tabla, se realiza aadiendo filas enteras a la tabla, la sentencia SQLque lo permite es la orden INSERT (o tambin denominada INSERT INTO).
De la sentencia INSERT completa, nosotros estudiaremos la sintaxis ms utilizada y estndar:
8/10/2019 Actualizacion de Datos SQL
3/22
INSERT [INTO]
{
[(lista_columnas)]
{VALUES ({DEFAULT|NULL|expresion}[ ,...n ])
|tabla_derivada
}
}
|DEFAULT VALUES
[;]
::=
{
[nbBaseDatos.nbEsquema. | nbEsquema.]nbTablaVista
}
Con esta instruccin podemos insertar una fila de valores determinados o un conjunto de filas
derivadas de otra consulta.
7.4. Insertar una fila de valores
Para insertar una fila de valores utilizamos la sintaxis:
INSERT [INTO] [(lista_columnas)]
VALUES ({DEFAULT|NULL|expresion}[ ,...n ])[;]
La palabra reservada INTO es opcional y no aade funcionalidad a la instruccin, originalmente era
obligatoria.
Despus de indicar que queremos insertar, debemos indicar dnde, mediante . es
el nombre de la tabla donde queremos insertar, puede ser un nombre de tabla o un nombre de vista.Si
utilizamos una vista, y sta tiene un origen basado en varias tablas, en su lista de seleccin debernaparecer columnas de una sola tabla (no podemos insertar datos en varias tablas a la vez).Con la
clusula VALUES indicamos entre parntesis los valores a insertar, separados por comas.Cada valor se
puede indicar mediante:
Una expresin que normalmente ser una constante,mediante la palabra reservada DEFAULT que
indica valor por defecto en este caso la columna se rellenar con el valor predeterminado de la
columna, si la columna no tiene DEFAULT se sustituir por el valor nulo NULL.
8/10/2019 Actualizacion de Datos SQL
4/22
8/10/2019 Actualizacion de Datos SQL
5/22
En este caso hemos indicado slo dos columnas y dos valores, las dems columnas se rellenan con el
valor por defecto si lo tiene (DEFAULT) o con NULL. Si alguna columna no nombrada no admite nulos ni
tiene clusula DEFAULT definida, la instruccin dar error.
INSERT INTO oficinas
VALUES (27,'Mstoles','Centro',default ,null, default)
Aqu no hemos indicado una lista de columnas luego los valores se tienen que indicar en el mismo
orden que las columnas dentro de la tabla, si nos equivocamos de orden, el valor se guardar en una
columna errnea (si los tipos son compatibles) o generar un mensaje de error y la fila no se insertar
(si los tipos no son compatibles).
Objetivo
Insertar una fila de datos en una tabla ya existente.
Ejercicio paso a paso
Aadir una nueva oficina para la ciudad de Elx, con el nmero de oficina 40, con director 108y con un
objetivo de 100.000.
INSERT INTO oficinas (oficina, ciudad, dir, objetivo) VALUES (40, 'Elx', 108, 100000);
Aadir un nuevo empleado numemp: 115, nombre: Luis Garcia, oficina: 40, sin objetivo ni ventas ni
director.
INSERT INTO empleados (numemp, nombre, oficina) VALUES (115, 'Luis Garcia', 40);
Aadir a la oficina 40un empleado Antonio Garca Lpez, con nmero de empleado 435, contratado
hoy sin ventas con cuota 1200,45 con ttulo Vendedor, de momento no le asignaremos jefe.
INSERT INTO empleados (numemp, nombre, titulo, contrato, ventas, cuota, oficina)
VALUES (435, 'Antonio Garca Lpez','Vendedor', GETDATE(), 0, 1200.45, 40);
Aadir a la oficina 40otro empleado, Luis Valverde, con nmero de empleado 436, con los mismos
datos que el anterior pero su jefe ser el director de la oficina 40(no sabemos qu nmero tiene).
INSERT INTO empleados (numemp, nombre, titulo, contrato, ventas, cuota, oficina, jefe)
SELECT 436, 'Luis Valverde','Vendedor', GETDATE(), 0, 1200.45, 40, dir
FROM oficinas WHERE oficina = 40;
7.5. Insercin de varias filas
8/10/2019 Actualizacion de Datos SQL
6/22
Si los valores que queremos insertar los tenemos en otras tablas, podemos insertar varias filas a la vez
indicando una consulta que genere las filas de valores a insertar. En este caso utilizamos la sintaxis:
INSERT [INTO] [(lista_columnas)]
tabla_derivada[;]
y lista_columnasfuncionan igual que en el punto anterior.
Tabla_derivadaes cualquier instruccin SELECT vlida que devuelva filas con los datos que se van a
cargar en el destino.
Cada fila devuelta por la SELECT es una lista de valores que se intentar insertar como con la clusula
VALUES, por lo que las columnas devueltas por la SELECT debern cumplir las mismas reglas que los
valores de la lista de valores anteriores.
Ejemplo:
CREATE TABLE trabajo (col1 INT, col2 VARCHAR(20), col3 MONEY);
Creamos una tabla trabajo de 3 columnas
INSERT INTO trabajo SELECT oficina, ciudad, ventas
FROM oficinas
WHERE region = 'Centro';
Insertamos en trabajo el resultado de la SELECT (el nmero de oficina, ciudad y ventas de las
oficinas del Centro).
En este caso no hemos incluido una lista de columnas, por lo que en la SELECT tenemos que generar
los valores en el mismo orden que en trabajo.
Si hubiesemos escrito:
INSERT INTO trabajo SELECT ciudad, oficina, ventas
FROM oficinas
WHERE region = 'Centro';
Hubiese dado error porque la columna col1 es INT y el valor a asignar es texto (el nombre de la ciudad
de la oficina).
INSERT INTO trabajo (col2, col1)
SELECT ciudad, oficina
FROM oficinas
8/10/2019 Actualizacion de Datos SQL
7/22
WHERE region = 'Este';
En este caso hemos incluido una lista de columnas, la SELECT debe generar los valores
correspondientes, y col3 que no se rellena explcitamente se rellenar con NULL porque la columna
col3 no est definida como columna calculada, ni con DEFAULT, ni IDENTITY y adems admite nulos.
Objetivo
Copiar un conjunto de filas de una tabla ya existente a otra.
Ejercicio paso a paso
Aadir a la tabla Oeste las oficinas del Este. (6 filas afectadas)
INSERT INTO Oeste SELECT *
FROM oficinas
WHERE region = 'Este';
7.6. Insertar una fila de valores por defecto
TRANSACT-SQL nos permite insertar una fila de valores por defecto utilizando la sintaxis:
INSERT [INTO] DEFAULT VALUES
[;]
Hace que la nueva fila contenga los valores predeterminados definidos para cada columna.Hay que
tener en cuenta una serie de aspectos al utilizar esta instruccin:
Puede generar filas duplicadas en la tabla si los valores que se generan son siempre los mismos.
Si la tabla tiene una clave principal, esta tendr que estar basada en una columna con la propiedad
IDENTITY para que se generen valores diferentes automticamente.
Si una columna est definida como NOT NULL tendr que incluir un DEFAULT o ser una columna
calculada con una expresin compatible.
7.7. Modificar datos almacenados - UPDATE
La sentencia UPDATE modifica los valores de una o ms columnas en las filas seleccionadas de una
nica tabla.
Para modificar los datos de una tabla es necesario disponer del privilegio UPDATE sobre dicha tabla.
UPDATE
8/10/2019 Actualizacion de Datos SQL
8/22
[ TOP (expression )[ PERCENT ] ]
SET { nbcolumna= {expresion| DEFAULT | NULL }
} [ ,...n ]
[ FROM{ }]
[ WHERE ]
[;]
::=
{
[nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTablaVista
}
Con indicamos la tabla que se va a actualizar.
La clusula SET especifica qu columnas van a modificarse y con qu valor, el valor se puede expresar
mediante una expresin, la palabra DEFAULT que equivale al valor predeterminado de la columna, o el
valor nulo NULL.
Las columnas de identidad no se pueden actualizar.
Expresin en cada asignacin debe generar un valor del tipo de dato apropiado para la columna
indicada. La expresin debe ser calculable basada en los valores de la fila actualmente en actualizacin.
Si para el clculo se utiliza una columna que tambin se modifica, el valor que se utilizar es el de antes
de la modificacin, lo mismo para la condicin del WHERE.
Expresintambin puede ser una subconsulta siempre y cuanto devuelva un nico valor y cumpla las
condiciones anteriormente expuestas.
Por ejemplo:
UPDATE oficinas SET ventas = 0;
Actualiza todas las filas de la tabla oficinas dejando el campo ventas con el valor cero.
Si el campo ventas est definido con un valor predeterminado 0, la sentencia anterior equivale a:
UPDATE oficinas SET ventas = DEFAULT;
Si lo que queremos es dejar el campo a nulo:
UPDATE oficinas SET ventas = NULL;
8/10/2019 Actualizacion de Datos SQL
9/22
En una misma sentencia podemos actualizar varias columnas, slo tenemos que indicar las distintas
asignaciones separadas por comas:
UPDATE oficinas SET ventas = 0, objetivo = 0;
Los nombres de columna pueden especificarse en cualquier orden.
Si no queremos actualizar todas las filas de la tabla sino unas cuantas, utilizaremos la clusula TOP, o
unas determinadas, utilizaremos la clusula WHERE.
TOP (expresion)[ PERCENT ]
Especifica el nmero o porcentaje de filas aleatorias que se van a modificar.
expressiondebe generar un valor numrico e indica el nmero de filas a modificar empezando por el
principio. Como en la SELECT, si aadimos la palabra PERCENT, el nmero representado por expresin
se refiere al porcentaje de filas a modificar sobre el total. La clusula TOP funciona casi igual que en laSELECT pero en este caso, las filas no se ordenan, y la expresin debe ir entre parntesis.
Por ejemplo:
UPDATE TOP (10) PERCENT oficinas
SET ventas = 0;
Actualiza el 10% de filas de la tabla oficinas.
[ WHERE ]
Utilizamos la clusula WHERE para filtrar las filas a actualizar. Se actualizarn todas las filas que
cumplan la condicin. Por ejemplo si queremos actualizar slo las oficinas del Este:
UPDATE oficinas
SET ventas = 0
WHERE region = 'Este';
Cuando para la condicin de la clusula WHERE necesitamos un dato de otra tabla podemos utilizar
una subconsulta:
UPDATE empleados SET ventas = 0
WHERE oficina IN (SELECT oficina
FROM oficinas
WHERE region = 'Este');
8/10/2019 Actualizacion de Datos SQL
10/22
Cuando el campo de la otra tabla se utiliza para la clusula SET, entonces debemos utilizar la clusula
FROM.
La clusula FROM permite definir un origen de datos basado en varias tablas, y ese origen ser el
utilizado para realizar la actualizacin.
Por ejemplo queremos actualizar el importe de los pedidos con el precio de la tabla productos.
UPDATE pedidos SET importe = cant * precio
FROM pedidos INNER JOIN productos
ON fab = idfab AND producto = idproducto;
Modificamos la tablapedidosdejando en la columna importeel resultado de multiplicar la cantidaddel
pedido por elpreciodel producto que se encuentra en la tablaproductos.
Si la actualizacin de una fila infringe una restriccin o una regla, infringe la configuracin de valores
NULL de la columna o si el nuevo valor es de un tipo de datos incompatible con la columna, se cancela
la instruccin, se devuelve un error y no se actualiza ningn registro.
Cuando una instruccin UPDATE encuentra un error aritmtico (error de desbordamiento, divisin por
cero o de dominio) durante la evaluacin de la expresin, la actualizacin no se lleva a cabo. El resto
del lote no se ejecuta y se devuelve un mensaje de error.
Adems del permiso de UPDATE, se requieren permisos SELECT para la tabla que se actualiza si la
instruccin UPDATE contiene una clusula WHERE o en el caso de que el argumento expressionde la
clusula SET utilice una columna de la tabla, y permisos SELECT para la tabla del origen si utilizamos
una clusula FROM o un WHERE con subconsulta.
Objetivo
Modificar los datos de una tabla.
Ejercicio paso a paso
Subir un 5% el precio de todos los productos del fabricante QSA. (3 filas afectadas)
UPDATE productos SET precio = ROUND(precio * 1.05,2)
WHERE idfab = 'qsa';
Resultado:
idfab idproducto precio
qsa xk47 3,73
qsa xk48 1,41
8/10/2019 Actualizacion de Datos SQL
11/22
qsa xk48a 1,55
Poner a cero las ventas y cuota del empleado Luis Garcia, si hay varios con el mismo nombre
actualizarlos todos. (1 filas afectadas)
UPDATE empleados set ventas=0, cuota=0
WHERE nombre = 'Luis Garcia';
Cambiar los empleados de la oficina 40 a la oficina 30. (3 filas afectadas)
UPDATE empleados SET oficina = 30
WHERE oficina = 40;
Actualizar los pedidos del fabricante rei dejando como representante el empleado asignado al cliente(2 filas afectadas). Lo ms cmodo es, primero sacar la consulta que obtiene los pedidos a actualizar, y
despus convertirla a UPDATE.
UPDATE pedidos SET rep=numemp
FROM pedidos inner join (clientes inner join empleados ON repclie=numemp) ON clie=numclie
WHERE rep numemp and fab ='rei'
Estos son los pedidos afectados y cmo deben quedar, los pedidos en los que el representante ya es el
correcto no se tienen que actualizar:
codigo numpedido clie rep fab
20 113042 2113 104 rei
21 113045 2112 108 rei
Actualizar el campo objetivo de la oficina 30 con las cuotas de los empleados asignados a ella.
UPDATE oficinas set oficinas.objetivo =(SELECT SUM (cuota)
from empleados where oficinas.oficina= empleados.oficina)
where oficina=30;
Actualizar el precio de los productos de BIC obteniendo el nuevo valor del precio medio del artculo
vendido en los pedidos (si hay pedidos). Primero sacamos la lista y despus redactar la UPDATE. Se puede
hacer de dos formas, actualizando nicamente los productos de BIC que tienen pedidos, o actualizando
8/10/2019 Actualizacion de Datos SQL
12/22
todos los productos de BIC. En cualquiera de los dos casos los productos debern acabar con el precio
que aparece en la columna Nuevo.
UPDATE productos SET precio = round(ISNULL((SELECT avg(importe/cant) FROM pedidos WHERE
fab=idfab and producto=idproducto),precio),2)
WHERE idfab='bic';
Estos son los productos que tenemos de BIC, precio es el precio actual, media es el precio medio de
pedidos, y nuevo el valor que deber quedar en precio despus de actualizar:
idfab idproducto precio media nuevo
bic 41003 6,52 5,1566 5,16
bic 41089 2,25 NULL 2,25
bic 41672 1,80 NULL 1,80
7.8. Eliminar filas - DELETE
La sentencia DELETE elimina filas de una tabla. Si se borran todas las filas, o se borra la nica fila de una
tabla, la definicin de la tabla no desaparece, slo que la tabla se queda vaca.
DELETE
[ TOP (expression )[ PERCENT ] ] [ FROM ]
[ FROM ]
[ WHERE < condicion>]
[; ]
::=
{
[nbBaseDatos.nbEsquema.| nbEsquema.]nbTablaVista
}
Con esta instruccin podemos eliminar una o varias filas de una tabla.
La palabra FROM (la primera) es opcional (originalmente era obligatorio) y no aade funcionalidad slo
sirve para introducir el destino.
es el nombre de la tabla de donde queremos eliminar las filas, puede ser un nombre de tabla
o un nombre de vista (de momento basada en una slo tabla).
8/10/2019 Actualizacion de Datos SQL
13/22
La segunda clusula FROM sirve para indicar un origen que permita una condicin de WHERE sobre
una tabla diferente de destino.
La instruccin bsica sera pues:
DELETE oficinas;
Equivalente a:
DELETE FROM oficinas;
Con esta instruccin eliminamos todas las filas de la tabla oficinas.
La clusula WHERE permite eliminar determinadas filas, indica una condicin que deben cumplir las
filas que se eliminan.
Por ejemplo:
DELETE oficinas
WHERE region = Este;
Elimina las oficinas del Este.
TOP (expresion)[ PERCENT ]
Especifica el nmero o porcentaje de filas aleatorias que se van a eliminar.
expressiondebe generar un valor numrico e indica el nmero de filas a eliminar empezando por el
principio. Como en la SELECT, si aadimos la palabra PERCENT, el nmero representado por expresin
se refiere al porcentaje de filas a eliminar sobre el total. La clusula TOP funciona casi igual que en la
SELECT pero en este caso, las filas no se ordenan, y la expresin debe ir entre parntesis.
Por ejemplo:
DELETE TOP (10) PERCENT
FROM oficinas;
Elimina el 10% de filas de la tabla oficinas.
Originalmente slo se poda indicar una tabla en la clusula FROM, pero ahora podemos indicar un
origen basado en varias tablas.
Si utilizamos un origen basado en varias tablas, se debe de utilizar una extensin de TRANSACT-SQL
que consiste en escribir dos clusulas FROM, una indica la tabla de donde eliminamos las filas y la otra
el origen que utilizamos para eliminar.
8/10/2019 Actualizacion de Datos SQL
14/22
Este caso se produce cuando las filas a eliminar dependen de un valor que est en otra tabla. Por
ejemplo queremos eliminar los empleados de las oficinas del Este. Como la regin de la oficina no est
en empleados, habra que aadir al origen la tabla oficinas para poder formular la condicin del
WHERE:
DELETE FROM empleados
FROM empleados INNER JOIN oficinas
ON empleados.oficina = oficinas.oficina
WHERE region = 'Este';
En el origen tenemos las dos tablas y en la primera FROM indicamos de qu tabla queremos borrar.
Esto se poda haber resuelto, como toda la vida, mediante una subconsulta:
DELETE FROM empleados
WHERE oficina IN (SELECT oficina
FROM oficinas
WHERE region = 'Este');
Para finalizar no debemos olvidar que para poder ejecutar un DELETE se requieren permisos DELETE en
la tabla de donde vamos a eliminar, y tambin se requieren los permisos para utilizar SELECT si la
instruccin contiene una clusula WHERE.
Muy importante siempre que actualicemos datos en nuestras tablas, no debemos olvidar tampoco las
reglas de integridad referencial. Si la tabla afectada interviene como tabla principal en una relacin con
otra tabla, no se podrn eliminar sus filas que estn relacionadas con registros de la otra tabla (no sepueden eliminar padres que tengan hijos ). Si se van a eliminar varias filas y al menos una no se
puede eliminar por infringir las reglas de integridad, entonces la operacin abortar y no se eliminar
ninguna fila.
En el ejemplo anterior, si un empleado asignado a una oficina del Este tiene pedidos, no se podr
eliminar y entonces no se eliminar ningn empleado.
Objetivo
Eliminar registros de una tabla utilizando DELETE.
Ejercicio paso a paso
Eliminar el empleado 435.
DELETE empleados
WHERE numemp = 435;
8/10/2019 Actualizacion de Datos SQL
15/22
Eliminar los pedidos del representante 105. (5 filas afectadas)
DELETE FROM pedidos
WHERE rep = 105;
7.9. Borrado masivo - TRUNCATE
Si queremos eliminar todas las filas de una tabla podemos utilizar tambin la instruccin TRUNCATE
TABLE.
TRUNCATE TABLE
[nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTabla [; ]
Esta sentencia quita todas las filas de una tabla sin registrar las eliminaciones individuales de filas.
Desde un punto de vista funcional, TRUNCATE TABLE es equivalente a la instruccin DELETE sin unaclusula WHERE; no obstante, TRUNCATE TABLE es ms rpida y utiliza menos recursos de registros de
transacciones y de sistema.
En comparacin con la instruccin DELETE, TRUNCATE TABLE ofrece las siguientes ventajas:
Se utiliza menos espacio del registro de transacciones.
La instruccin DELETE quita una a una las filas y graba una entrada en el registro de
transacciones por cada fila eliminada.
TRUNCATE TABLE quita los datos al cancelar la asignacin de las pginas de datos utilizadas para
almacenar los datos de la tabla y slo graba en el registro de transacciones las cancelaciones de
asignacin de pginas.
Por regla general, se utilizan menos bloqueos.
Si se ejecuta la instruccin DELETE con un bloqueo de fila, se bloquea cada fila de la tabla para su
eliminacin. TRUNCATE TABLE siempre bloquea la tabla y la pgina, pero no cada fila.
Las pginas cero se conservan en la tabla sin excepciones.
Despus de ejecutar una instruccin DELETE, la tabla puede seguir conteniendo pginas vacas.
Por ejemplo, no se puede cancelar la asignacin de las pginas vacas de un montn sin un
bloqueo de tabla exclusivo como mnimo. Si en la operacin de eliminacin no se utiliza un
bloqueo de tabla, la tabla contiene muchas pginas vacas. En el caso de los ndices, la operacin
de eliminacin puede dejar pginas vacas, aunque la asignacin de estas pginas se puede
cancelar rpidamente mediante un proceso de limpieza en segundo plano.
Si la tabla contiene una columna de identidad, el contador para dicha columna se restablece al
valor de inicializacin definido para ella. Si no se define ningn valor de inicializacin, se utiliza el
valor predeterminado 1. Para conservar el contador de identidad, se utiliza DELETE.
Pero no todo son ventajas, no se puede utilizar TRUNCATE TABLE en las siguientes tablas:
Tablas a las que se hace referencia mediante una restriccin FOREIGN KEY (las tablas que entran
como principales en una relacin).
Tablas que participan en una vista indizada.
Ejercicios unidad 7: Actualizacin de datos (I)
8/10/2019 Actualizacion de Datos SQL
16/22
1. Aadir a la oficina 40 otro empleado, Luis Valverde, con nmero de empleado 436, con los
mismos datos que el anterior pero su jefe ser el director de la oficina 40(no sabemos qu nmero
tiene).
2. Pasar los pedidos de octubre 1989a diciembre 2008. (3 filas afectadas)
3. Queremos actualizar el importe de los pedidos del mes actual con el precio almacenado en latabla productos.
Ayuda: En un primer paso obtener los pedidos del mes actual obteniendo tambin el precio unitario
dentro del pedido y el precio del producto de la tabla de productos.
codigo numpedido fechapedido cant importe precio pedido precio
1 110036 2008-12-12 00:00:00.000 9 22,50 2,50 NULL
2 110037 2008-12-12 00:00:00.000 7 31,50 4,50 45,00
6 112979 2008-12-12 00:00:00.000 6 150,00 25,00 NULL
9 112989 2008-12-10 00:00:00.000 6 14,58 2,43 2,43
16 113013 2008-12-28 00:00:00.000 1 6,52 6,52 5,16
Actualizar despus la tabla de pedidos cambiando los importes para que el precio unitario corresponda
con el precio del producto. Los pedidos de los productos que no tienen precio se quedarn como
estaban. (3 filas afectadas)
codigo numpedido fechapedido cant importe precio pedido precio
1 110036 2008-12-12 00:00:00.000 9 22,50 2,50 NULL
2 110037 2008-12-12 00:00:00.000 7 315,00 4,50 45,00
6 112979 2008-12-12 00:00:00.000 6 150,00 25,00 NULL
9 112989 2008-12-10 00:00:00.000 6 14,58 2,43 2,43
16 113013 2008-12-28 00:00:00.000 1 5,16 6,52 5,16
1.
Se ven algunos productos que no tienen precio, ahora vamos a actualizar el precio de estos
productos con el precio medio utilizado en los pedidos donde aparecen.
2. Ayuda: Primero sacamos los productos que queremos actualizar con los pedidos
correspondientes:
8/10/2019 Actualizacion de Datos SQL
17/22
idfab idproducto precio codigo numpedido fechapedido importe precio pedido
aci 41001 NULL NULL NULL NULL NULL NULL
aci 41002 NULL 10 112992 1990-04-15 20:00:00.000 7,60 0,76
aci 41002 NULL 18 113027 2008-02-05 00:00:00.000 450,00 8,3333
aci 41003 NULL 15 113012 2008-05-05 00:00:00.000 37,45 1,07
aci 41004 NULL 3 112963 2008-05-10 00:00:00.000 3,276 0,117
aci 41004 NULL 4 112968 1990-01-11 00:00:00.000 39,78 1,17
aci 41004 NULL 7 112983 2008-05-10 00:00:00.000 7,02 1,17
aci 4100x NULL 25 113055 2009-04-01 00:00:00.000 1,50 0,25
aci 4100x NULL 26 113057 2008-11-01 00:00:00.000 NULL NULL
aci 4100y NULL 8 112987 2008-01-01 00:00:00.000 275,00 25,00
aci 4100z NULL 1 110036 2008-12-12 00:00:00.000 22,50 2,50
aci 4100z NULL 6 112979 2008-12-12 00:00:00.000 150,00 25,00
Vemos que el producto ACI 41001no se podr actualizar porque no tiene pedidos. Pero los dems
se actualizarn con el precio medio de sus pedidos, debern quedar as (7 filas afectadas):
idfab idproducto precio
aci 41001 NULL
aci 41002 4,55
aci 41003 1,07
aci 41004 0,82
aci 4100x 0,25 *
aci 4100y 25,00
aci 4100z 13,75
8/10/2019 Actualizacion de Datos SQL
18/22
* aci 4100x tiene 2 pedidos pero uno sin precio por lo que no cuenta
Puedes consultaraqu las soluciones propuestas.
1. Aadir a la oficina 40otro empleado, Luis Valverde, con nmero de empleado 436, con los mismos
datos que el anterior pero su jefe ser el director de la oficina 40(no sabemos qu nmero tiene).
INSERT INTO empleados (numemp, nombre, titulo, contrato, ventas, cuota, oficina, jefe)
SELECT 436, 'Luis Valverde','Vendedor', GETDATE(), 0, 1200.45, 40, dir
FROM oficinas WHERE oficina = 40;
2. Pasar los pedidos de octubre 1989a diciembre 2008. (3 filas afectadas)
UPDATE pedidos SET fechapedido=DATEADD(month,230,fechapedido)
WHERE year(fechapedido)=1989 and month(fechapedido)=10;
3. Queremos actualizar el importe de los pedidos del mes actual con el precio almacenado en la tabla
productos.
SELECT codigo, numpedido,fechapedido,cant, importe,importe/cant AS [precio pedido],precio
FROM pedidos inner join productos ON fab=idfab and producto = idproducto
WHERE YEAR(fechapedido)=YEAR(GETDATE()) and MONTH(fechapedido)=MONTH(GETDATE())
Actualizar despus la tabla de pedidos cambiando los importes para que el precio unitario corresponda
con el precio del producto. Los pedidos de los productos que no tienen precio se quedarn como
estaban. (3 filas afectadas)
UPDATE pedidos SET importe=cant*precio
FROM pedidos inner join productos ON fab=idfab and producto = idproducto
WHERE year(fechapedido)=2008 and month(fechapedido)=12 AND precio IS NOT NULL;
4. Se ven algunos productos que no tienen precio, ahora vamos a actualizar el precio de estos
productos con el precio medio utilizado en los pedidos donde aparecen. La primera SELECT saca los
productos que queremos actualizar con los pedidos correspondientes.
SELECT idfab, idproducto, precio, codigo, numpedido,fechapedido,importe, importe/cant
FROM productos left join pedidos on idfab=fab AND idproducto=producto
WHERE precio IS NULL;
http://www.aulaclic.es/sqlserver/spr_7_6_1.htmhttp://www.aulaclic.es/sqlserver/spr_7_6_1.htm8/10/2019 Actualizacion de Datos SQL
19/22
UPDATE productos SET precio = (SELECT ROUND(AVG(importe/cant),2) FROM pedidos WHERE
fab=idfab AND producto=idproducto)
WHERE precio IS NULL
5. Eliminar los pedidos del representante Luis Antonio. (2 filas afectadas)
DELETE FROM pedidos
WHERE rep IN (SELECT numemp FROM empleados
WHERE nombre = 'Luis Antonio');
6. Eliminar las oficinas que no tengan empleados. (11 filas afectadas)
DELETE oficinas
WHERE NOT EXISTS (SELECT *
FROM empleados WHERE empleados.oficina =
oficinas.oficina);
7. Intenta eliminar el empleado 102. Te saldr un error : "Instruccin DELETE en conflicto con la
restriccin..."
DELETE empleados WHERE numemp=102;
Reflexiona sobre el error y elabora una consulta que liste los empleados que pueden dar problemas
(aqu no se trata de utilizar operaciones aprendidas en este tema sino de practicar la integridadreferencial y de paso recordar instrucciones vistas en temas anteriores).
SELECT * from empleados
WHERE numemp IN (select jefe from empleados)
UNION ALL
SELECT * FROM empleados
WHERE numemp IN (SELECT dir FROM oficinas)
UNION ALL
SELECT * FROM empleados
WHERE numemp IN (SELECT rep FROM pedidos)
UNION ALL
SELECT * FROM empleados
WHERE numemp IN (SELECT repclie FROM clientes)
8/10/2019 Actualizacion de Datos SQL
20/22
ORDER BY numemp
Elabora ahora una consulta que liste los que se pueden borrar sin problemas.
SELECT numemp FROM empleados
EXCEPT
SELECT numemp from empleados
WHERE numemp IN (select jefe from empleados)
EXCEPT
SELECT numemp FROM empleados
WHERE numemp IN (SELECT dir FROM oficinas)
EXCEPT
SELECT numemp FROM empleados
WHERE numemp IN (SELECT rep FROM pedidos)
EXCEPT
SELECT numemp FROM empleados
WHERE numemp IN (SELECT repclie FROM clientes)
ORDER BY numemp
Borra el primero de la lista, ste s lo puedes borrar.
DELETE empleados WHERE numemp=112;
8. Eliminar los pedidos de productos de ACI cuyo precio de venta en el pedido no corresponda con el
precio unitario del producto de la tabla de productos. (4 filas afectadas)
DELETE FROM pedidos
WHERE fab = 'ACI' AND Importe/cant (SELECT precio FROM productos WHERE fab = idfab AND
idproducto = producto);
9. Ahora vamos a recuperar las tablas tal cual estaban al principio, para ello utilizaremos las copiasrealizadas al principio de Nuevaoficinas, etc. Lo ms cmodo ser vaciar las tablas y rellenarlas de
nuevo con los datos de las tablas Nueva...
Empieza por eliminar los datos de las tablas. Utilizamos TRUNCATE en la tabla pedidos porque no est
referenciada y para que el contador empiece desde 1 otra vez
TRUNCATE TABLE pedidos
8/10/2019 Actualizacion de Datos SQL
21/22
DELETE productos
DELETE clientes
UPDATE oficinas SET dir = NULL; -- Para poder borrar los empleados
UPDATE empleados SET oficina=NULL, jefe=NULL; -- Para poder borrar las oficinas y los empleados
respectivamente.
DELETE oficinas;
DELETE empleados;
Inserta los datos de las tablas Nueva.. a las tablas normales.
INSERT INTO oficinas (oficina, ciudad, region,objetivo,ventas)
SELECT oficina, ciudad, region,objetivo,ventas
FROM Nuevaoficinas;
No podemos rellenar todava la columna Dirya que no tenemos los empleados dado de alta.
INSERT INTO empleados (numemp, nombre, edad, oficina,titulo,contrato,cuota,ventas)
SELECT numemp, nombre, edad, oficina,titulo,contrato,cuota,ventas
FROM NuevaEmpleados;
Lo mismo pasa con la columnajefe.
UPDATE empleados SET jefe=nueva.jefe
FROM empleados INNER JOIN NuevaEmpleados nueva ON empleados.numemp=nueva.numemp
Estas dos ltimas sentencias se podan haber resumido en una:
INSERT INTO empleados
SELECT *
FROM NuevaEmpleados;
Las hemos dejado en dos porque con otros SQLs no se podra hacer en un slo paso.
UPDATE oficinas SET dir = (SELECT dir FROM Nuevaoficinas nueva
WHERE
oficinas.oficina=nueva.oficina)
8/10/2019 Actualizacion de Datos SQL
22/22
INSERT INTO clientes (numclie,nombre,repclie,limitecredito)
SELECT numclie,nombre,repclie,limitecredito
FROM Nuevaclientes;
INSERT INTO productos
SELECT *
FROM Nuevaproductos;
INSERT INTO pedidos (numpedido,fechapedido,clie,rep,fab,producto,cant,importe)
SELECT numpedido,fechapedido,clie,rep,fab,producto,cant,importe
FROM Nuevapedidos;