Actualizacion de Datos SQL

download Actualizacion de Datos SQL

of 22

Transcript of Actualizacion de Datos SQL

  • 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.htm
  • 8/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;