You are on page 1of 92

SQL Intermedio

PROGRAMACIÓN EN BASE DE DATOS - TSQL

EDUNEG - Escuela de Desarrollo Universal de Negocios


Silabus
1. Sub Consultas 9. Tablas Temporales Locales
2. Vistas 10.Tablas Temporales Globales
3. Tipos de Datos 11.Tipo de dato TABLE
4. Variables 12.SQL Dinámico
5. Lotes 13.Funciones
6. IF 14.Procedimientos almacenados
7. WHILE 15.Desencadenadores (Triggers)
8. CURSOR 16. Transacciones

EDUNEG Programación de Objetos 2 - 30


Sub Consultas
SELECT orderid SELECT orderid
FROM Sales.Orders FROM Sales.Orders
WHERE empid = WHERE empid =
(SELECT E.empid (SELECT E.empid
FROM HR.Employees AS E FROM HR.Employees AS E
WHERE E.lastname LIKE N'C%'); WHERE E.lastname LIKE N’D%');

EDUNEG Programación de Objetos 3 - 30


Sub Consultas

<scalar_expression> [NOT] IN (<multivalued subquery>)

SELECT orderid SELECT custid, companyname


FROM Sales.Orders FROM Sales.Customers
WHERE empid IN WHERE custid NOT IN
(SELECT E.empid (SELECT O.custid
FROM HR.Employees AS E FROM Sales.Orders AS O);
WHERE E.lastname LIKE N'D%');

EDUNEG Programación de Objetos 4 - 30


Sub Consultas

SELECT custid, orderid, orderdate, empid SELECT orderid, custid, val,


FROM Sales.Orders AS O1 CAST(100. * val / (SELECT SUM(O2.val)
WHERE orderid = FROM Sales.OrderValues AS O2
(SELECT MAX(O2.orderid) WHERE O2.custid = O1.custid)
FROM Sales.Orders AS O2 AS NUMERIC(5,2)) AS pct
WHERE O2.custid = O1.custid); FROM Sales.OrderValues AS O1
ORDER BY custid, orderid;

EDUNEG Programación de Objetos 5 - 30


Sub Consultas

SELECT custid, companyname SELECT custid, companyname


FROM Sales.Customers AS C FROM Sales.Customers AS C
WHERE country = N'Spain' WHERE country = N'Spain'
AND EXISTS AND NOT EXISTS
(SELECT * FROM Sales.Orders AS O (SELECT * FROM Sales.Orders AS O
WHERE O.custid = C.custid); WHERE O.custid = C.custid);

EDUNEG Programación de Objetos 6 - 30


Sub Consultas

SELECT orderid, orderdate, empid, SELECT orderid, orderdate, empid, custid,


custid, (SELECT MIN(O2.orderid)
(SELECT MAX(O2.orderid) FROM Sales.Orders AS O2
FROM Sales.Orders AS O2 WHERE O2.orderid > O1.orderid) AS
WHERE O2.orderid < O1.orderid) AS nextorderid
prevorderid FROM Sales.Orders AS O1;
FROM Sales.Orders AS O1;

EDUNEG Programación de Objetos 7 - 30


Sub Consultas

SELECT orderyear, qty,


(SELECT SUM(O2.qty)
FROM Sales.OrderTotalsByYear AS O2
WHERE O2.orderyear <= O1.orderyear) AS runqty
FROM Sales.OrderTotalsByYear AS O1
ORDER BY orderyear;

EDUNEG Programación de Objetos 8 - 30


Sub Consultas

1. Escriba una consulta que devuelva todos los pedidos realizados el último día de
actividad que se pueden encontrar en la tabla Pedidos (Sales.Orders)
2. Escriba una consulta que devuelva todos los pedidos realizados por los clientes que
realizaron la mayor cantidad de pedidos. Tenga en cuenta que más de un cliente
puede tener la misma cantidad de pedidos(Sales.Orders)
3. Escriba una consulta que devuelva empleados que no realizaron pedidos el 1 de
mayo de 2016 o después (HR.Employees y Sales.Orders)

EDUNEG Programación de Objetos 9 - 30


Sub Consultas

4. Escriba una consulta que devuelva países donde hay clientes pero no empleados
(Sales.Customers y HR.Employees)
5. Escriba una consulta que devuelva para cada cliente todos los pedidos realizados en
el último día de actividad del cliente (Sales.Orders)
6. Escriba una consulta que devuelva clientes que realizaron pedidos en 2015 pero no
en 2016 (Sales.Customers y Sales.Orders)
7. Escriba una consulta que devuelva los clientes que pidieron el producto 12
(Sales.Customers, Sales.Orders y Sales.OrderDetails)
EDUNEG Programación de Objetos 10 - 30
Sub Consultas

8. Escriba una consulta que calcule una cantidad total acumulada para cada cliente y
mes (Sales.CustOrders)
9. Explique la diferencia entre IN y EXISTS
10. Escribe una consulta que devuelva para cada pedido el número de días que pasaron
desde el pedido anterior del mismo cliente. Para determinar la antigüedad entre
pedidos, use orderdate como el elemento de clasificación principal y orderid como
desempate (Sales.Orders)

EDUNEG Programación de Objetos 11 - 30


Vistas
CREATE VIEW Sales.ClientesUSA
AS
SELECT custid, companyname,
SELECT custid, companyname
contactname, contacttitle, address,city, region,
FROM Sales.ClientesUSA;
postalcode, country, phone, fax
FROM Sales.Customers
WHERE country = N'USA';

EDUNEG Programación de Objetos 12 - 30


Vistas

ALTER VIEW Sales.ClientesUSA


WITH ENCRYPTION
AS

EXEC sp_helptext 'Sales.ClientesUSA ';

EDUNEG Programación de Objetos 13 - 30


Vistas

ALTER VIEW Sales.ClientesUSA


WITH SCHEMABINDING
AS

ALTER TABLE Sales.Customers DROP COLUMN address;

EDUNEG Programación de Objetos 14 - 30


Vistas
ALTER VIEW Sales.ClientesUSA
INSERT INTO Sales. ClientesUSA(
WITH SCHEMABINDING
companyname, contactname, contacttitle, address,
AS
city, region, postalcode, country, phone, fax)
SELECT
VALUES( N'Customer FGHIJ', N'Contact FGHIJ',
custid, companyname, contactname, contacttitle,
N'Title FGHIJ', N'Address FGHIJ’, N'London', NULL,
address,
N'12345', N'UK', N'012-3456789', N'012-3456789');
city, region, postalcode, country, phone, fax
FROM Sales.Customers
WHERE country = N'USA'
WITH CHECK OPTION;

EDUNEG Programación de Objetos 15 - 30


Practica de Vistas
1. Crear 03 vistas en esquemas diferentes y de tablas diferentes
2. Encriptar la definición de las vistas creadas
3. Usar en las vistas creadas WITH SCHEMABINDING y demostrar las dependencias
de las tablas base
4. Usar WITH CHECK OPTION en las vistas creadas. Usar INSERT INTO, UPDATE,
DELETE y DROP TABLE

EDUNEG Programación de Objetos 16 - 30


Tipos de Datos
Almacen
Grupo Tipo de dato Intervalo
amiento
63 63
bigint De -2 (-9.223.372.036.854.775.808) a 2 - 1 (9.223.372.036.854.775.807) 8 bytes
31 31
int De -2 (-2.147.483.648) a 2 - 1 (2.147.483.647) 4 bytes
15 15
smallint De -2 (-32.768) a 2 - 1 (32.767) 2 bytes
tinyint De 0 a 255 1 byte
bit Tipo de datos entero que puede aceptar los valores 1, 0 ó NULL 2 bytes
•p (precisión): el número total máximo de dígitos decimales que se puede
almacenar, tanto a la izquierda como a la derecha del separador decimal. La
precisión debe ser un valor comprendido entre 1 y la precisión máxima de
Numéricos
decimal, 38. La precisión predeterminada es 18. Precisión
exactos
numeric, •s (escala): el número máximo de dígitos decimales que se puede almacenar 1 - 9: 5
decimal (p, s) a la derecha del separador decimal. La escala debe ser un valor comprendido bytes
entre 0 y p. Sólo es posible especificar la escala si se ha especificado la
precisión. La escala predeterminada es 0.
38 38
Con precisión máxima 10 +1 y 10 - 1
Tipos de datos que representan valores monetarios o de moneda: de -
money 8 bytes
922.337.203.685,4775808 a 922.337.203.685,4775807
smallmoney De - 214,7483648 a 214,7483647 4 bytes

EDUNEG Programación de Objetos 17 - 30


Tipos de Datos
De - 1,79E+308 a -2,23E-308, 0 y de Depende del valor
float
2,23E-308 a 1,79E+308 de n
Aproximados
De - 3,40E + 38 a -1,18E - 38, 0 y de 1,18E
real 4 Bytes
- 38 a 3,40E + 38
Del 1 de enero de 1753 hasta el 31 de
datetime
diciembre de 9999
Fecha y hora
Del 1 de enero de 1900 hasta el 6 de junio
smalldatetime
de 2079
Caracteres no Unicode de longitud fija, con
char (n) una longitud de n bytes. n debe ser un valor n bytes
entre 1 y 8.000
Caracteres no Unicode de longitud
varchar (n) variable. n indica que el tamaño de n bytes (aprox.)
Cadenas de caracteres 31
almacenamiento máximo es de 2 - 1 bytes
En desuso, sustituido por varchar.
Datos no Unicode de longitud variable con
text 31 max bytes (aprox.)
una longitud máxima de 2 - 1
(2.147.483.647) caracteres

EDUNEG Programación de Objetos 18 - 30


Tipos de Datos
Datos de carácter Unicode de longitud fija,
nchar (n) con n caracteres. n debe estar comprendido entre 1 y 2 * n bytes
4.000
cadenas de Datos de carácter Unicode de longitud
caracteres nvarchar (n) variable. n indica que el tamaño máximo de 2 * n bytes + 2 bytes
31
unicode almacenamiento es 2 - 1 bytes
En desuso, sustituido por nvarchar.
ntext (n) Datos Unicode de longitud variable con una longitud 2 * n bytes
30
máxima de 2 - 1 (1.073.741.823) caracteres
Datos binarios de longitud fija con una longitud
binary (n) de n bytes, donde n es un valor que oscila entre 1 y n bytes
8.000
Datos binarios de longitud variable. n indica que el
Cadenas 31
varbinary (n) tamaño de almacenamiento máximo es de 2 - 1 n bytes
binarias bytes
En desuso, sustituido por varbinary.
31
image Datos binarios de longitud variable desde 0 hasta 2 -
1 (2.147.483.647) bytes

EDUNEG Programación de Objetos 19 - 30


Tipos de Datos
Tipo de datos para las variables o para los parámetros de resultado de
cursor los procedimientos almacenados que contiene una referencia a un
cursor. Las variables creadas con el tipo de datos cursor aceptan NULL
Tipo de datos que expone números binarios únicos generados
automáticamente en una base de datos. El tipo de datos timestamp es
timestamp 8 bytes
simplemente un número que se incrementa y no conserva una fecha o
una hora
Tipo de datos que almacena valores de varios tipos de datos aceptados
Otros tipos sql_variant
en SQL Server, excepto text, ntext, image, timestamp y sql_variant
de datos
uniqueidentifier Es un GUID (Globally Unique Identifier, Identificador Único Global) 16 bytes
Es un tipo de datos especial que se puede utilizar para almacenar un
conjunto de resultados para su procesamiento posterior. table se utiliza
table principalmente para el almacenamiento temporal de un conjunto de filas
devuelto como el conjunto de resultados de una función con valores de
tabla
Almacena datos de XML. Puede almacenar instancias de xml en una
xml
columna o una variable de tipo xml

EDUNEG Programación de Objetos 20 - 30


Crear Llaves Foráneas y Primarias

EDUNEG Programación de Objetos 21 - 30


Crear Llaves Foráneas y Primarias

Alumnos
Id
Nombre
Apellido
Direccion
Fecha_nacimiento

Profesor Inscripcion
Id Id
Asignatura
Nombre IdAsignatura
Id
Apellido IdAlumno
Nombre
Direccion IdProfesor
Fecha_nacimiento Fecha
Nivel_Academico

EDUNEG Programación de Objetos 22 - 30


VARIABLES

Utiliza variables para almacenar temporalmente valores de datos para su uso


posterior en el mismo lote en el que se declararon.

DECLARE @i AS INT;
SET @i = 10;

DECLARE @x AS INT = 10;

SELECT @x;

EDUNEG Programación de Objetos 23 - 30


VARIABLES

USE TSQLV4;
DECLARE @empname AS NVARCHAR(61);

SET @empname = (SELECT firstname + N' ' + lastname


FROM HR.Employees
WHERE empid = 3);

SELECT @empname AS empname;

EDUNEG Programación de Objetos 24 - 30


VARIABLES

DECLARE @firstname AS NVARCHAR(20), @lastname AS NVARCHAR(40);


SET @firstname = (SELECT firstname
FROM HR.Employees
WHERE empid = 3);
SET @lastname = (SELECT lastname
FROM HR.Employees
WHERE empid = 3);

SELECT @firstname AS firstname, @lastname AS lastname;

EDUNEG Programación de Objetos 25 - 30


VARIABLES

DECLARE @firstname AS NVARCHAR(20), @lastname AS NVARCHAR(40);

SELECT
@firstname = firstname,
@lastname = lastname
FROM HR.Employees
WHERE empid = 3;

SELECT @firstname AS firstname, @lastname AS lastname;

EDUNEG Programación de Objetos 26 - 30


VARIABLES

DECLARE @empname AS NVARCHAR(61);

SELECT @empname = firstname + N' ' + lastname


FROM HR.Employees
WHERE mgrid = 2;

SELECT @empname AS empname;

EDUNEG Programación de Objetos 27 - 30


VARIABLES

DECLARE @empname AS NVARCHAR(61);

SET @empname = (SELECT firstname + N' ' + lastname


FROM HR.Employees
WHERE mgrid = 2);

SELECT @empname AS empname;

EDUNEG Programación de Objetos 28 - 30


LOTES

Un lote es una o más declaraciones T-SQL enviadas por una aplicación cliente a
SQL Server para su ejecución como una sola unidad. El lote se somete a análisis
(verificación de sintaxis), resolución / enlace (verificación de la existencia de
objetos y columnas referenciados, verificación de permisos) y optimización como
una unidad.

No confunda transacciones y lotes . Una transacción es una unidad atómica de


trabajo. Un lote puede tener múltiples transacciones, y una transacción puede
enviarse en partes como múltiples lotes. Cuando se cancela o revierte una
transacción, SQL Server deshace la actividad parcial que ha tenido lugar desde el
comienzo de la transacción, independientemente de dónde comenzó el lote.

EDUNEG Programación de Objetos 29 - 30


LOTES
-- Valido batch -- Valido batch
PRINT 'First batch'; PRINT 'Third batch';
USE TSQLV4; SELECT empid FROM HR.Employees;
GO
-- Invalido batch
PRINT 'Second batch';
SELECT custid FROM
Sales.Customers;
SELECT orderid FOM Sales.Orders;
GO

EDUNEG Programación de Objetos 30 - 30


LOTES
DECLARE @i AS INT;
SET @i = 10;
-- Succeeds
PRINT @i;
GO
-- Fails
PRINT @i;

EDUNEG Programación de Objetos 31 - 30


LOTES
DROP VIEW IF EXISTS Sales.MyView;

CREATE VIEW Sales.MyView


AS
SELECT YEAR(orderdate) AS orderyear, COUNT(*) AS numorders
FROM Sales.Orders
GROUP BY YEAR(orderdate);
GO

EDUNEG Programación de Objetos 32 - 30


Un lote como unidad de resolución
DROP TABLE IF EXISTS dbo.T1;
CREATE TABLE dbo.T1(col1 INT);
...
ALTER TABLE dbo.T1 ADD col2 INT;
SELECT col1, col2 FROM dbo.T1;
...
ALTER TABLE dbo.T1 ADD col2 INT;
SELECT col1, col2 FROM dbo.T1;

EDUNEG Programación de Objetos 33 - 30


La opción GO n
DROP TABLE IF EXISTS dbo.T1;
CREATE TABLE dbo.T1(col1 INT IDENTITY);
...
SET NOCOUNT ON;
...
INSERT INTO dbo.T1 DEFAULT VALUES;
GO 100

SELECT * FROM dbo.T1;

EDUNEG Programación de Objetos 34 - 30


ELEMENTOS DE FLUJO

Utiliza elementos de flujo para controlar el flujo de su código. T-SQL


proporciona formas básicas de control con elementos de flujo, incluido
el IF. . . ELSE elemento y el elemento WHILE .

EDUNEG Programación de Objetos 35 - 30


IF… ELSE
IF YEAR(SYSDATETIME()) <> YEAR(DATEADD(day, 1, SYSDATETIME()))
PRINT 'Today is the last day of the year.';
ELSE
PRINT 'Today is not the last day of the year.';

EDUNEG Programación de Objetos 36 - 30


IF… ELSE
IF YEAR(SYSDATETIME()) <> YEAR(DATEADD(day, 1, SYSDATETIME()))
PRINT ‘Hoy es el ultimo día del año';
ELSE
IF MONTH(SYSDATETIME()) <> MONTH(DATEADD(day, 1, SYSDATETIME()))
PRINT ‘Hoy es el ultimo día del mes pero no del año';
ELSE
PRINT ‘Hoy no es ultimo día del Mes';

EDUNEG Programación de Objetos 37 - 30


IF… ELSE
IF DAY(SYSDATETIME()) = 1
BEGIN
PRINT 'Today is the first day of the month.';
PRINT 'Starting first-of-month-day process.';
/* ... process code goes here ... */
PRINT 'Finished first-of-month-day database process.';
END;
ELSE
BEGIN
PRINT 'Today is not the first day of the month.';
PRINT 'Starting non-first-of-month-day process.';
/* ... process code goes here ... */
PRINT 'Finished non-first-of-month-day process.';
END;

EDUNEG Programación de Objetos 38 - 30


IF… ELSE

EDUNEG Programación de Objetos 39 - 30


WHILE
DECLARE @i AS INT = 1;
WHILE @i <= 10
BEGIN
PRINT @i;
SET @i = @i + 1;
END;

EDUNEG Programación de Objetos 40 - 30


WHILE - Break
DECLARE @i AS INT = 1;
WHILE @i <= 10
BEGIN
IF @i = 6 BREAK;
PRINT @i;
SET @i = @i + 1;
END;

EDUNEG Programación de Objetos 41 - 30


WHILE - Continue
DECLARE @i AS INT = 0;
WHILE @i < 10
BEGIN
SET @i = @i + 1;
IF @i = 6 CONTINUE;
PRINT @i;
END;

EDUNEG Programación de Objetos 42 - 30


WHILE
SET NOCOUNT ON;
DROP TABLE IF EXISTS dbo.Numbers;
CREATE TABLE dbo.Numbers(n INT NOT NULL PRIMARY KEY);
GO
DECLARE @i AS INT = 1;
WHILE @i <= 1000
BEGIN
INSERT INTO dbo.Numbers(n) VALUES(@i);
SET @i = @i + 1;
END;

EDUNEG Programación de Objetos 43 - 30


CURSOR

SQL y T-SQL también admiten un objeto llamado cursor que puede usar para
procesar filas de un resultado de una consulta de una en una y en el orden
solicitado.
Esto contrasta con el uso de consultas basadas en conjuntos: consultas
normales sin cursor para las que manipula el conjunto o el conjunto múltiple
en su conjunto y no puede confiar en el orden.

EDUNEG Programación de Objetos 44 - 30


CURSOR - Pasos

1. Declare el cursor basado en una consulta.


2. Abra el cursor.
3. Obtenga los valores de los atributos del primer registro del cursor en variables.
4. Mientras no haya llegado al final del cursor (mientras el valor de una función
llamada
@@ FETCH_STATUS es 0 ), recorra los registros del cursor; En cada iteración del
bucle, realice el procesamiento necesario para la fila actual y luego busque los
valores de atributo de la siguiente fila en las variables.
5. Cerrar el cursor.
6. Desasignar el cursor.

EDUNEG Programación de Objetos 45 - 30


CURSOR - Ejemplo

SET NOCOUNT ON;


DECLARE @Result AS TABLE
(
custid INT,
ordermonth DATE,
qty INT,
runqty INT,
PRIMARY KEY(custid, ordermonth)
);

EDUNEG Programación de Objetos 46 - 30


CURSOR - Ejemplo

DECLARE
@custid AS INT,
@prvcustid AS INT,
@ordermonth AS DATE,
@qty AS INT,
@runqty AS INT;

EDUNEG Programación de Objetos 47 - 30


CURSOR - Ejemplo

DECLARE C CURSOR FAST_FORWARD /* read only, forward only */


FOR SELECT custid, ordermonth, qty
FROM Sales.CustOrders
ORDER BY custid, ordermonth;
OPEN C;
FETCH NEXT FROM C INTO @custid, @ordermonth, @qty;

SELECT @prvcustid = @custid, @runqty = 0;

EDUNEG Programación de Objetos 48 - 30


CURSOR - Ejemplo

WHILE @@FETCH_STATUS = 0
BEGIN
IF @custid <> @prvcustid
SELECT @prvcustid = @custid, @runqty = 0;

SET @runqty = @runqty + @qty;


INSERT INTO @Result VALUES(@custid, @ordermonth, @qty, @runqty);

FETCH NEXT FROM C INTO @custid, @ordermonth, @qty;


END;
EDUNEG Programación de Objetos 49 - 30
CURSOR - Ejemplo

CLOSE C;
DEALLOCATE C;

SELECT
custid,
CONVERT(VARCHAR(7), ordermonth, 121) AS ordermonth,
qty,
runqty
FROM @Result
ORDER BY custid, ordermonth;
EDUNEG Programación de Objetos 50 - 30
CURSOR - Ejemplo 2

SELECT custid, ordermonth, qty,


SUM(qty) OVER(PARTITION BY custid
ORDER BY ordermonth
ROWS UNBOUNDED PRECEDING) AS runqty
FROM Sales.CustOrders
ORDER BY custid, ordermonth;

EDUNEG Programación de Objetos 51 - 30


Tablas Temporales

Cuando necesite almacenar datos temporalmente en tablas, en ciertos casos


puede preferir no trabajar con tablas permanentes. Suponga que necesita que
los datos sean visibles solo para la sesión actual, o incluso solo para el lote
actual.

EDUNEG Programación de Objetos 52 - 30


Tablas Temporales locales

DROP TABLE IF EXISTS #MyOrderTotalsByYear;


GO
CREATE TABLE #MyOrderTotalsByYear
(
orderyear INT NOT NULL PRIMARY KEY,
qty INT NOT NULL
);

EDUNEG Programación de Objetos 53 - 30


Tablas Temporales locales

INSERT INTO #MyOrderTotalsByYear(orderyear, qty)


SELECT YEAR(O.orderdate) AS orderyear,
SUM(OD.qty) AS qty
FROM Sales.Orders AS O
INNER JOIN Sales.OrderDetails AS OD
ON OD.orderid = O.orderid
GROUP BY YEAR(orderdate);

EDUNEG Programación de Objetos 54 - 30


Tablas Temporales locales

SELECT Cur.orderyear,
Cur.qty AS curyearqty,
Prv.qty AS prvyearqty
FROM #MyOrderTotalsByYear AS Cur
LEFT OUTER JOIN #MyOrderTotalsByYear AS Prv
ON Cur.orderyear = Prv.orderyear + 1;

EDUNEG Programación de Objetos 55 - 30


Tablas Temporales Globales

DROP TABLE IF EXISTS ##Globals;


CREATE TABLE ##Globals
(
id sysname NOT NULL PRIMARY KEY,
val SQL_VARIANT NOT NULL
);
INSERT INTO ##Globals(id, val) VALUES(N'i', CAST(10 AS INT));

SELECT val FROM ##Globals WHERE id = N'i';

EDUNEG Programación de Objetos 56 - 30


Variables tipo TABLE

Las variables de tabla son similares a las tablas temporales locales en algunos
aspectos y diferentes en otros. Declara variables de tabla de la misma manera
que declara otras variables, utilizando la instrucción DECLARE .

Al igual que con las tablas temporales locales, las variables de tabla tienen una
presencia física como una tabla en la base de datos tempdb , al contrario del
error común de que solo existen en la memoria. Al igual que las tablas
temporales locales, las variables de tabla solo son visibles para la sesión de
creación, pero debido a que son variables tienen un alcance más limitado: solo
el lote actual. Las variables de tabla no son visibles ni para lotes internos en la
pila de llamadas ni para lotes posteriores en la sesión.
EDUNEG Programación de Objetos 57 - 30
Variables tipo TABLE

DECLARE @MyOrderTotalsByYear TABLE


(
orderyear INT NOT NULL PRIMARY KEY,
qty INT NOT NULL
);

EDUNEG Programación de Objetos 58 - 30


Variables tipo TABLE

INSERT INTO @MyOrderTotalsByYear(orderyear, qty)

SELECT
YEAR(O.orderdate) AS orderyear,
SUM(OD.qty) AS qty
FROM Sales.Orders AS O
INNER JOIN Sales.OrderDetails AS OD
ON OD.orderid = O.orderid
GROUP BY YEAR(orderdate);

EDUNEG Programación de Objetos 59 - 30


Variables tipo TABLE

SELECT
Cur.orderyear,
Cur.qty AS curyearqty,
Prv.qty AS prvyearqty
FROM
@MyOrderTotalsByYear AS Cur
LEFT OUTER JOIN @MyOrderTotalsByYear AS Prv
ON Cur.orderyear = Prv.orderyear + 1;

EDUNEG Programación de Objetos 60 - 30


Variables tipo TABLE – Función LAG

SELECT
YEAR(O.orderdate) AS orderyear,
SUM(OD.qty) AS curyearqty,
LAG(SUM(OD.qty))
OVER(ORDER BY YEAR(orderdate)) AS prvyearqty
FROM Sales.Orders AS O
INNER JOIN Sales.OrderDetails AS OD
ON OD.orderid = O.orderid
GROUP BY YEAR(orderdate);

EDUNEG Programación de Objetos 61 - 30


Lab #01
Usar Sales.OrderValues

EDUNEG Programación de Objetos 62 - 30


Lab #02
Usar Sales.OrderValues

EDUNEG Programación de Objetos 63 - 30


Lab #03
Usar Sales.EmpOrders

EDUNEG Programación de Objetos 64 - 30


Lab #04
Usar Sales.EmpOrders

EDUNEG Programación de Objetos 65 - 30


SQL Dinámico

Con SQL Server, puede construir un lote de código T-SQL como una cadena
de caracteres y luego ejecutar ese lote. Esta capacidad se llama SQL
dinámico.

SQL Server proporciona dos formas de ejecutar SQL dinámico:


• Usando el comando EXEC (abreviatura de EXECUTE ) y
• Usando el procedimiento almacenado sp_executesql

EDUNEG Programación de Objetos 66 - 30


SQL Dinámico – Comando EXEC

DECLARE @sql AS VARCHAR (100);

SET @sql = 'PRINT''Este mensaje fue impreso por un lote SQL


dinámico.'';';

EXEC (@sql);

EDUNEG Programación de Objetos 67 - 30


SQL Dinámico – Comando sp_executesql
DECLARE @sql AS NVARCHAR(100);

SET @sql = N'SELECT orderid, custid, empid, orderdate


FROM Sales.Orders
WHERE orderid = @orderid;';

EXEC sp_executesql
@stmt = @sql,
@params = N'@orderid AS INT',
@orderid = 10248;

EDUNEG Programación de Objetos 68 - 30


SQL Dinámico – Usar PIVOT con SQL dinámico
SELECT *
FROM (SELECT shipperid,
YEAR(orderdate) AS orderyear,
freight
FROM Sales.Orders) AS D
PIVOT(
SUM(freight)
FOR orderyear IN([2014],[2015],[2016])
) AS P;

EDUNEG Programación de Objetos 69 - 30


SQL Dinámico – Usar PIVOT con SQL dinámico
DECLARE @sql AS NVARCHAR(1000),
@orderyear AS INT,
@first AS INT;

DECLARE C CURSOR FAST_FORWARD FOR


SELECT DISTINCT(YEAR(orderdate)) AS orderyear
FROM Sales.Orders
ORDER BY orderyear;

SET @first = 1;

EDUNEG Programación de Objetos 70 - 30


SQL Dinámico – Usar PIVOT con SQL dinámico

SET @sql = N'SELECT *


FROM (SELECT shipperid,
YEAR(orderdate) AS orderyear,
freight
FROM Sales.Orders) AS D
PIVOT(SUM(freight) FOR orderyear IN(';
OPEN C;

FETCH NEXT FROM C INTO @orderyear;

EDUNEG Programación de Objetos 71 - 30


SQL Dinámico – Usar PIVOT con SQL dinámico
WHILE @@fetch_status = 0
BEGIN
IF @first = 0
SET @sql += N',’
ELSE
SET @first = 0;

SET @sql += QUOTENAME(@orderyear);


FETCH NEXT FROM C INTO @orderyear;
END;

EDUNEG Programación de Objetos 72 - 30


SQL Dinámico – Usar PIVOT con SQL dinámico

CLOSE C;
DEALLOCATE C;

SET @sql += N')) AS P;';

EXEC sp_executesql @stmt = @sql;

EDUNEG Programación de Objetos 73 - 30


Laboratorio
SQL Dinámico

EDUNEG - Escuela de Desarrollo Universal de Negocios


Base de Datos

EDUNEG Programación de Objetos 75


Realizar…
1. Insertar 03 registros en las 11 tablas usando
SQL Dinámico, usando la tabla de
configuración.
2. Actualizar los registros en el campo tipoVia =
9 de las tablas (tbl_05000_Capitulo_100,
tbl_10000_Capitulo_100 y
tbl_02000_Capitulo_100) usando SQL
Dinámico, usando la tabla de configuración.
3. Eliminar los registros que tengan tipoVia = 9
de las tablas (tbl_05000_Capitulo_100 y
tbl_02000_Capitulo_100) usando SQL
Dinámico, usando la tabla de configuración.

EDUNEG Programación de Objetos 76


RUTINAS

Las rutinas son objetos programables que encapsulan código para calcular
un resultado o ejecutar actividad.

SQL Server admite tres tipos de rutinas:


• Funciones definidas por el usuario (FUNCTION),
• Procedimientos almacenados (STORE PROCEDURE)
• y Disparadores (TRIGGER).

EDUNEG Programación de Objetos 77 - 30


Funciones definidas por el usuario - UDF
DROP FUNCTION IF EXISTS dbo.GetAge; BEGIN
GO RETURN
CREATE FUNCTION dbo.GetAge DATEDIFF(year, @birthdate,
@eventdate)
(
@birthdate AS DATE, - CASE WHEN 100 * MONTH(@eventdate)
+ DAY(@eventdate)
@eventdate AS DATE
< 100 * MONTH(@birthdate)
) + DAY(@birthdate)
RETURNS INT THEN 1 ELSE 0
AS END;
END;
GO

EDUNEG Programación de Objetos 78 - 30


Funciones definidas por el usuario - UDF

SELECT
empid,
firstname,
lastname,
birthdate,
dbo.GetAge(birthdate, SYSDATETIME()) AS age
FROM HR.Employees;

EDUNEG Programación de Objetos 79 - 30


LAB - Funciones definidas por el usuario - UDF

Se pide realizar una Función de usuario usando la tabla


Sales.OrderDetails, que permita calcular el descuento.

getDescuento(p1, p2)
p1 -> precio (cantidad por precio unitario)
p2 -> descuento

EDUNEG Programación de Objetos 80 - 30


Procedimientos almacenados

Los procedimientos almacenados son rutinas que encapsulan código.


Pueden tener parámetros de entrada y salida, pueden devolver conjuntos
de resultados de consultas y se les permite tener efectos secundarios.
No solo puede modificar datos a través de procedimientos almacenados,
sino que también puede aplicar cambios de esquema a través de ellos.

EDUNEG Programación de Objetos 81 - 30


Procedimientos almacenados
DROP PROC IF EXISTS SET NOCOUNT ON;
Sales.GetCustomerOrders; SELECT orderid, custid, empid,
GO orderdate
CREATE PROC Sales.GetCustomerOrders FROM Sales.Orders
@custid AS INT, WHERE custid = @custid
@fromdate AS DATETIME = '19000101', AND orderdate >= @fromdate
@todate AS DATETIME = '99991231', AND orderdate < @todate;
@numrows AS INT OUTPUT
AS SET @numrows = @@rowcount;
GO

EDUNEG Programación de Objetos 82 - 30


Procedimientos almacenados

DECLARE @rc AS INT;


EXEC Sales.GetCustomerOrders
@custid = 1,
@fromdate = '20150101',
@todate = '20160101',
@numrows = @rc OUTPUT;

SELECT @rc AS numrows;

EDUNEG Programación de Objetos 83 - 30


Disparadores

Un activador es un tipo especial de procedimiento almacenado, uno


que no se puede ejecutar explícitamente.
En cambio, se adjunta a un evento. Cada vez que tiene lugar el evento,
el disparador se dispara y se ejecuta el código del disparador.
SQL Server admite la asociación de disparadores con dos tipos de
eventos:
• Eventos de manipulación de datos (disparadores DML) como INSERT
• Y eventos de definición de datos (disparadores DDL) como CREATE
TABLE .

EDUNEG Programación de Objetos 84 - 30


Disparadores – DML
DROP TABLE IF EXISTS dbo.T1_Audit, dbo.T1;
CREATE TABLE dbo.T1
(
keycol INT NOT NULL PRIMARY KEY,
datacol VARCHAR(10) NOT NULL
);
CREATE TABLE dbo.T1_Audit
(
audit_lsn INT NOT NULL IDENTITY PRIMARY KEY,
dt DATETIME2(3) NOT NULL DEFAULT(SYSDATETIME()),
login_name sysname NOT NULL DEFAULT(ORIGINAL_LOGIN()),
keycol INT NOT NULL,
datacol VARCHAR(10) NOT NULL
);
EDUNEG Programación de Objetos 85 - 30
Disparadores

CREATE TRIGGER trg_T1_insert_audit


ON dbo.T1 AFTER INSERT
AS
SET NOCOUNT ON;
INSERT INTO dbo.T1_Audit(keycol, datacol)
SELECT keycol, datacol FROM inserted;
GO

EDUNEG Programación de Objetos 86 - 30


Disparadores

INSERT INTO dbo.T1(keycol, datacol) VALUES(10, 'a');


INSERT INTO dbo.T1(keycol, datacol) VALUES(30, 'x');
INSERT INTO dbo.T1(keycol, datacol) VALUES(20, 'g’);
...
SELECT audit_lsn, dt, login_name, keycol, datacol
FROM dbo.T1_Audit;

EDUNEG Programación de Objetos 87 - 30


Disparadores – DDL

SQL Server admite desencadenadores DDL, que pueden usarse para


fines tales como auditoría, aplicación de políticas y gestión de cambios.
SQL Server admite la creación de desencadenadores DDL en dos
ámbitos:
• El ámbito de la Base de Datos y
• El ámbito del servidor

EDUNEG Programación de Objetos 88 - 30


Disparadores – DDL
DROP TABLE IF EXISTS dbo.AuditDDLEvents;
CREATE TABLE dbo.AuditDDLEvents
(
audit_lsn INT NOT NULL IDENTITY,
posttime DATETIME2(3) NOT NULL,
eventtype sysname NOT NULL,
loginname sysname NOT NULL,
schemaname sysname NOT NULL,
objectname sysname NOT NULL,
targetobjectname sysname NULL,
eventdata XML NOT NULL,
CONSTRAINT PK_AuditDDLEvents PRIMARY KEY(audit_lsn)
);

EDUNEG Programación de Objetos 89 - 30


Disparadores – DDL
CREATE TRIGGER trg_audit_ddl_events
ON DATABASE FOR DDL_DATABASE_LEVEL_EVENTS
AS
SET NOCOUNT ON;
DECLARE @eventdata AS XML = eventdata();
INSERT INTO dbo.AuditDDLEvents(
posttime, eventtype, loginname, schemaname,
objectname, targetobjectname, eventdata)
VALUES(
@eventdata.value('(/EVENT_INSTANCE/PostTime)[1]', 'VARCHAR(23)'),
@eventdata.value('(/EVENT_INSTANCE/EventType)[1]', 'sysname'),
@eventdata.value('(/EVENT_INSTANCE/LoginName)[1]', 'sysname'),
@eventdata.value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname'),
@eventdata.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname'),
@eventdata.value('(/EVENT_INSTANCE/TargetObjectName)[1]', 'sysname'),
@eventdata);
EDUNEG
GO Programación de Objetos 90 - 30
Disparadores – DDL
CREATE TABLE dbo.T1(col1 INT NOT NULL PRIMARY KEY);
ALTER TABLE dbo.T1 ADD col2 INT NULL;
ALTER TABLE dbo.T1 ALTER COLUMN col2 INT NOT NULL;
CREATE NONCLUSTERED INDEX idx1 ON dbo.T1(col2);
...
SELECT * FROM dbo.AuditDDLEvents;

EDUNEG Programación de Objetos 91 - 30


Examen Final
1. Crear la Base de Datos
2. Insertar registros a las tablas creadas
3. Crear un Cursor que te identifique todos los registros
que son de lima e imprimir su identificación de registro.
4. Crear una función que te devuelva los nombres de la vía,
según código de vía
5. Crear un procedimiento almacenado que genere un resumen
de la información registrada por departamento
6. Crear un Trigger que te guarde el histórico de una
variable de la caratula de la encuesta

EDUNEG Programación de Objetos 92 - 30

You might also like