Escolar Documentos
Profissional Documentos
Cultura Documentos
SEMANA12
(*.MDF)
-PRINCIPAL (NUNCA PUEDE FALTAR =1)(GUARDA TODOS LOS DATOS(SIST,USER))
*-ARCH. DE DATOS (*.NDF)
-SECUNDARIO(SI PUEDE FALTAR >=0)(SOLO GUARDA DATOS DEL USER
SI SE LLENA EN UN DISCO PODEMOS CREAR OTRO EN OTRO DISCO)
-BD
(*.LFD) (>=1)
*-ARCH. LOGICO DE REGISTRO
DE TRANSACCIONES
(GUARDA LAS INSTRUCCIONES PARA LUEGO
APLICARSE EN EL ARCHIVO DE DATOS)
LO MAS RECOMENDABLE PARA SQL ES SEPARAR LA DATA DEL SISTEMA DE LA DATA DEL USUARIO
SQL 2005
ES UNA SWEER QUE CONSIST EREN DATABASE ENGINE ANALAYSYS SERVICES(PARA CUBOS) SREPORTING SERVICES RSQL
SERVER
MOBILE INTEGGRATION SERVICES
ALA HORA DE PONER EL NOMBRE DE NUESTRA BASE DE DATOS, EN LA GRILLA FILEGROUP EL *MDF() SIEMPRE ES PRIMARY
ASIENDO CLICK EN ADD PODEMOS AGREGARLE MAS ARCHIBOS SECUNDARIOS PARA POSIBLEMENTE GUARDAR DATA DE OTRAS
AREAS
EN ESTE CASO EL NOMBRE VENTAS_DATA Y EN FILE TYPE DATA EN FILEGROUP LE ASIGNAMOS EL FILE GROUP DONDE
QUERAMOS QUE SE GUARDE
AL FORMULARIO QUE NOS PARECE LE ASIGNAMOS EL NOMBRE DE VENTAS Y EN OPTIONS NO MARCAMOS NADA Y ACEPTAMOS.
ES IMPORTANTE
NO GUARDARLO EN EL FILEGROUP PRIMARY! YA QUE QUEREMOS ASIGANARLE UNA UBICACION DIFERENTE DE ESTE.
AHORA LOS TAMAÑOS DE INICIO. SE DICE QUE LO LOS ARCHIVOS LOGICOS DEBEN TENER LA TERCERA PARTE DE LOS ARCHIVOS
DE
DATOS
EL TAMAÑO DE INICIO LO CALCULAMOS CONTANDO LAS FILAS QUE SE MUEVEN EN CADA FILA.
TENER EN CUENTA QUE NUESTRO ARCHIVO DE DATOS SECUNDARIO VA A CRECER MAS.
LUEGO EL AUTOROW TENEMOS QUE DEFINIR EN CUANTO POR TANTO VA A AUMENTAR UNA VEZ QUE SE ACABE EL TAMAÑO
INICIAL
EN ESTE CASO LE PONEMOS 2 MEGAS Y SIN RESTRICCION.
LUEGO EL PARCHNAME ES LA UBICACION DONDE GRABAREMOS NUESTROS TIPOS DE ARCHIVO EN OTRA CARPETA O EN OTRO
DISCO DURO
EN ESTE CASO LO COLOCAREMOS EN EL DISCO C:
.dIe<->Go Página 1
CREATE DATABASE [BD2453] ON PRIMARY
( NAME = N'BD2453', FILENAME = N'E:\Program Files\Microsoft SQL
Server\MSSQL.1\MSSQL\DATA\BD2453.mdf' , SIZE = 3072KB , FILEGROWTH = 1024KB ),
FILEGROUP [VENTAS]
( NAME = N'VENTAS_DATA', FILENAME = N'C:\VENTAS_DATA.ndf' , SIZE = 3072KB ,
FILEGROWTH = 2048KB )
LOG ON
( NAME = N'BD2453_log', FILENAME = N'E:\Program Files\Microsoft SQL
Server\MSSQL.1\MSSQL\DATA\BD2453_log.ldf' , SIZE = 1024KB , FILEGROWTH = 10%)
GO
SEMANA13
--USO DE CONSTRAINTS
--------------------
use bdconstraints
go
--VEMOS QUE COMO NUESTRA TABLA CLIENTES NO CUENTA CON UNA PRIMARY KEY
--NUESTROS DATOS INGRESADOS SE MUESTRAN DE FORMA DESORDENADA
--Y PODRIAMOS INGRESAR CODIGOS DUPLICADOS
.dIe<->Go Página 2
go
*/
/*
USE NORTHWIND
SELECT TOP 2 PRODUCTID, PRODUCTNAME FROM PRODUCTS
UNION ALL
SELECT TOP 4 EMPLOYEEID, LASTNAME FROM EMPLOYEES
--NO SE PUEDO USAR ORDEY BY EN LA CLAUSULA UNION ALL
*/
*/
ALTER TABLE ORDENES WITH NOCHECK ADD CONSTRAINT FK_CODCLI FOREIGN KEY (CODCLI)
.dIe<->Go Página 3
REFERENCES CLIENTES(CODCLI) ON UPDATE CASCADE --ON DELETE NO ACTION
GO
--NOTA WITH NOCHECK, SE UTILIZA SPÑP AÑ CREAR UN NUEVO CONTRAINT QUE PUEDE SER DE
--TIPO CHECK
--DESACTIVANDO CONSTRAINTS
--ACTIVANDO CONTRAINTS
ALTER TABLE ORDENES
CHECK CONSTRAINT FK_CODCLI
GO
---------------------------------------------------------------------------------
USE NORTHWIND
GO
--TRANSACT SQL
--LISTAR LOS "N" MEJORES EMPLEADOS QUE HAYAN
--REALIADO LOS MAS ALTOS IMPORTANTES DE ORDENES
--EN EL AÑO 1996. SE DEBE MOSTRAR EL NOMBRE
--COMPLETO: NOMBRE, APELLIDO Y EL NUMERO DE LA
--ORDEN Y SU IMPORTE CORRESPONDIENTE.
DECLARE @N INT
SET @N=3
SELECT TOP (@N) FIRSTNAME+', ' +LASTNAME AS EMPLEADO,
O.ORDERID,IMPORTE=SUM(D.QUANTITY*D.UNITPRICE)
FROM EMPLOYEES E INNER JOIN ORDERS O
ON E.EMPLOYEEID=O.EMPLOYEEID
INNER JOIN [ORDER DETAILS] D
ON O.ORDERID=D.ORDERID
WHERE YEAR(O.ORDERDATE)=1996
GROUP BY FIRSTNAME+', ' +LASTNAME,O.ORDERID
ORDER BY IMPORTE DESC
.dIe<->Go Página 4
FROM PRODUCTS P INNER JOIN [ORDER DETAILS] D
ON P.PRODUCTID=D.PRODUCTID
INNER JOIN ORDERS O
ON O.ORDERID=D.ORDERID
WHERE O.EMPLOYEEID=1 AND P.CATEGORYID=1
GROUP BY P.PRODUCTID,PRODUCTNAME
GO
SELECT AÑO=YEAR(ORDERDATE),ORDERID=MAX(ORDERID)--,COMPANYNAME
FROM ORDERS O --INNER JOIN CUSTOMERS C
--ON O.CUSTOMERID=C.CUSTOMERID
GROUP BY YEAR(ORDERDATE)--,COMPANYNAME
ORDER BY ORDERID
GO
----CO SUBCONSULTAS
SELECT T.AÑO, T.ORDEN, C.COMPANYNAME
FROM CUSTOMERS C INNER JOIN ORDERS O
ON C.CUSTOMERID=O.CUSTOMERID
INNER JOIN (SELECT AÑO=YEAR(ORDERDATE),ORDEN=MAX(ORDERID)
FROM ORDERS GROUP BY YEAR(ORDERDATE)) AS T ON O.ORDERID=T.ORDEN
GO
--------------------------------------------------------
--OTRA FORMA
CREATE VIEW VISTA1
AS
SELECT AÑO=YEAR(ORDERDATE),ORDEN=MAX(ORDERID)
FROM ORDERS GROUP BY YEAR(ORDERDATE)
GO
.dIe<->Go Página 5
SEMANA14
--CONSULTAS Y SUBCONSULTAS
/*
LISTAR LAS ORDENES DEL ULTIMO MES DEL ULTIMO AÑO DE LA TABLA ORDERS
*/
--PRIMERO AVERIGUAMOS EL ULTIMO MES DEL ULTIMO AÑO
-- 1998
--MES
SELECT TOP 1
MONTH(ORDERDATE) FROM ORDERS
WHERE YEAR(ORDERDATE)=1998
ORDER BY MONTH(ORDERDATE) DESC
GO
/*
LISTAR LOS NOMBRES DE LOS PRODUCTOS Y LA CANTIDAD VENDIDA DEL ULTIMO PEDIDO
REALIZADO POR EL EMPLEADO MAS ANTIGUO (UTILICE EL CAMPO HIREDATE DE EMPLOYEES)
*/
--11063
-- "O"
/*
.dIe<->Go Página 6
LISTAR LAS VENTAS ACUMULADAS DE LOS CLIENTES
POR PAIS. SE DEBE LISTAR EL NOMBRE DEL PAIS,
LA CANTIDAD TOTAL DE ORDENES ASI COMO EL ACUMULADO
GENERAL DE LAS VENTAS POR PAIS.
*/
/*
DEL RESULTADO ANTERIOR AQUELLOS PAISES QUE SUPEREN
LOS 50000 EN LAS VENTAS ACUMULADAS
*/
/*
DEL RESULTADO ANTERIOR EL PAIS QUE MAS PEDIDOS
HAYA REALIZADO
*/
/*
CREATE VIEW V_VISTA1
AS
SELECT COUNTRY,CANT=COUNT(DISTINCT(O.ORDERID)),VENTAS=SUM(UnitPrice*Quantity) FROM
[Order Details] OD
INNER JOIN ORDERS O ON O.ORDERID=OD.ORDERID
INNER JOIN CUSTOMERS C ON O.CUSTOMERID=C.CUSTOMERID
GROUP BY COUNTRY
GO
*/
.dIe<->Go Página 7
SELECT TOP 1 WITH TIES * FROM V_VISTA1
ORDER BY CANT DESC
GO
------------------------------------------------------------
/*
LISTAR LA CANTIDAD DE PEDIDOS REALIZADOS POR CADA
DIA DE LA SEMANA (DATENMAE) REALIZADOS EN EL AÑO 1997.
DEBERA APARECER ORDENADO POR LOS DIAS DE SEMANA ES
DECIR: LUNES, MARTES, ... DOMINGO
*/
--PREFIJO DE FECHA, PARTE DE FECHA, DATEPART
--DAY OF WEEK DW, MONTH MM
------------------------------------------------
--FORMA CORRECTA
SET LANGUAGE SPANISH
SELECT DATENAME(MM,GETDATE())
SELECT DATENAME(DW,GETDATE())
------------------------------------------------
--FORMA INCORRECTA
SELECT DATENAME(YY,GETDATE())
SELECT DATENAME(DD,GETDATE())
------------------------------------------------
SELECT --DATEPART(DW,ORDERDATE),
DATENAME(DW,ORDERDATE),CANT=COUNT(ORDERID)
FROM ORDERS
WHERE YEAR(ORDERDATE)=1997
GROUP BY DATENAME(DW,ORDERDATE),
DATEPART(DW,ORDERDATE)
ORDER BY DATEPART(DW,ORDERDATE)I
GO
--------------------------------------------------------------------------------
--SUBCONSULTAS
/*
1. A NIVEL DE CAMPO.
SELECT <LISTA DE CAMPOS>,
ALIAS1(SELECT UN_VALOR .....),
ALIAS2=(SELECT .........)
FROM TABLA_PRINCIPAL
.........
2. A NIVEL DE TABLA (TABLA DERIVADA)
SELECT <LISTA_CAMPOS>,
FROM TABLA_PRINCIPAL T,
(SELECT <LISTA_CAMPOS> FROM TABLAS.........) AS X
WHERE T.CAMPOCOMUN=X.CAMPOCOMUN
.....................................
3. A NIVEL DE FILTRO(WHERE)
SELECT <LISTA_CAMPOS>
FROM TABLA_PRINCIPAL
WHERE CAMPO OPERATDOR (SELECT UNA_COLUMNA)
...............
OPERADOR:
=,<,<=,>,>=, EL SELECT SOLO TRAE UN VALOR
IN, EL SELECT PUEDE DEVOLVER MUCHOS VALORES
*/
--EJEMPLOS:
/*
.dIe<->Go Página 8
HACIENDO USO DE SUBCONSULTAS, RESOLVER:
LISTAR EL NOMBRE DE LA CATEGORIA CON LA CANTIDAD DE PRODUCTOS
PERTENECIENTE A CADA CATEGORIA.
*/
SELECT C.CATEGORYNAME,
CANT=(SELECT COUNT(*) FROM PRODUCTS
WHERE CATEGORYID=C.CATEGORYID)
FROM CATEGORIES C
/*
LISTAR EL NOMBRE DEL PRODUCTO MAS VENDIDO EN EL AÑO 1997.
MAS VENDIDO POR LA MAYOR CANTIDAD DE VECES QUE APARECE EN LA TABLA [ORDER DETAILS]
UTILICE SUBCONSULTAS A NIVEL DE TABLA
*/
SELECT TOP 1 WITH TIES PRODUCTID, CANT=COUNT(D.ORDERID)
FROM [ORDER DETAILS] D INNER JOIN ORDERS O ON D.ORDERID=O.ORDERID
WHERE YEAR(ORDERDATE)=1997
GROUP BY PRODUCTID
ORDER BY CANT DESC
GO
SELECT P.PRODUCTNAME
FROM PRODUCTS P INNER JOIN
(
SELECT TOP 1 WITH TIES PRODUCTID, CANT=COUNT(D.ORDERID)
FROM [ORDER DETAILS] D INNER JOIN ORDERS O ON D.ORDERID=O.ORDERID
WHERE YEAR(ORDERDATE)=1997
GROUP BY PRODUCTID
ORDER BY CANT DESC
) AS X
ON P.PRODUCTID=X.PRODUCTID
GO
------------------------------------
--CONVERTIRLA A NIVEL DE FILTRO
.dIe<->Go Página 9
SELECT PRODUCTNAME FROM PRODUCTS
WHERE PRODUCTID=(SELECT TOP 1 WITH TIES PRODUCTID
FROM [ORDER DETAILS] D INNER JOIN ORDERS O ON D.ORDERID=O.ORDERID
WHERE YEAR(ORDERDATE)=1997
GROUP BY PRODUCTID
ORDER BY COUNT(D.ORDERID) DESC)
SEMANA15
--SUBCONSULTAS
--1ERA PREGUNTA
--LISTAR EL ULTIMO PEDIDO REALIZADO POR CADA CLIENTE EN UN AÑO DETERMINADO.
--DEBERA MOSTRAR EL NUMERO DE PEDIDO, NOMBRE DEL CLIENTE Y LA FECHA
--EJEMPLO AÑO 1997
--2DA PREGUNTA
--LISTAR EL NOMBRE DEL CLIENTE, LA CANTIDAD DE PEDIDOS REALIZADOS EN EL AÑO:
--1996,1997,1998, DE ACUERDO A UN PAIS DETERMINADO
--EJEMPLO CLIENTES DE MEXICO
--1RA SOLUCION
--NOTA LAS VISTAS NO OCUPAN ESPACIO FISICO
CREATE VIEW VISTA1
AS
SELECT C.COMPANYNAME, C_1996=(SELECT COUNT(*) FROM ORDERS
WHERE
CUSTOMERID=C.CUSTOMERID AND YEAR(ORDERDATE)=1996),
C_1997=(SELECT COUNT(*) FROM ORDERS
WHERE
CUSTOMERID=C.CUSTOMERID AND YEAR(ORDERDATE)=1997),
C_1998=(SELECT COUNT(*) FROM ORDERS
WHERE
CUSTOMERID=C.CUSTOMERID AND YEAR(ORDERDATE)=1998)
FROM CUSTOMERS C
WHERE COUNTRY='MEXICO'
GO
.dIe<->Go Página 10
--2DA SOLUCION
INTO #TEMPO1 -- TABLA TEMPORAL # DURA EL TIEMPO DE LA SESION DEL USUARIO CUANDO
CIERRA SU SESION SE ELIMINE
FROM CUSTOMERS C
WHERE COUNTRY='MEXICO'
GO
-----------------------------------------------
---------------USO DE VISTAS-------------------
-----------------------------------------------
/*
ES UN OBJETO DE SQL SERVER QUE SOLO CONSUME RECURSOS CUANDO ES LLAMADA DENTRO
DE UNA INSTRUCCION SELECT, POR EL CUAL ES DENOMINADO TABLA VIRTUAL.
ESTE OBJETO SOLO PUEDE DEVOLVER UN CONJUNTO DE DATOS, NO PERMITE EL USO
DE LA CLAUSSULA ORDER BY (SALVO QUE SE UTILICE TOP),COMPUTE,COMPUTE BY,
SINTAXIS:
CREATE VIEW NOMBRE_VISTA
WITH ENCRYPTION, SHEMABINDIG --EVITA QUE BOREN LAS TABLAS O COLUMNAS QUE USE LA
VISTA
AS
--UNICA INSTRUCCION SELECT
GO
EXEC LISTAR_PROD_CAT 7
GO
--CAMBIANDO EL NOMBRE DE UNA COLUMNA
SP_RENAME 'TMP_PROD.UNITPRICE','PRECIO','COLUMN'
.dIe<->Go Página 11
GO
EXEC LISTAR_PROD_CAT 7
GO
SP_RENAME 'TMP_PROD.PRECIO','UNITPRICE','COLUMN'
GO
EXEC LISTAR_PROD_CAT 7
GO
--UTILIZANDO SCHEMABINDING
CREATE VIEW V_PRODUCTS
WITH SCHEMABINDING
AS
SELECT PRODUCTID, PRODUCTNAME, UNITPRICE,UNITSINSTOCK FROM DBO.TMP_PROD
GO
--AL INTENTAR RENOMBRAR LA COLUMNA UNITPRICE NUEVAMENTE
--SQL NOS IMPEDIRA POR QUE ESTA COLUMNA ESTA ENLAZA AL
--ESQUEMA
SP_RENAME 'TMP_PROD.UNITPRICE','PRECIO','COLUMN'
DROP TABLE TMP_PROD
GO
.dIe<->Go Página 12
-------------------------
CREATE VIEW V_TABLAS
AS
SELECT EMPLOYEEID,FIRSTNAME+', '+LASTNAME AS EMPLEADO
FROM EMPLOYEES
UNION ALL
SELECT PRODUCTID,PRODUCTNAME FROM PRODUCTS
GO
----COMPUTE
SELECT CUSTOMERID,COMPANYNAME FROM CUSTOMERS
COMPUTE COUNT(CUSTOMERID)
--COMPUTE <FUNCTION_AGREGADO(COLUMNA)>
GO
SEMANA16
USE BDTRIGGERS
GO
/*
CREAR UN TRIGGER QUE NO PERMITA LA DUPLICACION
DE NOMBRES DE CLIENTES AL MOMENTO DE LA INSERCION
DE UN NUEVO CLIENTE.
*/
CREATE TRIGGER TR_01
ON CLIENTES AFTER INSERT
AS
SELECT 'TABLA INSERTED' AS TABLA,
* FROM INSERTED
SELECT 'TABLA CLIENTES' AS TABLA,
* FROM CLIENTES
.dIe<->Go Página 13
IF @CONTA>=2
BEGIN
PRINT 'EL NOMBRE: '+@NOMBRE+
' ESTÁ DUPLICADO'
ROLLBACK
END
GO
-- INSERTANDO UN NUEVO CLIENTE
INSERT CLIENTES VALUES('ABCDE','CLIENTE ABCDE','PERU')
GO
-- VOLVEMOS A INSERTAR UN CLIENTE
INSERT CLIENTES VALUES('XWSDE','CLIENTE ABCDE','PERU')
GO
/*
CREAR UN TRIGGER QUE NO PERMITA LA ELIMINACION
DE CLIENTES SI ES QUE EL CLIENTE TIENE ORDENES.
*/
CREATE TRIGGER TR_02
ON CLIENTES AFTER DELETE
AS
SELECT * FROM DELETED
SELECT * FROM CLIENTES
/*
DESACTIVE AL TRIGGER ANTERIOR, Y CREE UNO NUEVO
QUE PERMITA ELIMINAR A UN CLIENTE Y A SUS ORDENES
SOLO SI EL CLIENTE TIENE MENOS DE 5 ORDENES.
*/
-- DISABLE TRIGGER NOMBRE_TRIGGER ON NOMBRE_TABLA
DISABLE TRIGGER TR_02 ON CLIENTES
GO
.dIe<->Go Página 14
' TIENE: '+STR(@CANT,3)+ ' ORDENES'
ROLLBACK
END
ELSE -- CASO CONTRARIO
BEGIN -- ELIMINAMOS TAMBIEN SUS ORDENES
PRINT 'ELIMINANDO LAS ORDENES DE: '+@COD
DELETE ORDENES WHERE COD_CLI=@COD
PRINT 'CLIENTE ELIMINADO'
END
GO
-- LISTAR LOS CODIGOS DE LOS CLIENTES Y LA CANTIDAD
-- DE ORDENES
SELECT COD_CLI, CANTIDAD=COUNT(*) FROM ORDENES
GROUP BY COD_CLI ORDER BY CANTIDAD DESC
-- THEBI, ANATR --> 4 ORDENES
-- VINET, FOLIG --> 5 ORDENES
SELECT * FROM ORDENES WHERE COD_CLI='THEBI'
SELECT * FROM CLIENTES WHERE COD_CLI='THEBI'
DELETE CLIENTES WHERE COD_CLI='THEBI'
GO
-------------------------------------------------------------------
USE MASTER
GO
.dIe<->Go Página 15
GO
/*
CREAR UN TRIGGER QUE PERMITA AUDITAR LA ELIMINACION DE
REGISTROS EN LA TABLA CLIENTES.
*/
-- 1RO. CREAREMOS UNA TABLA QUE NOS PERMITA AUDITAR
CREATE TABLE AUDITA_USUARIOS
(
NRO_OPER INT IDENTITY PRIMARY KEY,
FECHA DATETIME,
USUARIO VARCHAR(50),
COMANDO VARCHAR(50),
DESCRIPCION VARCHAR(100)
)
GO
.dIe<->Go Página 16
SELECT * FROM AUDITA_USUARIOS
-------------------------------------------------------------------
USE BDTRIGGERS
GO
/*
CREAR UN TRIGGER QUE PERMITA ACTUALIZAR EL STOCK DE LOS
PRODUCTOS CADA VEZ QUE SE INSERTE UN NUEVO REGISTRO EN LA
TABLA DETALLE. SI EL NUEVO STOCK DEL PRODUCTO ES MENOR A CERO
NO SE PUEDE REALIZAR LA VENTA. SI EL NUEVO STOCK DEL PRODUCTO
ESTA ENTRE 0 (CERO) Y 10 SE DEBE GUARDAR EN UNA TABLA LLAMADA
PRODUCTOS_STOCKS_MINIMOS
UPDATE PRODUCTOS
SET STK_PROD=STK_PROD - @CANT WHERE COD_PROD=@COD
IF @STOCK < 0
BEGIN
ROLLBACK
DECLARE @MSJ VARCHAR(100)
SET @MSJ='EL PRODUCTO %s TIENE UN STOCK NEGATIVO: %d'
RAISERROR(@MSJ, 14, 1, @NOM, @STOCK) WITH LOG
END
GO
.dIe<->Go Página 17
SELECT * FROM PRODUCTOS WHERE STK_PROD BETWEEN 11 AND 20
-- PRODUCTO 3, TIENE 13 DE STOCK Y 10 DE PRECIO
SELECT * FROM DETALLES WHERE NRO_ORD=10248
/*
CREAR UN TRIGGER QUE LISTE LOS VALORES DEL REGISTRO ORIGINAL Y
DEL NUEVO REGISTRO AL MOMENTO DE ACTUALIZAR LOS DATOS DE UN
PRODUCTO.
*/
CREATE TRIGGER TR_ACT_PRODUCTOS
ON PRODUCTOS AFTER UPDATE
AS
-- DATOS DEL REGISTRO ORIGINAL
DECLARE @COD_ANT INT, @NOM_ANT VARCHAR(50), @PRE_ANT MONEY
SELECT @COD_ANT=COD_PROD, @NOM_ANT=NOM_PROD,
@PRE_ANT=PRE_PROD FROM DELETED
--SP_SEND_DBMAIL
GO
.dIe<->Go Página 18