Вы находитесь на странице: 1из 46

Crear vistas y

procedimientos
almacenados
Ahora que Mary puede tener acceso a la base de datos TestData, puede que desee
crear algunos objetos de base de datos, como una vista o un procedimiento
almacenado y concederle a Mary acceso a los mismos. Una vista es una instruccin
SELECT almacenada y un procedimiento almacenado es una o varias instrucciones
Transact-SQL que se ejecutan como un lote.
Las vistas se consultan como las tablas y no aceptan parmetros. Los
procedimientos almacenados son ms complejos que las vistas. Los procedimientos
almacenados pueden tener parmetros de entrada y salida y pueden contener
instrucciones para controlar el flujo del cdigo, como instrucciones IF y WHILE. Una
prctica recomendable de programacin es usar procedimientos almacenados para
realizar todas las tareas repetitivas en la base de datos.
Para este ejemplo, usar CREATE VIEW para crear una vista que seleccione solo dos
de las columnas de la tabla Products. A continuacin, usar CREATE PROCEDURE
para crear un procedimiento almacenado que acepta un parmetro de precio y
devuelve solo los productos cuyo costo es menor que el valor del parmetro
especificado.

Para crear una vista

Ejecute la instruccin siguiente para crear una vista muy sencilla que ejecuta
una instruccin SELECT y devuelve los nombres y los precios de nuestros
productos al usuario.
CREATE VIEW vw_Names
AS
SELECT ProductName, Price FROM Products;
GO

Pruebe la vista

Las vistas se tratan como tablas. Use una instruccin SELECT para tener
acceso a la vista.
SELECT * FROM vw_Names;
GO

Para crear un procedimiento almacenado

La siguiente instruccin crea un procedimiento almacenado


denominado pr_Names, acepta un parmetro de entrada
denominado @VarPrice del tipo de datos money.El procedimiento
almacenado imprime la instruccin Products less than concatenada con el
parmetro de entrada que cambia del tipo de datos money a un tipo de
datos de carcter varchar(10). A continuacin, el procedimiento ejecuta una

instruccin SELECT en la vista y le pasa el parmetro de entrada como parte


de la clusula WHERE. Esto devuelve todos los productos cuyo costo es
menor que el valor del parmetro de entrada.
CREATE PROCEDURE pr_Names @VarPrice money
AS
BEGIN
-- The print statement returns text to the user
PRINT 'Products less than ' + CAST(@VarPrice AS
varchar(10));
-- A second statement starts here
SELECT ProductName, Price FROM vw_Names
WHERE Price < @varPrice;
END
GO

Probar el procedimiento almacenado

Para probar el procedimiento almacenado, escriba y ejecute la instruccin


siguiente. El procedimiento debe devolver los nombres de dos productos
introducidos en la tabla Products en la leccin 1 con un precio menor
que 10.00.
EXECUTE pr_Names 10.00;
GO

7. Vistas, Procedimientos y Trigger


7. Vistas, Procedimientos y Triggers
VISTAS
Una vista es una consulta, que refleja el contenido de una o ms tablas, desde la que se puede
acceder a los datos como si fuera una tabla.
Dos son las principales razones por las que podemos crear vistas.

Seguridad, nos pueden interesar que los usuarios tengan acceso a una parte de la
informacin que hay en una tabla, pero no a toda la tabla.
Comodidad, como hemos dicho el modelo relacional no es el ms comodo para visualizar
los datos, lo que nos puede llevar a tener que escribir complejas sentencias SQL, tener una
vista nos simplifica esta tarea.
Las vistas no tienen una copia fsica de los datos, son consultas a los datos que hay en las
tablas, por lo que si actualizamos los datos de una vista, estamos actualizando realmente la
tabla, y si actualizamos la tabla estos cambios sern visibles desde la vista.
Nota: No siempre podremos actualizar los datos de una vista, depender de la complejidad de
la misma (depender de si el conjunto de resultados tiene acceso a la clave principal de la tabla
o no), y del gestor de base de datos. No todos los gestores de bases de datos permiten
actualizar vistas, ORACLE, por ejemplo, no lo permite, mientras que SQL Server s.

7.1 Creacin de vistas.


Para crear una vista debemos utilizar la sentencia CREATE
proporcionar un nombre a la vista y una sentencia SQL SELECT vlida.

VIEW, debiendo

CREATE VIEW <nombre_vista>


AS
(<sentencia_select>);
Ejemplo: Crear una vista sobre nuestra tabla alquileres, en la que se nos muestre el nombre y
apellidos del cliente en lugar de su cdigo.

CREATE VIEW

vAlquileres

AS
(
SELECT nombre, apellidos,
matricula
FROM tAlquileres, tClientes
WHERE ( tAlquileres.codigo_cliente

tClientes.codigo

Si queremos, modificar la definicin de nuestra vista podemos utilizar la sentencia ALTER


VIEW, de forma muy parecida a como lo haciamos con las tablas. En este caso queremos
aadir los campos fx_alquiler y fx_devolucion a la vista.
ALTER

VIEW

vAlquileres

AS
(
SELECT nombre, apellidos,
matricula, fx_alquiler, fx_devolucion
FROM tAlquileres, tClientes
WHERE ( tAlquileres.codigo_cliente
)

tClientes.codigo

Por ltimo podemos eliminar la vista a travs de la sentencia DROP VIEW. Para eliminar la
vista que hemos creado anteriormente se uitlizara:
DROP VIEW vAlquileres;

Una vista se consulta como si fuera una tabla. Ejemplo:


USE NORTHWIND GO
--CREACION DE VISTA PROVEEDORES Y SUS PEDIDOS
CREATE VIEW VIEW_SUPPLIER_PRODUCS
AS
SELECT S.SUPPLIERID,S.COMPANYNAME,S.CONTACTNAME
,P.PRODUCTID,P.PRODUCTNAME, P.UNITPRICE FROM SUPPLIERS AS S INNER JOIN
PRODUCTS AS P ON
S.SUPPLIERID=P.SUPPLIERID GO
--CREACION DE UNA VISTA CON INSTRUCCION GROUP
CREATE VIEW VIEW_SUBTOTALES(CODIGO_ORDEN,SUB_TOTAL)
AS
SELECT OD.ORDERID,SUM(CONVERT(MONEY,(OD.UNITPRICE* QUANTITY*(1DISCOUNT)/100))*100)
FROM [ORDER DETAILS] OD GROUP BY OD.ORDERID
GO
--LLAMAR A LA CONSULTA ANTERIOR SELECT * FROM VIEW_SUBTOTALES
--VER VISTAS
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='VIEW'
--BORRAR UNA VISTA
DROP VIEW VIEW_SUBTOTALES
--ALTERAR UNA VISTA
ALTER VIEW VIEW_SUPPLIER_PRODUCS AS
7.2 PROCEDIMIENTOS
Que son procedimientos Almacenados: Es un conjunto de cdigo puro del lenguaje que
utilizamos dentro de las bases de datos como por ejemplo: create table, insert into, Select from.
Que se almacena fsicamente en la base de datos y de la misma forma se exportan cuando
creamos una copia de seguridad de nuestra base de datos.
Como funcionan: Los procedimientos almacenados se basan en una estructura definida por
SQL SERVER.
Iniciamos con:

CREATE PROCEDURE nombre_del_procedimiento @variables tipo(longitud) }


AS

BEGIN
Todo el codigo puro de base de datos
END
Como probamos: Esto es lo ms fcil de realizar solo necesitamos lo siguiente: Escribimos
EXEC nombre_del_procedimiento ' variables',12,' variables'
Nota: Cabe destacar que no necesariamente se deben definir variables en el caso de un Select
* From solo pondremos EXEC y nombre del procedimiento
Vamos a realizar un ejemplo

Creemos una base de datos con el nombre que decidamos


Creemos la siguiente tabla.

Ahora definimos el procedimiento almacenado para insertar un nuevo registro(Recordemos


que todo lo que est dentro del Begin puede ser cualquier sentencia de cdigo puro de SQL
SERVER: Insert into, Delete From, Update set, etc) .

Ejecutamos el cogido y ahora probamos con los siguientes datos:

Codigo: 001 ; Nombre: Patricia ; Apellido: Colimba ; Edad: 21; Universidad: UTN
Ejecutamos el procedimiento almacenado con los datos anteriores tomando en
consideracin que: los campos tipo int se envan sin comilla el resto dentro de comilla.
Para ejecutar el procedimiento almacenado escribimos EXEC + el nombre del
procedimiento + las variables si fuera el caso y clic en ejecutar

Ahora revisamos en nuestra tabla y tenemos lo siguiente:

Como podemos ver funciona sin ningn problema


Nota: Todas las sentencias de SQL SERVER se pueden enviar dentro de un procedimiento
almacenado, inclusive inner joins, busquedas &like entre otras.

7.3 TRIGGERS
Un trigger( o desencadenador) es una clase especial de procedimiento
almacenado que se ejecuta automticamente cuando se produce un evento en el servidor de
bases de datos.

La estructura de un trigger es:

Create Trigger pr_usuarios_Trigger1


On dbo.pr_usuarios
For /* Insert, Update, Delete */ As

Los triggers pueden incluir cualquier nmero y clase de instruccin de Transact- SQL.
Desde el Trigger podremos obtener los datos de la fila que se ha modificado o aadido
utilizando inserted o deleted:

Select * from deleted

Limitaciones de los triggers.


- Solo se pueden aplicar a una tabla especfica, es decir, un trigger no sirve para dos o ms
tablas
- El trigger se crea en la base de datos que de trabajo pero desde un trigger puedes hacer
referencia a otras bases de datos.
- Un Trigger devuelve resultados al programa que lo desencadena de la misma forma que un
Stored Procedure aunque no es lo mas idoneo, para impedir que una instruccin de asignacin
devuelva un resultado se puede utilizar la sentencia SET NOCOUNT al principio del Trigger.
- Las siguientes instrucciones no se pueden utilizar en los triggers :

ALTER DATABASE CREATE DATABASE DISK INIT DISK RESIZE


DROP DATABASE LOAD DATABASE

LOAD LOG RECONFIGURE

RESTORE DATABASE RESTORE LOG

SQL Server proporciona los siguientes tipos de triggers:

Trigger DML, se ejecutan cuando un usuario intenta modificar datos mediante un evento de
lenguaje de manipulacin de datos (DML). Los eventos DML son instrucciones INSERT,
UPDATE o DELETE de una tabla o vista.
Trigger DDL, se ejecutan en respuesta a una variedad de eventos de lenguaje de definicin
de datos (DDL). Estos eventos corresponden principalmente a instrucciones
CREATE, ALTER y DROP de Transact-SQL, y a determinados procedimientos
almacenados del sistema que ejecutan operaciones de tipo DDL. Trigger DML, se ejecutan
cuando un usuario intenta modificar datos mediante un evento de lenguaje de manipulacin
de datos (DML). Los eventos DML son instrucciones INSERT, UPDATE o DELETE de una
tabla o vista.

Ejemplo 1:
Como ejemplo crearemos un Trigger que avise al webmaster con un mail cuando un usuario se
da de alta en nuestro web, para crear el trigger solo se han de seguir los pasos arriba
indicados, como muestran las imgenes y el cdigo es el siguiente, haciendo Copy & Paste
funciona.

El funcionamiento del trigger es muy sencillo, declaramos dos variables, una para el mensaje
que se enviar en el mail y otra para obtener el ID del registro recin insertado y luego este
ID lo concatenamos al mensaje para envirselo al webmaster.

Alter Trigger Trigger_Aviso_al_Webmaster


On dbo.pr_usuarios
For Insert
As

Declaramos las variables del mensaje y del ID del nuevo usuario


Declare @Mensaje varchar(200)
Declare @ID numeric

Obtenemos el id del usuario recien insertado


Select @ID = (Select IDUsuario From Inserted )
Select @Mensaje = Nuevo Usuarios en el web : + Convert(varchar(10), @ID)

Exec master.dbo.xp_sendmail
@recipients = webmaster@dominio.com,
@subject = Nuevo usuario,
@message = @Mensaje

EJEMPLO 2:
Para indicar los triggers en esta base hacemos lo siguiente:
Podemos hacer dentro de nuestra base o creamos una Nueva Consulta, donde llamamos a
nuestra base:
use Biblioteca
y comenzamos realizando nuestros triggers asi:
--Trigger que inserta una fila historico cuando se borra un prestamo
/*4. Siempre que se borra una fila de la tabla PRESTAMO, se inserta en HISTORICO la
fila con los datos correspondientes al prestamo que se borra*/ create trigger
tr_delete_prestamo2
on PRESTAMO
after delete as declare
@a char(3),
@b smallint,
@c datetime,
@d smallint,
@e int,
@f datetime select
@a=DELETED.isbn,
@b=DELETED.copiaNro,

@c=DELETED.fechaPrestamo,
@d=DELETED.tituloNro,
@e=DELETED.usuarioNro,
@f=DELETED.fechaDebeDevolver from DELETED
insert into HISTORICO values(@a,@b,@c,@d,@e,@f,null,null,null)
Para ver el resultado tenemos que insertar a la tabla histrico lo siguiente:
insert into HISTORICO values(@a,@b,@c,@d,@e,@f,null,null,null) Luego llamamos a la tabla
histrico y prestamo
select * from historico select * from prestamo
Ejecutamos el triggers.

SCRIPT: Creacin de VISTAS en SQL Server 2008 R2


USE NORTHWIND
GO

--CREACION DE VISTA PROVEEDORES Y SUS PEDIDOS

CREATE VIEW VIEW_SUPPLIER_PRODUCS


AS
SELECT S.SUPPLIERID,S.COMPANYNAME,S.CONTACTNAME
,P.PRODUCTID,P.PRODUCTNAME, P.UNITPRICE
FROM SUPPLIERS AS S INNER JOIN PRODUCTS AS P
ON
S.SUPPLIERID=P.SUPPLIERID
GO

--CREACION DE UNA VISTA CON INSTRUCCION GROUP

CREATE VIEW VIEW_SUBTOTALES(CODIGO_ORDEN,SUB_TOTAL)


AS
SELECT OD.ORDERID,SUM(CONVERT(MONEY,(OD.UNITPRICE* QUAN
TITY*(1-DISCOUNT)/100))*100)
FROM [ORDER DETAILS] OD
GROUP BY OD.ORDERID
GO
--LLAMAR A LA CONSULTA ANTERIOR

SELECT * FROM VIEW_SUBTOTALES

--VER VISTAS

SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYP


E='VIEW'

/*
SOLO LOS DEL ROL DEL SISTEMA SYSADMIN, O DE EL ROL DE
BASE DE DATOS DB_OWNER,
DB_DLADMIN HACEN CONSULTAS
O BIEN AL TENER PERMINOS CREATE VIEW Y PERMISOS DE
SELECT EN LAS TABLAS A UTILIZAR
-NO SE PUEDE USAR COMPUTE COMPUTE BY
-NO SE PUEDE USAR ORDER BY SO SI SE USA TOP
-NO SE PUEDE HACER REFERENCIA A TABLAS TEMPORALES
-NO SE PUEDE HACER REFERENCIA A MAS DE 1024 COLUMNAS
-NO SE PUEDE COMBINAR CREATE VIEW EN OTRO LOTE
*/

--BORRAR UNA VISTA

DROP VIEW VIEW_SUBTOTALES


--ALTERAR UNA VISTA

ALTER VIEW

VIEW_SUPPLIER_PRODUCS

AS
SELECT S.SUPPLIERID,S.COMPANYNAME,S.CONTACTNAME
,P.PRODUCTID,P.PRODUCTNAME, P.UNITPR ICE
FROM SUPPLIERS AS S INNER JOIN PRODUCTS AS P
ON
S.SUPPLIERID=P.SUPPLIERID
GO

--ESCONDER EL CODIGO DE LA VISTA NO ELIMINE LAS


ENTRADAS DE syscomments
ALTER VIEW VIEW_SUPPLIER_PRODUCS
WITH ENCRYPTION
AS
SELECT S.SUPPLIERID,S.COMPANYNAME,S.CONTACTNAME
,P.PRODUCTID,P.PRODUCTNAME, P.UNITPR ICE
FROM SUPPLIERS AS S INNER JOIN PRODUCTS AS P
ON
S.SUPPLIERID=P.SUPPLIERID
GO

--CONSULTAR INFORMACION INFORMACION DE LA VISTA ATRAVEZ


DE INFORMATION_SCHEMA
--SI ESTA PUESTO WITH ENRCRYPTION ESTA INFORMACION NO
ESTA VISIBLE

SELECT * FROM INFORMATION_SCHEMA.TABLES --o sysobjects


--Nombres de vistas y tablas
SELECT * FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE --o
select * from sysdepends
--Nombres de las tablas o vistas base.
SELECT * FROM INFORMATION_SCHEMA.VIEWS -- o select *
from syscomments --Definicin de como se hicieron las
vistas.
SELECT * FROM INFORMATION_SCHEMA.VIEW_COLUMN_USAGE -- o
syscolumns
--tablas y vistas base y Columnas definidas en una
vista.

--PARA VER EL SCRIPT DE UNA CONSULTA O


INFORMATION_SCHEMA.VIEWS O SP_HELPTEXT
SP_HELPTEXT [ORDERS QRY]
SP_DEPENDS [ORDERS QRY] --NOMBRES DE TABLA Y SUS
DEPENDENCIAS

--PUEDE HACER INSERCIONES EN UNA CONSULTA PERO


CONSIDERE QUE
--WITH CHECK OPTION OBLIGA A QUE LAS INSTRUCCIONES DE
MODIFICACION SE COMPRUEBEN CONTRA EL WHERE

--CREAR UNA VISTA CON WITH CHECK OPTION PARA COMPROBAR


EL EJERCICIO
CREATE VIEW CLIENTESARGENTINA
AS
SELECT * FROM CUSTOMERS WHERE COUNTRY='ARGENTINA'
WITH CHECK OPTION

--ESTA INSERCION DEBE PRODUCIR SOBRE LA CONSULTA


ANTERIOR DEBE PRODUCIR UN ERROR.

INSERT CLIENTESARGENTINA (CUSTOMERID,COMPANYNAME,CONTAC


TNAME,CONTACTTITLE,CITY,COUNTRY)
VALUES
('VHCVV','UNIVERSIDAD GALILEO','VICTOR HUGO
CARDENAS','SALES AGENT','GUATEMALA','GUATEMALA')

--CREACION DE UNA TABLA PARA COMPROBAR LA INSERCCION A


MULTIPLES TABLAS
CREATE VIEW PROVEEDORES_PRODUCTOS
AS
SELECTS.SUPPLIERID,S.COMPANYNAME,S.CONTACTNAME,S.COUNTR
Y,P.PRODUCTID,P.PRODUCTNAME,P.UNITPRICEFROM SUPPLIERS A
S S
INNER JOIN PRODUCTS AS P ON S.SUPPLIERID=P.SUPPLIERID

--ESTA INSERCION DEBE DE DAR ERROR PORQUE AFECTA A

VARIAS TABLAS

INSERT PROVEEDORES_PRODUCTOS(COMPANYNAME,CONTACTNAME,CO
UNTRY,PRODUCTNAME,UNITPRICE)
VALUES('CARDENAS','VICTOR HUGO','GUATEMALA','LECHE EN
POLVO',788.00)

--ESTA INSERCION A LA MISMA CONSULTA, SOLO QUE AHORA


AFECTA SOLO
UNA TABLA, EL RESULTADO ES EXITOSO

INSERT PROVEEDORES_PRODUCTOS(COMPANYNAME,CONTACTNAME,CO
UNTRY)
VALUES('CARDENAS','VICTOR HUGO','GUATEMALA')

--COLOCAR UN INDICE EN LA CONSULTA PUEDE OPTIMIZAR SU


RENDIMIENTO, DEBE HACER REFERENCIA AL NOMBRE DE 2
PARTES DEL OBJETO
--DEBE AGREGAR LA OPCION WITH SCHEMABINDIGN
DROP view PROVEEDORES_PRODUCTOS

CREATE VIEW DBO.PROVEEDORES_PRODUCTOS


WITH SCHEMABINDING
AS
SELECTS.SUPPLIERID,S.COMPANYNAME,S.CONTACTNAME,S.COUNTR
Y,P.PRODUCTID,P.PRODUCTNAME,P.UNITPRICEFROM DBO.SUPPLIE
RS AS S
INNER JOIN DBO.PRODUCTS AS P ON S.SUPPLIERID=P.SUPPLIER
ID

--CREACION DEL INDICE, EL PRIMER INDICE DEBE SER UN


INDICE UNICO AGRUPADO

CREATE UNIQUE CLUSTERED INDEX CL_SUPPLIERID


ON DBO.PROVEEDORES_PRODUCTOS (SUPPLIERID,PRODUCTID)

--CREACION DE OTROS INDICES NO AGRUPADOS

CREATE NONCLUSTERED INDEX VIEW_PRODUCTNAME


ON PROVEEDORES_PRODUCTOS(PRODUCTNAME)

--PARA REVISAR SI ES INDEXABLE UNA CONSULTA

SELECT OBJECTPROPERTY (object_id('DBO.PROVEEDORES_PROD


UCTOS'),'IsIndexable')

--VISTAS DIVIDIDAS
-- ALL Incorpora todas las filas en los resultados,
incluidas las duplicadas.
--Si no se especifica lo contrario, se quitan las filas
duplicadas.

SELECT COMPANYNAME, CONTACTNAME, 'CLIENTE' AS ESTADO FR


OM CUSTOMERS
UNION ALL
SELECT COMPANYNAME, CONTACTNAME, 'PROVEEDOR' AS ESTADO
FROM SUPPLIERS

/*
WITH CHECK OPTION

Exige que todas las instrucciones de modificacin de


datos ejecutadas contra la vista se adhieran a los
criterios establecidos en select_statement. Cuando una
fila se modifica mediante una vista, WITH CHECK OPTION
garantiza que los datos permanecern visibles en toda
la vista despus de confirmar la modificacin.

WITH ENCRYPTION

Indica que SQL Server cifra las columnas de la tabla


del sistema
que contienen el texto de la instruccin CREATE VIEW.
Utilizar

WITH ENCRYPTION evita que la vista se publique como


parte de la
duplicacin de SQL Server.

SCHEMABINDING

Enlaza la vista al esquema. Cuando se especifica


SCHEMABINDING,
select_statement debe incluir los nombres con dos
partes
(propietario.objeto) de las tablas, vistas o funciones
definidas
por el usuario a las que se hace referencia.

Las vistas o las tablas que participan en una vista


creada con
la clusula de enlace de esquema no se pueden quitar ni
alterar,
de forma que deja de tener un enlace de esquema. De lo
contrario,
SQL Server genera un error. Adems, las instrucciones
ALTER TABLE
sobre tablas que participan en vistas que tienen
enlaces de
esquemas provocarn un error si estas instrucciones
afectan a
la definicin de la vista.

VIEW_METADATA

Especifica que SQL Server devolver a las API de DBLIB,


ODBC y
OLE DB la informacin de metadatos sobre la vista, en
vez de
las tablas o tabla base, cuando se soliciten los
metadatos del
modo de exploracin para una consulta que hace
referencia a la
vista. Los metadatos del modo de exploracin son
metadatos
adicionales devueltos por SQL Server a las API DB-LIB,
ODBC y
OLE DB del cliente, que permiten a las API del cliente
implementar cursores actualizables en el cliente. Los
metadatos
del modo de exploracin incluyen informacin sobre la
tabla
base a la que pertenecen las columnas del conjunto de
resultados.

Para las vistas creadas con la opcin VIEW_METADATA,


los
metadatos del modo de exploracin devuelven el nombre
de
vista en vez de los nombres de la tabla base cuando se
describen las columnas de la vista en el conjunto de
resultados.

Cuando se crea una vista WITH VIEW_METADATA, todas sus


columnas (excepto timestamp) son actualizables si la
vista tiene los desencadenadores INSERT o UPDATE
INSTEAD
OF. Consulte Vistas actualizables, ms adelante en este
captulo

1.
JUL

12

VISTAS

----- Vistas ---Una vista es una consulta especial que se emplea para registrar selecciones complejas o
que se usan frecuentemente.
Una vez creada la vista se puede realizar una seleccin de los datos como si fuera esta
una tabla e incluso se puede utilizar para definir procedimientos almacenados.
EJEMPLOS :
1. Crear una vista que liste 3 campos de clientes

create view v_listaclientes

as
select IdCliente,NombreCompaa,Pas from Clientes
go

nota : para ejecutar la vista se hace lo siguiente

select * from v_listaclientes


go

2. Crear una vista que muestre el subtotal de los pedidos


create view v_subtotal
as
select IdPedido,SUM(d.PrecioUnidad * Cantidad * (1-d.Descuento ))as Subtotal
from DetallesDepedidos d
inner join Productos p
on d.IdProducto=p.IdProducto
group by IdPedido
go

select * from v_subtotal


go

3.

Crear

una

vista

liste NombreProducto,NombreCategora,PrecioUnidad,Suspendido

create view v_productos


as

que

select NombreProducto,NombreCategora,PrecioUnidad,Suspendido from Productos p


inner join Categoras c on p.IdCategora =c.IdCategora
go

select * from v_productos


order by NombreCategora,NombreProducto
go

4. Utilizando la vista anterior , crear una vista que muestre el total de productos x
categoria
create view total_prodxcateg
as
select NombreCategora,COUNT(*)as Totalprodxcateg from v_productos
group by NombreCategora
go

select * from total_prodxcateg

5. Crear una vista que nos devuelva la cantidad de pedidos que tiene cada empleado
en

los

---aos 94,95 y 96

create view v_cant_pedidos


as
select Nombre,(Select COUNT (*)from v_empleado e where e.Nombre=c.Nombre and
YEAR(FechaPedido)=1994) as Ao_1994,
(select

COUNT(*)from

v_empleado

YEAR(FechaPedido)=1995)as Ao_1995,

where

e.Nombre=c.Nombre

and

(select

COUNT(*)from

v_empleado

where

e.Nombre

=c.Nombre

and

YEAR(FechaPedido)=1996)as Ao_1996
from v_empleado c
group by Nombre

select * from v_cant_pedidos

6. Crear una vista que presente el total de pedido que tiene cada compaia de envio

create view v_totalpedidos


as
select NombreCompaa,COUNT(*)as Total_Pedidos from v_compaia
group by NombreCompaa
go

select * from v_totalpedidos


Publicado 12th July 2012 por kevin lopez chavez

Add a comment
2.
3.
JUL

12

COMBINACION DE TABLAS

Bienvenidos a mi blog !!!!!


Aqu Ud. podr conocer y aprender un poco mas de SQL SERVER 2008,con ejercicios
resueltos y bien explicados.
Bueno comencemos con lo ejercicios, ya que la teora ustedes ya saben y si no ??
Me la escriben...

---- Combinacin de Tablas ----1 . Combinacin Interna de Tablas

Hay

formas

de

Para este caso lo voy hacer con la tabla Productos y Categoras

hacerlo:

- Primera Forma : (INNER JOIN)

SELECT
FROM

NOMBRECATEGORA,NOMBREPRODUCTO
Productos

ON

INNER

JOIN

P.IdCategora

Categoras

=C.IdCategora

GO
-Segunda Forma : (WHERE)

SELECT
FROM
WHERE

NOMBRECATEGORA,NOMBREPRODUCTO
Productos

P
P.IdCategora

Categoras

=C.IdCategora

GO

2. Combinacin Externa de Tablas

-- IZQUIERDA ---> LISTA TODAS LOS PRODUCTOS QUE NO TIENEN CATEGORAS


SELECT
FROM

NOMBRECATEGORA,NOMBREPRODUCTO
Productos

ON

P LEFT

OUTER

JOIN Categoras

P.IdCategora

=C.IdCategora

GO
---DERECHA ---> LISTA TODAS LA CATEGORAS QUE NO TIENES PRODUCTOS
SELECT
FROM

NOMBRECATEGORA,NOMBREPRODUCTO
Productos

ON

P RIGHT

OUTER

JOIN Categoras

P.IdCategora

=C.IdCategora

GO
---- COMPLETA ----> LISTA TODOS LOS PRODUCTOS CON SUS CATEGORAS,
PRODUCTOS QUE NO TIENE CATEGORAS
Y LAS CATEGORIAS QUE NO TIENEN PRODUCTOS
SELECT
FROM
ON

NOMBRECATEGORA,NOMBREPRODUCTO
Productos

P FULL

OUTER

JOIN Categoras

P.IdCategora

GO

Publicado 12th July 2012 por kevin lopez chavez

Add a comment

4.
JUL

12

CREACION DE BASE DE DATOS

=C.IdCategora

---- CREACION DE BASE DE DATOS ---Creamos la base de datos llamada ventas

create

database

ventas

go
use

ventas

go
Para crear la tabla tienda preguntamos si existe, si existe la borramos y la creamos
para evitar errores al momento de ejecutar varias veces

if

exists(select

from

sysobjects

drop

where

type

='u'

and

name

table

='Tienda')
Tienda

go
create

table

Tienda

(
IdTienda

int

identity(1,1)primary

NombreTienda

key,

varchar(30) not

Estado

null,

varchar(10)not

null)

go
nota
-

:
estoy

estableciendo

que

el

campo IdTienda

es

llave

primaria

- estoy estableciendo que el campo NombreTienda tiene que ser llenado obligatoriamente
al

momento
de

ingresar

un

nuevo

registro

Creamos la tabla TiendaProducto

if exists(select * from sysobjects where type='u' and name ='TiendaProducto')


drop

table

TiendaProducto

go
create

table

TiendaProducto

(
IdTienda
IdProducto
Cantidad

int

not

int

not
int

null,
null,
)

go
-estoy
alter

asignando
table

dos

llaves

TiendaProducto

primarias

add

la

constraint

tabla

TiendaProducto

pk_TiendaProducto

primary

key(IdTienda,IdProducto)
-estoy relacionando el campo IdTienda que es llave primaria con el campo IdTienda
de

la

tabla

Tienda

alter table TiendaProducto add constraint fk_TiendaProducto foreign key(IdTienda)


references
-estoy

Tienda(IdTienda)

relacionando

el

campo

campo IdProducto de

IdProducto que

es

llave

la

tabla

primaria con

el

Producto

alter table TiendaProducto add constraint fk_TiendaProduct foreign key(IdProducto)


references Producto(IdProducto)
Creamos la tabla Producto

if

exists(select

from

sysobjects

drop

where

type='u'

and

name

='Producto')

table

Producto

go
create

table

Producto

(
IdProducto

int

NombreProducto

identity(1,1)primary
char(30)

Precio

key,

not

Money

null,

not

null)

go
Creamos la tabla Empleado
if

exists(select

from

sysobjects

drop

where

type='u'

and

name

='Empleado')

table

Empleado

go
create

table

Empleado

(
IdEmpleado

int

Nombres

char(30)

Apellidos
-relaciono
IdTienda
go

identity(1,1)primary

key,

not

null,

varchar(30)not
el

campo
int

IdTienda
foreign

de

Empleado

key

null,
con

references

IdTienda

de

Tienda

Tienda(IdTienda))

Estas lineas de cdigo es para generar el diagrama de tablas relacionadas


exec
alter

sp_dbcmptlevel
authorization

on

exec

'ventas','90';

database

::ventas

to

sp_dbcmptlevel

Sa

'ventas','90';

go
Publicado 12th July 2012 por kevin lopez chavez

Add a comment

5.
JUL

12

SUBCONSULTAS

---- SUBCONSULTAS ---Una subconsulta es una consulta dentro de otra que se puede emplear para obtener
totales y seleccin de datos de tablas anidadas

EJEMPLOS
---CONTAR

select

LOS

CLIENTES

distinct

DE

Pas

:
UN

DETERMINADO PAS---

,(select

COUNT(*)

from
where

c2.Pas
as

from

Clientes

order

by

Clientes

c2

=c1.Pas)
total_clientes
c1
Pas

go
---SUMA
select

EL

PRECIO

DE

Nombrecategora,(select

UNA CATEGORA DE
SUM(PrecioUnidad)from

PRODUCTOS

---

Productos

where

p.IdCategora

c.IdCategora

from

)as

Suma_PrecioUnidad

Categoras

go
---CUENTA

LOS

PEDIDOS

DEL

CLIENTE

---

select NombreCompaa ,(select COUNT(*)from Pedidos p where p.IdCliente=c.IdCliente )


as

Pedidos_Del_Cliente

from

Clientes

go
---CLIENTES
select
where

QUE

SEAN

NombreCompaa
IdCliente

IN

(select

as
IdCliente

DE MXICO ---

Clientes
from

from

Clientes

where

Clientes
Pas='Mxico')

go
---CLIENTES

QUE

COMPRARON

select

NombreCompaa

(select

IdCliente

(select

IdPedido

(select

IdProducto

as

Clientes

from
from
from

EL PRODUCTO PEZ
from

Clientes

Pedidos

Productos

where

where

where

DetallesDepedidos

ESPADA

where

IdCliente

--in

IdPedido

in

IdProducto

in

NombreProducto='Pez

Espada')))

go

---MUESTRA LA CANTIDAD DE PEDIDOS POR AO --select

distinct

year(fechaPedido),(select

COUNT(*)

from
where

year(d.FechaPedido

year(p.FechaPedido
as

from

Pedidos

))

Pedidos_X_Ao

Pedidos

go

La sentencia SELECT
La sentencia SELECT nos permite consultar los datos almacenados en una tabla
de la base de datos.
El formato de la sentencia select es:

SELECT [ALL | DISTINCT ]


<nombre_campo> [{,<nombre_campo>}]
FROM <nombre_tabla>|<nombre_vista>
[{,<nombre_tabla>|<nombre_vista>}]
[WHERE <condicion> [{ AND|OR <condicion>}]]
[GROUP BY <nombre_campo> [{,<nombre_campo >}]]
[HAVING <condicion>[{ AND|OR <condicion>}]]
[ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC]
[{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]

Veamos por partes que quiere decir cada una de las partes que conforman la
sentecia.
Significado
SELECT

ALL

Palabra clave que indica que la sentencia de SQL que queremos ejecutar es
de seleccin.

Indica que queremos seleccionar todos los valores.Es el valor por defecto y no
suele especificarse casi nunca.

DISTINCT Indica que queremos seleccionar slo los valores distintos.

FROM

Indica la tabla (o tablas) desde la que queremos recuperar los datos. En el


caso de que exista ms de una tabla se denomina a la consulta "consulta
combinada" o "join". En las consultas combinadas es necesario aplicar una
condicin de combinacin a travs de una clusula WHERE.

WHERE

Especifica una condicin que debe cumplirse para que los datos sean
devueltos por la consulta. Admite los operadores lgicos AND y OR.

GROUP BY

Especifica la agrupacin que se da a los datos. Se usa siempre en


combinacin con funciones agregadas.

HAVING

Especifica una condicin que debe cumplirse para los datosEspecifica una
condicin que debe cumplirse para que los datos sean devueltos por la
consulta. Su funcionamiento es similar al de WHERE pero aplicado al
conjunto de resultados devueltos por la consulta. Debe aplicarse siempre
junto a GROUP BY y la condicion debe estar referida a los campos contenidos
en ella.

ORDER BY

Presenta el resultado ordenado por las columnas indicadas. El orden puede

expresarse conASC (orden ascendente) y DESC (orden descendente). El valor


predeterminado es ASC.

Para formular una consulta a la tabla tCoches (creada en el captulo de tablas) y


recuperar los campos matricula, marca, modelo, color, numero_kilometros,
num_plazas debemos ejecutar la siguiente consulta. Los datos seran devueltos
ordenados por marca y por modelo en orden ascendente, de menor a mayor.

SELECT matricula,
marca,
modelo,
color,
numero_kilometros,
num_plazas
FROM tCoches
ORDER BY marca,modelo;

La palabra clave FROM indica que los datos sern recuperados de la tabla
tCoches. Podriamos haber especificado mas de una tabla, pero esto se ver en el
apartado de consultas combinadas.
Tambien podramos haber simplicado la consulta a travs del uso del comodin de
campos, el asterisco "*".

SELECT *
FROM tCoches
ORDER BY marca,modelo;

El uso del asterisco indica que queremos que la consulta devuelva todos los
campos que existen en la tabla.
[arriba]

La clusula WHERE
La clusula WHERE es la instruccin que nos permite filtrar el resultado de una
sentencia SELECT. Habitualmente no deseamos obtener toda la informacin
existente en la tabla, sino que queremos obtener slo la informacin que nos resulte
util es ese momento. La clusula WHERE filtra los datos antes de ser devueltos por
la consulta.
En nuestro ejemplo, si queremos consultar un coche en concreto debemos
agregar una clusula WHERE. Esta clusula especifica una o varias condiciones que
deben cumplirse para que la sentencia SELECT devuelva los datos. Por ejemplo,

para que la consulta devuelva slo los datos del coche con maricula M-1525-ZA
debemos ejecutar la siguiente sentencia:

SELECT matricula,
marca,
modelo,
color,
numero_kilometros,
num_plazas
FROM tCoches
WHERE matricula = 'M-1525-ZA';
Cuando en una clusula where queremos incluir un tipo texto,
debemos incluir el valor entre comillas simples.

Adems, podemos utilizar tantas condiciones como queramos, utilizando los


operadores lgicos AND y OR . El siguiente ejemplo muestra una consulta que
devolver los coches cuyas matriculas sean M-1525-ZA o bien M-2566-AA.

SELECT matricula,
marca,
modelo,
color,
numero_kilometros,
num_plazas
FROM tCoches
WHERE matricula = 'M-1525-ZA'
OR matricula = 'M-2566-AA' ;

Adems una condicin WHERE puede ser negada a travs del operador
lgico NOT. La siguiente consulta devolver todos los datos de la tabla tCohes
menos el que tenga matricula M-1525-ZA.

SELECT matricula,
marca,
modelo,
color,
numero_kilometros,
num_plazas
FROM tCoches
WHERE NOT matricula = 'M-1525-ZA' ;

Podemos tambien obtener las diferentes marcas y modelos de coches ejecutando


la consulta.

SELECT DISTINCT marca,


modelo
FROM tCoches;

La ver los valores distintos. En el caso anterior se devolveran lpalabra


clave DISTINCT indica que slo queremos os valores distintos del par formado por
los campos marca y modelo.
[arriba]

La clusula ORDER BY
Como ya hemos visto en los ejemplos anteriores podemos especificar el orden en
el que sern devueltos los datos a travs de la clusula ORDER BY.

SELECT matricula,
marca,
modelo,
color,
numero_kilometros,
num_plazas
FROM tCoches
ORDER BY marca ASC,modelo DESC;

Como podemos ver en el ejemplo podemos especificar la ordenacin ascendente


o descendente a travs de las palabras clave ASCy DESC. La ordenacin depende
del tipo de datos que este definido en la columna, de forma que un campo nmerico
ser ordenado como tal, y un alfanmerico se ordenar de la A a la Z, aunque su
contenido sea nmerico. De esta forma el valor 100 se devuelve antes que el 11.
Tambin podemos especificar el en la clusula ORDER BY el ndice nmerico del
campo dentro del la sentencia SELECT para la ordenacin, el siguiente ejemplo
ordenara los datos por el campo marca, ya que aparece en segundo lugar dentro
de la lista de campos que componen la SELECT.

SELECT matricula,
marca,
modelo,
color,
numero_kilometros,
num_plazas
FROM tCoches
ORDER BY 2;

El resto de opciones que podemos especificar al construir sentencias SELECT se


irn presentando en los siguientes capitulos de este tutorial.

Insertar datos.
Hasta ahora hemos visto como se almacenan los datos en una base de datos y
como consultar esos datos almacenados, pero no hemos visto como almacenar
dichos datos.
Para almacenar datos en una base de datos debemos insertar filas en las tablas.
Para ellos SQL pone a nuestra disposicin la sentencia INSERT.
[arriba]

Insercin de filas
El proceso de insercin de filas consiste en aadir a una tabla una o ms filas y
en cada fila todos o parte de sus campos.
Podemos distinguir dos formas de insertar filas:

Insercin individual de filas.

Insercin multiple de filas.


La sintaxis de la sentencia INSERT es diferente segn cual sea nuestro proposito.
Slo podremos omitir un campo al efectuar una insercin cuando este acwepte
valores nulos.
[arriba]

Insercin individual de filas


Para realizar la inserccin individual de filas SQL posee la instruccin INSERT
INTO.La inserccin individual de filas es la que ms comunmente utilizaremos. Su
sintaxis es la siguiente:

INSERT INTO <nombre_tabla>


[(<campo1>[,<campo2>,...])]
values
(<valor1>,<valor2>,...);
Como se puede observar la sentencia tiene dos partes claramente diferenciadas,
por un lado la propia INSERT INTO seguida de la lista de campos en los que
queremos insertar los datos, y por otro la lista de valores que queremos insertar en
los campos. La mejor forma de ver esto es a travs de un ejemplo.

INSERT INTO tCoches


(matricula,
marca
,
modelo
,
color
,
numero_kilometros)
values
('M1111CA',
'RENAULT',
'MEGANE TR100',
'NEGRO DIAMANTE',
78000);
Nota:Hemos utilizado el color rojo para los datos de tipo texto,
entrecomillados con la comilla simple, y el azul para
los numericos.
Con esta sentencia INSERT creamos un registro en la tabla tCoches con los
valores especificados, es decir, la matricula tendr el valor M-1111-CA, la marca
ser RENAULT y as sucesivamente.
Que ocurrira si ya existiera un coche con la matricula M-1111-CA? Se producir
un error, porque hemos definido la clave primaria en el campo matricula, y como
hemos visto la clave primaria debe ser nica.
Si omitimos algn par " campo-valor " en la sentencia INSERT, pueden ocurrir
varias cosas:

Que se produzca un error , si el campo no acepta valores nulos.

Que se grave el registro y se deje nulo el campo, cuando el campo acepte


valores nulos.

Que se grave el registro y se tome el valor por defecto, cuando el campo


tenga definido un valor por defecto.
Que hacer en cada cada momento depender del programa.
Por ejemplo, la siguiente sentencia crear un registro en la tabla tCoches con el
campo numero_kilometros cero, ya que este es su valor por defecto.

INSERT INTO tCoches


(matricula,
marca
,
modelo
,
color)
values
('M1111CA',
'RENAULT',
'MEGANE TR100',
'NEGRO DIAMANTE');
[arriba]

Insercin multiple de filas


La sentencia INSERT permite tambien insertar varios registros en una tabla. Pare
ello se utiliza una combinacin de la sentenciaINSERT junto a una
sentencia SELECT. El resultado es que se insertan todos los registros devueltos por
la consulta.

INSERT INTO <nombre_tabla>


[(<campo1>[,<campo2>,...])]
SELECT
[(<campo1>[,<campo2>,...])]
FROM
<nombre_tabla_origen>;
Para poder utilizar la insercin multiple de filas se deben cumplir las siguientes
normas:

La lista de campos de las sentencias insert y select deben coincidir en


nmero y tipo de datos.

Ninguna de las filas devueltas por la consulta debe infringir las reglas de
integridad de la tabla en la que vayamos a realizar la insercin.
Pongamos un ejemplo, vamos a crear una tabla con las diferentes marcas que
tenemos en la base de datos. La sentencia SQL para crear la tabla es la siguiente:

CREATE TABLE tMarcas


(
codigo
integer not null identity(1,1),
marca
varchar(255),
constraint PK_Marcas primary key (codigo)
);
Nota: Hemos incluido la funcin identity para el campo codigo, esta
funcin es propia de SQL Server e indica que
el cdigo se genera automticamente cada vez que se inserta un registro
con un valor autonumrico. Praticamente
todos los gestores de bases de datos dan la opcin del campo autonumerico
o incremental, si bien el modo varias.
Para SQL Server utilizaremos la funcion identity, para ORACLE las
secuencias ...
Una vez que tenemos creada la tabla de marcas vamos a insetar otro par de
registros en la tabla de coches, para ello utilizamos una sentencia insert into para
una nica fila.

INSERT INTO tCoches


(matricula,
marca
,
modelo
,

color)
values
('M2233FH',
'SEAT',
'LEON FR',
'ROJO');
INSERT INTO tCoches
(matricula,
marca
,
modelo
,
color)
values
('M1332FY',
'FORD',
'FIESTA',
'GRIS PLATA');
Ahora tenemos tres marcas diferentes en la tabla tCoches, y queremos
insertarlas en la tabla de marcas, para ello podemos realizar tres inserciones
individuales, pero que pasaria si no supieramos de antemano el nmero de
marcas?y si fueran unas cincuenta marcas?. Nos podriamos pasar el da entero
escribiendo sentencias insert into.
Afortunadamente podemos realizar una insercin multiple del siguiente modo:

INSERT INTO tMarcas


(marca)
SELECT DISTINCT marca FROM tCoches;
Como resultado obtenemos un registro en la tabla tMarcas por cada marca de la
tabla tCoches. El campo codigo se ha generado automticamente ya que est
definido como identidad.
CODIGO

MARCA
1 FORD
2 RENAULT
3 SEAT

Demonos cuenta de que el orden de generacin no ha sido el mismo que el de


insercin, sino que se ha aplicado el orden en el que han sido devueltos los datos
por la sentencia SELECT.
Ahora deberiamos cambiar los datos de la tabla tCoches, para guardar el cdigo
de la marca en lugar de su descripcin, pero para ello necesitamos saber como
modificar un dato grabado ... Es momento de pasar al siguiente punto, la actualizacin
de datos.

La sentencia DELETE.
Para borrar datos de una tabla, debemos utilizar la sentencia DELETE.

La sintaxis de la sentencia DELETE es la siguiente:

DELETE FROM <nombre_tabla>


[ WHERE <condicion>];
El siguiente ejemplo ilustra el uso de la sentencia DELETE. Es buena idea
especificar en la sentencia WHERE los campos que forman la clave primaria de la
tabla para evitar borrar datos que no queramos eliminar.

DELETE FROM tCoches


WHERE marca = 'SEAT';
La sintaxis de DELETE varia en Access, siendo necesario el uso del comodn *. DELETE *
FROM <tCoches>
Cuando trabajemos con la sentencia DELETE debemos tener en cuenta las
siguientes consideraciones:

Solo podemos borrar datos de una nica tabla.

Cuando borramos datos de una vista, los estamos borrando tambin de la


tabla. Las vistas son solo una forma de ver los datos, no una copia.

Si intentamos borrar un registro de una tabla referenciada por una FOREING


KEY como tabla maestra, si la tabla dependiente tiene registros relacionados la
sentencia DELETE fallar.

La sentencia TRUNCATE
Para realizar un borrado completo de tabla debemos considerar la posibilidad de
utilizar la sentencia TRUNCATE, mucho ms rpida que DELETE.
La sintaxis de la sentencia TRUNCATE es la siguiente:

TRUNCATE TABLE <nombre_tabla>;


El siguiente ejemplo muestra el uso de la sentencia TRUNCATE.

TRUNCATE TABLE tCoches;


Cuando trabajemos con la sentencia TRUNCATE debemos tener en cuenta las
siguientes consideraciones.

La sentencia TRUNCATE no es transaccional. No se puede deshacer.

La sentencia TRUNCATE no admite clausula WHERE. Borra toda la tabla.

No todos los gestores de bases de datos admiten la sentencia TRUNCATE.

Actualizacin de datos.
La sentencia UPDATE.
Para la actualizacin de datos SQL dispone de la sentencia UPDATE. La
sentencia UPDATE permite la actualizacin de uno o varios registros de una nica
tabla. La sintaxis de la sentencia UPDATE es la siguiente

UPDATE <nombre_tabla>
SET <campo1> = <valor1>
{[,<campo2> = <valor2>,...,<campoN> = <valorN>]}
[ WHERE <condicion>];
Las siguientes sentencias actualizan los datos de la tabla tCoches con los valores
de la tabla tMarca obtenidos anteriormente en la pgina dedicada a la insercin de
datos.

UPDATE tCoches
SET marca = '1'
WHERE marca = 'FORD';
UPDATE tCoches
SET marca = '2'
WHERE marca = 'RENAULT';
UPDATE tCoches
SET marca = '3'
WHERE marca = 'SEAT';
Notese que los valores para el campo marca aparecen entrecomillados, ya que es
un campo de tipo varchar. Los valores con los que actualicemos los datos deben
ser del tipo del campo.
Un aspecto a tener en cuenta es que los campos que forman la primary key de
una tabla slo se podrn modificar si los registros no estn referenciados en
ninguna otra tabla. En nuestro caso slo podremos modificar la matrcula de un
coche si no tiene registros asociados en la tabla tAlquileres.
Esto puede causar poblemas, ya que podramos habernos equivocado al dar de alta
el coche en la tabla tCoches y detectar el error despues de alquilar el coche. En tal
caso tendramos dar de alta un nuevo coche con la matrcula correcta, actualizar los
registros de la tabla alquileres y por ltimo borrar el registro erroneo de la tabla
tCoches. Este proceso puede ser bastante complicado en el caso de
que existiran ms relaciones con la tabla. Se podra considerar que la clave primaria
de la tabla esta mal definida y que la matrcula no debe ser el elemento que
identifique el coche. Una alternativa seria crear un cdigo autonumrico para la
tabla tCoches que realizar las veces de clave primaria y crear un ndice nico para
la matrcula, este diseo tambien tiene sus "pegas", por lo que debemos decidir que
modelo utilizar, y seleccionar las claves primarias con sumo cuidado.

[arriba]

Uso de subconsultas con UPDATE


El uso de subconsultas es una tcnica avanzada de consulta que veremos
con detalle ms adelante, pero que tratamos aqu de forma introductoria.
Hasta ahora hemos actualizado los datos con valores que conocemos de
antemano, pero qu ocurre cuando esos datos deben tomarse de otra tabla de la
base de datos?.Podramos disear un programa que recorriera toda la tabla y
buscar el valor adecuado para cada registro y lo actualizase. Sin duda es una
solucin, y en ocasiones cas la nica, pero es una solucin cara y compleja que
adems exige que conozcamos algn otro lenguaje de programacin. Para estos
casos podemos utilizar subconsultas con la sentenciaUPDATE.
La sintaxis es la siguiente:

UPDATE <nombre_tabla>
SET <campo1> = <valor1> | <subconsulta1>
{[,<campo2> = <valor2> | <subconsulta2>
,...
, <campoN> = <valorN> | <subconsultaN>]}
[ WHERE <condicion>];
Como puede verse la sintaxis es practicamente igual a la sintaxis del la
sentencia UPDATE, con la salvedad de que podemos utilizar subconsultas en lugar
de valores al asignar los campos. De forma generica podemos decir que las
subconsultas son consultas SELECTincluidas dentro de otra sentencia SQL.
Las siguientes sentencias UPDATE son equivalentes:

Utilizando sentencias UPDATE normales:


UPDATE tCoches
SET marca = '1'
WHERE marca = 'FORD';
UPDATE tCoches
SET marca = '2'
WHERE marca = 'RENAULT';
UPDATE tCoches
SET marca = '3'
WHERE marca = 'SEAT';
Utilizando sentencias UPDATE combinadas con subconsultas:
UPDATE tCoches
SET marca = (SELECT CODIGO FROM tMarcas
WHERE tMarcas.Marca = tCoches.Marca )
WHERE marca IN ('FORD','RENAULT','SEAT');
Por cada registro de la tabla tCoches se ejecutar la subconsulta, actualizando el
campo marca a el valor del cdigo de la marca en la tabla tMarcas.
El uso de subconsultas para actualizar datos tiene algunas limitaciones:

La subconsulta slo puede devover un nico campo.

La subconsulta slo puede devolver un slo registro.

El tipo de datos devuelto por la subconsulta debe ser del mismo tipo que el
campo al que estamos asignando el valor.

No todos los sistemas de bases de datos permiten usar subconsultas para


actualizar datos (Access) aunque si una buena parte de ellos (ORACLE, SQL Server,
Sybase ...)
Pero en nuestro ejemplo el campo codigo de la tabla tMarcas es numrico y el
campo marca de la tabla tCoches es texto. Por qu funciona? Muy facil, el motor de
la base de datos es capaz de convertir el valor numrico a un valor texto de forma
automtica, si bien esta es una excepcin.
Ahora que ya tenemos modificado el valor de la marca de los registros, es
conveniente modificar su tipo de datos y crear una foreign key contra la tabla
tMarcas. Para ello ejecutaremos las siguientes sentencias.

ALTER TABLE tCoches


alter column marca int not null;
La opcion alter column es propia de SQL Server. Para modificar el tipo de
datos de una tabla debemos consultar la ayuda del gestor de bases de datos.
ALTER TABLE tCoches
add constraint FK_Coches_Marcas foreign key (marca)
references tMarcas (codigo);

Consultas combinadas. JOINS


Consultas combinadas.
Habitualmente cuando necesitamos recuperar la informacin de una base de
datos nos encontramos con que dicha informacin se encuentra repartida en varias
tablas, referenciadas a travs de varios cdigos. De este modo si tuvieramos una
tabla de ventas con un campo cliente, dicho campo contendra el cdigo del cliente
de la tabla de cliente.
Sin embargo est forma de almacenar la informacin no resulta muy util a la hora
de consultar los datos. SQL nos proporciona una forma facil de mostrar la
informacin repartida en varias tablas, las consultas combinadas o JOINS.
Las consultas combinadas pueden ser de tres tipos:

Combinacin interna

Combinacin externa

Uniones
[arriba]

Combinacin interna.
La combinacin interna nos permite mostrar los datos de dos o ms tablas a
travs de una condicin WHERE.
Si recordamos los ejemplos de los capitulos anteriores tenemos una tabla de
coches, en la que tenemos referenciada la marca a travs del cdigo de marca. Para
realizar la consulta combinada entre estas dos tablas debemos escribir una
consulta SELECT en cuya clasula FROM escribiremos el nombre de las dos tablas,
separados por comas, y una condicin WHERE que obligue a que el cdigo de
marca de la tabla de coches sea igual al cdigo de la tabla de marcas.
Lo ms sencillo es ver un ejemplo directamente:

SELECT tCoches.matricula,
tMarcas.marca,
tCoches.modelo,
tCoches.color,
tCoches.numero_kilometros,
tCoches.num_plazas
FROM tCoches, tMarcas
WHERE tCoches.marca = tMarcas.codigo
La misma consulta de forma "visual" ...

Demonos cuenta que hemos antepuesto el nombre de cada tabla a el nombre del
campo, esto no es obligatorio si los nombres de campos no se repiten en las tablas,
pero es acondajable para evitar conflictos de nombres entre campos. Por ejemplo, si
para referirnos al campo marca no anteponemos el nombre del campo la base de
datos no sabe si queremos el campo marca de la tabla tCoches, que contiene el
cdigo de la marca, o el campo marca de la tabla tMarcas, que contiene el nombre
de la marca.
Otra opcin es utilizar la clusula INNER JOIN. Su sintaxis es identica a la de una
consulta SELECT habitual, con la particularidad de que n la clusula FROM slo
aparece una tabla o vista, aadiendose el resto de tablas a travs de
clusulas INNER JOIN .

SELECT [ALL | DISTINCT ]


<nombre_campo> [{,<nombre_campo>}]
FROM <nombre_tabla>
[{INNER JOIN <nombre_tabla> ON <condicion_combinacion>}]
[WHERE <condicion> [{ AND|OR <condicion>}]]
[GROUP BY <nombre_campo> [{,<nombre_campo >}]]
[HAVING <condicion>[{ AND|OR <condicion>}]]
[ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC]
[{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]
El ejemplo anterior escrito utilizando la clausula INNER JOIN quedaria de la
siguiente manera:

SELECT tCoches.matricula,
tMarcas.marca,
tCoches.modelo,
tCoches.color,
tCoches.numero_kilometros,
tCoches.num_plazas
FROM tCoches
INNER JOIN tMarcas ON tCoches.marca = tMarcas.codigo
La clusula INNER JOIN permite separar completamente las condiciones de
combinacin con otros criterios, cuando tenemos consultas que combinan nueve o
diez tablas esto realmente se agradece. Sin embargo muchos programadores no
son amigos de la clusula INNER JOIN, la razn es que uno de los principales
gestores de bases de datos, ORACLE, no la soportaba. Si nuestro porgrama debia
trabajar sobre bases de datos ORACLE no podiamos utilizar INNER JOIN. A partir
de la version ORACLE 9i oracle soporta la clusula INNER JOIN.
[arriba]

Combinacin Externa
La combinacin interna es excluyente. Esto quiere decir que si un registro no
cumple la condicin de combinacin no se incluye en los resultados. De este modo
en el ejemplo anterior si un coche no tiene grabada la marca no se devuelve en mi
consulta.
Segn la naturaleza de nuestra consulta esto puede ser una ventaja , pero en
otros casos significa un serio problema. Para modificar este comportamiento SQL
pone a nuestra disposicin la combinacin externa. La combinacin externa no es
excluyente.
La sintaxis es muy parecida a la combinacin interna,

SELECT [ALL | DISTINCT ]


<nombre_campo> [{,<nombre_campo>}]
FROM <nombre_tabla>
[{LEFT|RIGHT OUTER JOIN <nombre_tabla> ON <condicion_combinacion>}]
[WHERE <condicion> [{ AND|OR <condicion>}]]

[GROUP BY <nombre_campo> [{,<nombre_campo >}]]


[HAVING <condicion>[{ AND|OR <condicion>}]]
[ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC]
[{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]
La combinacin externa puede ser diestra o siniestra, LEFT OUTER
JOIN o RIGHT OUTER JOIN. Con LEFT OUTER JOIN obtenemos todos los
registros de en la tabla que situemos a la izquierda de la clausula JOIN, mientras
que con RIGHT OUTER JOIN obtenmos el efecto contrario.
Como mejor se ve la combinacin externa es con un ejemplo.

SELECT tCoches.matricula,
tMarcas.marca,
tCoches.modelo,
tCoches.color,
tCoches.numero_kilometros,
tCoches.num_plazas
FROM tCoches
LEFT OUTER JOIN tMarcas ON tCoches.marca = tMarcas.codigo
Esta consulta devolver todos los registros de la tabla tCoches,
independientemente de que tengan marca o no. En el caso de que el coche no
tenga marca se devolver el valor null para los campos de la tabla tMarcas.
Visualmente (la consulta devuelve los datos en azul) ...

El mismo ejemplo con RIGHT OUTER JOIN.

SELECT tCoches.matricula,
tMarcas.marca,
tCoches.modelo,
tCoches.color,
tCoches.numero_kilometros,
tCoches.num_plazas
FROM tCoches
RIGHT OUTER JOIN tMarcas ON tCoches.marca = tMarcas.codigo
Esta consulta devolver los registros de la tabla tCoches que tengan marca
relacionada y todos los registros de la tabla tMarcas, tengan algn registro en
tCoches o no.
Visualmente (la consulta devuelve los datos en azul) ...

[arriba]

Union
La clusula UNION permite unir dos o ms conjuntos de resultados en uno detras
del otro como si se tratase de una nica tabla. De este modo podemos obtener los
registros de mas de una tabla "unidos".
La sintaxis corresponde a la de varias SELECT unidas a travs de UNION, como
se muestra a continuacin:

SELECT [ALL | DISTINCT ]


<nombre_campo> [{,<nombre_campo>}]
FROM <nombre_tabla>
[{LEFT|RIGHT OUTER JOIN <nombre_tabla> ON <condicion_combinacion>}]
[WHERE <condicion> [{ AND|OR <condicion>}]]
[GROUP BY <nombre_campo> [{,<nombre_campo >}]]
[HAVING <condicion>[{ AND|OR <condicion>}]]
{
UNION [ALL | DISTINCT ]
SELECT [ALL | DISTINCT ]
<nombre_campo> [{,<nombre_campo>}]
FROM <nombre_tabla>
[{LEFT|RIGHT OUTER JOIN <nombre_tabla> ON <condicion_combinacion>}]
[WHERE <condicion> [{ AND|OR <condicion>}]]
[GROUP BY <nombre_campo> [{,<nombre_campo >}]]
[HAVING <condicion>[{ AND|OR <condicion>}]]
}
[ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC]
[{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]
Para utilizar la clausula UNION debemos cumplir una serie de normas.

Las consultas a unir deben tener el mismo nmero campos, y adems los
campos deben ser del mismo tipo.

Slo puede haber una nica clausula ORDER BY al final de la


sentencia SELECT.
El siguiente ejemplo muestra el uso de UNION

SELECT tCoches.matricula,
tMarcas.marca,
tCoches.modelo,

tCoches.color,
tCoches.numero_kilometros,
tCoches.num_plazas
FROM tCoches
INNER JOIN tMarcas ON tCoches.marca = tMarcas.codigo
UNION
SELECT tMotos.matricula,
tMarcas.marca,
tMotos.modelo,
tMotos.color,
tMotos.numero_kilometros,
0
FROM tMotos
INNER JOIN tMarcas ON tMotos.marca = tMarcas.codigo;
Puede observarse el uso de la constante cero en la segunda lista de seleccin para
hacer coincidir el nmero y tipo de
campos que devuelve la consulta UNIO

Consultas agregadas
La clusula GROUP BY
La clausula GROUP BY combina los registros con valores idnticos en un nico
registro. Para cada registro se puede crear un valor agregado si se incluye una
funcin SQL agregada, como por ejemplo Sum o Count, en la instruccin SELECT.
Su sintaxis es:

SELECT [ALL | DISTINCT ]


<nombre_campo> [{,<nombre_campo>}]
[{,<funcion_agregado>}]
FROM <nombre_tabla>|<nombre_vista>
[{,<nombre_tabla>|<nombre_vista>}]
[WHERE <condicion> [{ AND|OR <condicion>}]]
[GROUP BY <nombre_campo> [{,<nombre_campo >}]]
[HAVING <condicion>[{ AND|OR <condicion>}]]
[ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC]
[{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]
GROUP BY es opcional. Si se utiliza GROUP BY pero no existe una funcin SQL
agregada en la instruccin SELECT se obtiene el mismo resultado que con una
consulta SELECT DISTINCT. Los valores Null en los campos GROUP BY se agrupan
y no se omiten. No obstante, los valores Null no se evalan en ninguna de las
funciones SQL agregadas.
Todos los campos de la lista de campos de SELECT deben incluirse en la
clusula GROUP BY o como argumentos de una funcin SQL agregada.

SELECT marca, modelo, SUM(numero_kilometros)


FROM tCoches
GROUP BY marca, modelo

La clusula HAVING

Una vez que GROUP BY ha combinado los registros, HAVING muestra cualquier
registro agrupado por la clusula GROUP BY que satisfaga las condiciones de la
clusula HAVING. Se utiliza la clusula WHERE para excluir aquellas filas que no
desea agrupar, y la clusula HAVING para filtrar los registros una vez agrupados.
HAVING es similar a WHERE, determina qu registros se seleccionan. Una vez
que los registros se han agrupado utilizando GROUP BY, HAVING determina cuales
de ellos se van a mostrar. HAVING permite el uso de funciones agregadas.

SELECT marca, modelo, SUM(numero_kilometros)


FROM tCoches
WHERE marca <> 'BMW'
GROUP BY marca, modelo
HAVING SUM(numero_kilometros)>100000
En el ejemplo anterior, no se cuentan los datos para todas las marcas
menos "BMW", una vez que se han contado, se evaluaHAVING, y el conjunto de
resultados devuelve solo aquellos modelos con ms de 100.000 km.

AVG
Calcula la media aritmtica de un conjunto de valores contenidos en un campo
especificado de una consulta. Su sintaxis es la siguiente

AVG(<expr>)

En donde expr representa el campo que contiene los datos numricos para los
que se desea calcular la media o una expresin que realiza un clculo utilizando los
datos de dicho campo. La media calculada por Avg es la media aritmtica (la suma
de los valores dividido por el nmero de valores). La funcin Avg no incluye ningn
campo Null en el clculo.

SELECT marca, modelo, AVG(numero_kilometros)


FROM tCoches
GROUP BY marca, modelo

Count
Calcula el nmero de registros devueltos por una consulta. Su sintaxis es la
siguiente:

COUNT(<expr>)
En donde expr contiene el nombre del campo que desea contar. Los operandos
de expr pueden incluir el nombre de un campo de una tabla, una constante o una

funcin (la cual puede ser intrnseca o definida por el usuario pero no otras de las
funciones agregadas de SQL). Puede contar cualquier tipo de datos incluso texto.
Aunque expr puede realizar un clculo sobre un campo, Count simplemente
cuenta el nmero de registros sin tener en cuenta qu valores se almacenan en los
registros. La funcin Count no cuenta los registros que tienen campos null a menos
que expr sea el carcter comodn asterisco (*). Si utiliza un asterisco, Count calcula
el nmero total de registros, incluyendo aquellos que contienen campos null.
Count(*) es considerablemente ms rpida que Count(Campo). No se debe poner el
asterisco entre dobles comillas ('*').

SELECT COUNT(*) FROM tCoches;


SELECT marca, COUNT(modelo)
FROM tCoches
GROUP BY marca;
SELECT marca, COUNT(DISTINCT modelo)
FROM tCoches
GROUP BY marca;

Max, Min
Devuelven el mnimo o el mximo de un conjunto de valores contenidos en un
campo especifico de una consulta. Su sintaxis es:

MIN(<expr>)
MAX(<expr>)
En donde expr es el campo sobre el que se desea realizar el clculo. Expr pueden
incluir el nombre de un campo de una tabla, una constante o una funcin (la cual
puede ser intrnseca o definida por el usuario pero no otras de las funciones
agregadas de SQL).

SELECT marca, modelo, MIN(numero_kilometros)


, MAX(numero_kilometros)
FROM tCoches
GROUP BY marca, modelo

Sum
Devuelve la suma del conjunto de valores contenido en un campo especifico de
una consulta. Su sintaxis es:
SUM(<expr>)
En donde expr respresenta el nombre del campo que contiene los datos que
desean sumarse o una expresin que realiza un clculo utilizando los datos de
dichos campos. Los operandos de expr pueden incluir el nombre de un campo de
una tabla, una constante o una funcin (la cual puede ser intrnseca o definida por
el usuario pero no otras de las funciones agregadas de SQL).

SELECT marca, modelo, SUM(numero_kilometros)


FROM tCoches
GROUP BY marca, modelo

Вам также может понравиться