Está en la página 1de 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 el
entorno 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_NuevaTabla es 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

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 las
tablas 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 que
oficinas. (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 SQL
que lo permite es la orden INSERT (o tambin denominada INSERT INTO).
De la sentencia INSERT completa, nosotros estudiaremos la sintaxis ms utilizada y estndar:

INSERT [INTO] <destino>


{
[(lista_columnas)]
{VALUES ({DEFAULT|NULL|expresion}[ ,...n ])
|tabla_derivada
}
}
|DEFAULT VALUES
[;]

<destino> ::=
{
[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] <destino> [(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 <destino>.<destino> 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 debern
aparecer 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.

Mediante la palabra reservada NULL valor nulo.


Delante de VALUES, de forma opcional podemos indicar una lista de columnas entre parntesis. Las
columnas son columnas del destino.
Cuando indicamos nombres de columnas, esas columnas sern las que reciban los valores a insertar, la
asignacin de valores se realiza por posicin, la primera columna recibe el primer valor, la segunda
columna el segundo, y as sucesivamente.
En la lista, las columnas pueden estar en cualquier orden y tambin se pueden omitir algunas
columnas.
Una columna que no aparezca en la lista de columnas se rellenar de acuerdo a su definicin:
Con su valor por defecto si est definida con la clusula DEFAULT
Con el valor de identidad incremental siguiente si tiene la propiedad IDENTITY.
Con el valor calculado si es una columna calculada.
Con el valor NULL , en cualquier otro caso y si la columna lo admite.
Cuando no se indica una lista de columnas el sistema asume por defecto todas las columnas de la tabla
y en el mismo orden que aparecen en la definicin de la tabla, en este caso, los valores se tienen que
especificar en el mismo orden que las columnas en la definicin de la tabla, y se tiene que especificar
un valor por cada columna ya que los valores se rellenan por posicin, la primera columna recibe el
primer valor, la segunda columna el segundo, y as sucesivamente.
En cualquier caso, el nmero de valores debe coincidir con el nmero de columnas y los tipos de dato
de los valores deben ser compatibles con las columnas.
Aunque pueda parecer ms engorroso escribir la lista de columnas, es un hbito recomendable, hace
que la sentencia sea ms fcil de leer y mantener (cuando leemos la sentencia sabemos en qu
columnas asignamos los valores sin necesidad de consultar la definicin de la tabla) y evita que se
tenga que cambiar la sentencia si se modifica el esquema de la tabla (si el orden de las columnas
dentro de la tabla cambia).
Los registros se agregan al final de la tabla.
Cuando se insertan nuevas filas en una tabla, el sistema comprobar que la nueva fila no infrinja
ninguna regla de integridad, por ejemplo no podremos asignar a una columna PRIMARY KEY un valor
nulo o que ya exista en la tabla, a una columna UNIQUE un valor que ya exista en la tabla, a una
columna NOT NULL un valor NULL, a una clave ajena (FOREIGN KEY) un valor que no exista en la tabla
de referencia.
De producirse alguna de las situaciones anterior, la instruccin genera un mensaje de error y la fila no
se inserta.
Ejemplos.
INSERT INTO oficinas (oficina, ciudad) VALUES (26, 'Elx');

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 108 y 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 40 un 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 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).
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

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] <destino> [(lista_columnas)]
tabla_derivada [;]
<destino> y lista_columnas funcionan igual que en el punto anterior.
Tabla_derivada es 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

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] <destino> 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

[ TOP ( expression ) [ PERCENT ] ]


<destino>
SET { nbcolumna = { expresion | DEFAULT | NULL }
} [ ,...n ]
[ FROM{ <origen> }]
[ WHERE <condicion> ]
[;]
<destino> ::=
{
[nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTablaVista
}
Con <destino> 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.
Expresin tambin 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;

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.
expression debe 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 la
SELECT 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 <condicion> ]
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');

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 tabla pedidos dejando en la columna importe el resultado de multiplicar la cantidad del
pedido por el precio del producto que se encuentra en la tabla productos.
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 expression de 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

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

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 ] <destino>
[ FROM <origen>]
[ WHERE < condicion>]
[; ]
<destino> ::=
{
[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.
<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).

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.
expression debe 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.

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 se
pueden 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;

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 una
clusula 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)

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 1989 a diciembre 2008. (3 filas afectadas)
3. Queremos actualizar el importe de los pedidos del mes actual con el precio almacenado en la
tabla 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

110036

2008-12-12 00:00:00.000

22,50

2,50

NULL

110037

2008-12-12 00:00:00.000

31,50

4,50

45,00

112979

2008-12-12 00:00:00.000

150,00

25,00

NULL

112989

2008-12-10 00:00:00.000

14,58

2,43

2,43

16

113013

2008-12-28 00:00:00.000

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

110036

2008-12-12 00:00:00.000

22,50

2,50

NULL

110037

2008-12-12 00:00:00.000

315,00

4,50

45,00

112979

2008-12-12 00:00:00.000

150,00

25,00

NULL

112989

2008-12-10 00:00:00.000

14,58

2,43

2,43

16

113013

2008-12-28 00:00:00.000

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:

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

112963

2008-05-10 00:00:00.000

3,276

0,117

aci

41004

NULL

112968

1990-01-11 00:00:00.000

39,78

1,17

aci

41004

NULL

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

112987

2008-01-01 00:00:00.000

275,00

25,00

aci

4100z

NULL

110036

2008-12-12 00:00:00.000

22,50

2,50

aci

4100z

NULL

112979

2008-12-12 00:00:00.000

150,00

25,00

Vemos que el producto ACI 41001 no 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

* aci 4100x tiene 2 pedidos pero uno sin precio por lo que no cuenta
Puedes consultar aqu las soluciones propuestas.
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).
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 1989 a 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;

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 integridad
referencial 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)

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 copias
realizadas 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

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 Dir ya 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 columna jefe.
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)

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;

También podría gustarte