TRANSACT – SQL DEL SQL SERVER 2000 – Ejemplos y Sintaxis
Es el lenguaje SQL que emplea SQL Server 2000, cuando se ejecuta una instrucción
SQL simple se está empleando Transact, se puede forzar a que utilice el estándar SQL-
92, que realmente es lo mismo pero con menor funcionalidad.
Referencia básica con ejemplos ( índice )
1
USE 3
GO 3
PRINT 4
EXECUTE - EXEC 4
IDENTIFICADORES TRANSACT-SQL 5
DECLARE @local_variable
5
TRIGGERS
6
CREATE FUNCTION
7
CREATE PROCEDURE
8
LIKE
9
JOIN
10
SET NOCOUNT
11
SET NOEXEC
11
SELECT
11
DELETE
13
INSERT
13
CREATE STATISTICS
14
CREATE RULE
14
CREATE VIEW
15
CREATE TABLE
15
UPDATE
16
@@FETCH_STATUS
16
@@ERROR
17
@@ROWCOUNT
18
TRANSACCIONES
19
DECLARE CURSOR
2
---------------------------------------------------------------------------------------------------------
USE
Cambia el contexto de la base de datos al de la base de datos especificada.
Sintaxis
USE {baseDatos}
GO
Indica a las herramientas de Microsoft® SQL Server™ el final de un lote de
instrucciones Transact-SQL. Permite ejecutar varias instrucciones por separado una a
continuación de la otra.
Sintaxis
GO
Ejemplo:
USE pubs
GO
DECLARE @NmbrAuthors int
SELECT @NmbrAuthors = COUNT(*)
FROM authors
PRINT 'The number of authors as of ' +
CAST(GETDATE() AS char(20)) + ' is ' +
CAST(@NmbrAuthors AS char (10))
GO
PRINT
Devuelve al cliente un mensaje definido por el usuario.
Observaciones
Para imprimir un mensaje de error definido por el usuario cuando se tiene el número de
error que se puede obtener con @@ERROR, utilice RAISERROR en lugar de PRINT.
Ejemplos
A. Impresión ejecutada condicionalmente (IF EXISTS)
Este ejemplo utiliza la instrucción PRINT para devolver un mensaje condicionalmente.
IF EXISTS (SELECT zip FROM authors WHERE zip = '94705')
3
PRINT 'Berkeley author'
B. Crear y mostrar una cadena
Este ejemplo convierte el resultado de la función GETDATE al tipo de datos varchar y
le concatena texto literal que devuelve PRINT.
PRINT 'This message was printed on ' +
RTRIM(CONVERT(varchar(30), GETDATE())) + '.'
EXECUTE - EXEC
Ejecuta una función definida por el usuario y que devuelve valores escalares, un
procedimiento del sistema, un procedimiento almacenado definido por el usuario o un
procedimiento almacenado extendido. Admite también la ejecución de una cadena de
caracteres en un proceso por lotes Transact-SQL.
Para llamar a una función, utilice la sintaxis que se describe para EXECUTE
stored_procedure.
F. Utilizar EXECUTE con una variable de procedimiento almacenado
El ejemplo siguiente crea una variable que representa un nombre de procedimiento
almacenado.
DECLARE @proc_name varchar(30)
SET @proc_name = 'sp_who'
EXEC @proc_name
El procedimiento almacenado proc_calculate_taxes se puede ejecutar con muchas
combinaciones:
EXECUTE proc_calculate_taxes @p2 = 'A'
EXECUTE proc_calculate_taxes 69, 'B'
EXECUTE proc_calculate_taxes 69, 'C', 'House'
EXECUTE proc_calculate_taxes @p1 = DEFAULT, @p2 = 'D'
IDENTIFICADORES TRANSACT-SQL
@ = variable global
# = objeto temporal local
## = objeto temporal global
DECLARE @local_variable
Las variables se declaran en el cuerpo de un proceso por lotes o procedimiento con la
instrucción DECLARE, y se les asignan valores con una instrucción SET o SELECT.
Las variables de cursor pueden declararse con esta instrucción y utilizarse con otras
4
instrucciones relacionadas con los cursores. Después de su declaración, todas las
variables se inicializan con NULL (nulo).
A. Utilizar DECLARE
Este ejemplo utiliza una variable local denominada @find para recuperar información
de todos los autores cuyos apellidos comienzan con Ring.
USE pubs
DECLARE @find varchar(30)
SET @find = 'Ring%'
SELECT au_lname, au_fname, phone
FROM authors
WHERE au_lname LIKE @find
El siguiente es el conjunto de resultados:
au_lname au_fname phone
-------------------------------------- --------------------
------------
Ringer Anne 801 826-
0752
Ringer Albert 801 826-
0752
(2 row(s) affected)
B. Utilizar DECLARE con dos variables
Este ejemplo recupera nombres de empleados de los empleados de Binnet & Hardley
(pub_id = 0877) contratados el 1 de enero de 1993 o posteriormente.
USE pubs
SET NOCOUNT ON
GO
DECLARE @pub_id char(4), @hire_date datetime
SET @pub_id = '0877'
SET @hire_date = '1/01/93'
-- Here is the SELECT statement syntax to assign values to two local
-- variables.
-- SELECT @pub_id = '0877', @hire_date = '1/01/93'
SET NOCOUNT OFF
SELECT fname, lname
FROM employee
WHERE pub_id = @pub_id and hire_date >= @hire_date
El siguiente es el conjunto de resultados:
fname lname
-------------------- ------------------------------
Anabela Domingues
Paul Henriot
5
(2 row(s) affected)
TRIGGERS
A. Utilizar un desencadenador con un mensaje de aviso
El siguiente desencadenador de ejemplo imprime un mensaje en el cliente cuando
alguien intenta agregar o cambiar datos en la tabla titles.
Nota El mensaje 50009 es un mensaje definido por el usuario en sysmessages. Para
obtener más información acerca de la creación de mensajes definidos por el usuario,
consulte sp_addmessage.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'reminder' AND type = 'TR')
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERT, UPDATE
AS RAISERROR (50009, 16, 10)
GO
F. Utilizar COLUMNS_UPDATED para probar más de 8 columnas
Si tiene que probar actualizaciones que afectan a otras columnas que no sean las 8
primeras de una tabla, debe utilizar la función SUBSTRING para probar si
COLUMNS_UPDATED devuelve el bit correcto. Este ejemplo prueba las
actualizaciones que afectan a las columnas 3, 5 o 9 de la tabla
Northwind.dbo.Customers.
USE Northwind
DROP TRIGGER tr1
GO
CREATE TRIGGER tr1 ON Customers
FOR UPDATE AS
IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1)=power(2,(3-1))
+ power(2,(5-1)))
AND (SUBSTRING(COLUMNS_UPDATED(),2,1)=power(2,(1-1)))
)
PRINT 'Columns 3, 5 and 9 updated'
GO
UPDATE Customers
SET ContactName=ContactName,
Address=Address,
Country=Country
GO
6
CREATE FUNCTION
A. Función de valores escalares definida por el usuario que calcula la semana ISO
En este ejemplo, una función definida por el usuario, ISOweek, toma un argumento de
fecha y calcula el número de semana ISO. Para que esta función realice el cálculo
correctamente, se debe llamar a SET DATEFIRST 1 antes de llamar a la función.
CREATE FUNCTION ISOweek (@DATE datetime)
RETURNS int
AS
BEGIN
DECLARE @ISOweek int
SET @ISOweek= DATEPART(wk,@DATE)+1
-DATEPART(wk,CAST(DATEPART(yy,@DATE) as CHAR(4))+'0104')
--Special cases: Jan 1-3 may belong to the previous year
IF (@ISOweek=0)
SET @ISOweek=dbo.ISOweek(CAST(DATEPART(yy,@DATE)-1
AS CHAR(4))+'12'+ CAST(24+DATEPART(DAY,@DATE) AS CHAR(2)))+1
--Special case: Dec 29-31 may belong to the next year
IF ((DATEPART(mm,@DATE)=12) AND
((DATEPART(dd,@DATE)-DATEPART(dw,@DATE))>= 28))
SET @ISOweek=1
RETURN(@ISOweek)
END
Ésta es la llamada a la función. Observe que el valor de DATEFIRST es 1.
SET DATEFIRST 1
SELECT master.dbo.ISOweek('12/26/1999') AS 'ISO Week'
Éste es el conjunto de resultados:
ISO Week
----------------
52
CREATE PROCEDURE
Procedimientos almacenados temporales
De forma similar a las tablas temporales, los procedimientos almacenados temporales,
tanto privados como globales, se pueden crear agregando los prefijos # y ## delante del
nombre del procedimiento. # denota un procedimiento almacenado temporal local; ##
denota un procedimiento almacenado temporal global. Estos procedimientos dejan de
existir cuando se cierra SQL Server.
A. Utilizar un procedimiento sencillo con una instrucción SELECT compleja
Este procedimiento almacenado devuelve todos los autores (nombre y apellidos), los
títulos y los publicadores a partir de una combinación de cuatro tablas. Este
procedimiento almacenado no utiliza ningún parámetro.
USE pubs
7
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'au_info_all' AND type = 'P')
DROP PROCEDURE au_info_all
GO
CREATE PROCEDURE au_info_all
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
GO
El procedimiento almacenado au_info_all se puede ejecutar de estas formas:
EXECUTE au_info_all
-- Or
EXEC au_info_all
O si este procedimiento es la primera instrucción del proceso por lotes:
au_info_all
B. Utilizar un procedimiento sencillo con parámetros
Este procedimiento almacenado devuelve sólo los autores especificados (nombre y
apellidos), los títulos y los publicadores a partir de una combinación de cuatro tablas.
Este procedimiento almacenado acepta coincidencias exactas de los parámetros pasados.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'au_info' AND type = 'P')
DROP PROCEDURE au_info
GO
USE pubs
GO
CREATE PROCEDURE au_info
@lastname varchar(40),
@firstname varchar(20)
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
WHERE au_fname = @firstname
AND au_lname = @lastname
GO
El procedimiento almacenado au_info se puede ejecutar de estas formas:
EXECUTE au_info 'Dull', 'Ann'
-- Or
EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'
-- Or
EXEC au_info 'Dull', 'Ann'
8
-- Or
EXEC au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXEC au_info @firstname = 'Ann', @lastname = 'Dull'
O si este procedimiento es la primera instrucción del proceso por lotes:
au_info 'Dull', 'Ann'
-- Or
au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
au_info @firstname = 'Ann', @lastname = 'Dull'
Ver Tambien
* DROP PROCEDURE
* ALTER PROCEDURE
LIKE
Carácter Descripción Ejemplo
comodín
% Cualquier cadena de cero o WHERE title LIKE '%computer%'
más caracteres. busca todos los títulos de libros que
contengan la palabra 'computer' en
cualquier parte del título.
_ (subrayado) Cualquier carácter individual WHERE au_fname LIKE '_ean' busca
todos los nombres de cuatro letras que
finalicen con ean (Dean, Sean, etc.).
[] Cualquier carácter individual WHERE au_lname LIKE '[C-P]arsen'
de intervalo ([a-f]) o del busca apellidos de autores que terminen
conjunto ([abcdef]) con arsen y comiencen con cualquier
especificado. carácter individual entre C y P, por
ejemplo Carsen, Larsen, Karsen, etc.
[^] Cualquier carácter individual WHERE au_lname LIKE 'de[^l]%'
que no se encuentre en el busca todos los apellidos de autores que
intervalo ([^a-f]) o el conjunto comienzan con de y en los que la
([^abcdef]) especificado. siguiente letra no sea l.
Utilizar caracteres comodín como literales
Los caracteres comodín de concordancia de patrón se pueden utilizar como literales.
Para utilizar como literal un carácter comodín, inclúyalo entre corchetes. La tabla
muestra varios ejemplos del uso de la palabra clave LIKE y los caracteres comodín [ ].
9
Símbolo Significado
LIKE '5[%]' 5%
LIKE '[_]n' _n
LIKE '[a-cdf]' a, b, c, d o f
LIKE '[-acdf]' -, a, c, d o f
LIKE '[ [ ]' [
LIKE ']' ]
LIKE 'abc[_]d%' abc_d y abc_de
LIKE 'abc[def]' abcd, abce y abcf
JOIN
Esta consulta de Transact-SQL es un ejemplo de una combinación interna:
USE pubs
SELECT *
FROM authors AS a INNER JOIN publishers AS p
ON a.city = p.city
ORDER BY a.au_lname DESC
• LEFT OUTER JOIN o LEFT JOIN
• RIGHT OUTER JOIN o RIGHT JOIN
• FULL OUTER JOIN o FULL JOIN
USE pubs
SELECT a.au_fname, a.au_lname, p.pub_name
FROM authors a LEFT OUTER JOIN publishers p
ON a.city = p.city
ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ASC
REALIZA EL PRODUCTO CARTESIANO DE LAS TABLAS
USE pubs
SELECT au_fname, au_lname, pub_name
FROM authors CROSS JOIN publishers
ORDER BY au_lname DESC
10
SET NOCOUNT
Hace que deje de devolverse como parte de los resultados el mensaje que indica el
número de filas afectado por una instrucción Transact-SQL.
Sintaxis
SET NOCOUNT { ON | OFF }
SET NOEXEC
Compila cada consulta, pero no la ejecuta.
Sintaxis
SET NOEXEC { ON | OFF }
SELECT
SELECT select_list
[ INTO new_table ]
FROM table_source
[ WHERE search_condition ]
[ GROUP BY group_by_expression ]
[ HAVING search_condition ]
[ ORDER BY order_expression [ ASC | DESC ] ]
Se puede utilizar el operador UNION entre consultas para combinar sus resultados en
un solo conjunto de resultados.
Sintaxis
SELECT statement ::=
< query_expression >
[ ORDER BY { order_by_expression | column_position [ ASC | DESC ] }
[,...n] ]
[ COMPUTE
{ { AVG | COUNT | MAX | MIN | SUM } ( expression ) } [ ,...n ]
[ BY expression [ ,...n ] ]
]
[ FOR { BROWSE | XML { RAW | AUTO | EXPLICIT }
[ , XMLDATA ]
[ , ELEMENTS ]
[ , BINARY base64 ]
}
]
[ OPTION ( < query_hint > [ ,...n ]) ]
11
< query expression > ::=
{ < query specification > | ( < query expression > ) }
[ UNION [ ALL ] < query specification | ( < query expression > ) [...n ] ]
< query specification > ::=
SELECT [ ALL | DISTINCT ]
[ { TOP integer | TOP integer PERCENT } [ WITH TIES ] ]
< select_list >
[ INTO new_table ]
[ FROM { < table_source > } [ ,...n ] ]
[ WHERE < search_condition > ]
[ GROUP BY [ ALL ] group_by_expression [ ,...n ]
[ WITH { CUBE | ROLLUP } ]
]
[ HAVING < search_condition > ]
Cláusula COMPUTE
Genera totales que aparecen como columnas de resumen adicionales al final del
conjunto de resultados.
XML
Especifica que el resultado de una consulta se devolverá como un documento XML.
CUBE
Especifica que, además de las filas que normalmente proporciona GROUP BY, deben
incluirse filas de resumen en el conjunto de resultados. Se devuelve una fila de resumen
GROUP BY por cada posible combinación de grupo y subgrupo del conjunto de
resultados.
ROLLUP
Especifica que, además de las filas que normalmente proporciona GROUP BY, deben
incluirse filas de resumen en el conjunto de resultados. Los grupos se resumen en un
orden jerárquico, desde el nivel inferior del grupo al superior. La jerarquía del grupo se
determina mediante el orden en que se especifican las columnas de agrupamiento.
Importante Cube y RollUp No es posible utilizar agregados diferentes, por ejemplo
AVG(DISTINCT column_name), COUNT(DISTINCT column_name) y
SUM(DISTINCT column_name) cuando se utiliza CUBE o ROLLUP
DELETE
Ejemplos
A. Utilizar DELETE sin parámetros
12
Este ejemplo elimina todas las filas de la tabla authors.
USE pubs
DELETE authors
B. Utilizar DELETE en un conjunto de filas
Debido a que au_lname puede no ser único, este ejemplo elimina todas las filas en que
au_lname es McBadden.
USE pubs
DELETE FROM authors
WHERE au_lname = 'McBadden'
C. Utilizar DELETE en la fila actual de un cursor
Este ejemplo muestra una eliminación realizada contra un cursor denominado
complex_join_cursor. Sólo afecta a la única fila que se recupera actualmente del
cursor.
USE pubs
DELETE FROM authors
WHERE CURRENT OF complex_join_cursor
INSERT
CREATE TABLE T1 ( column_1 int, column_2 varchar(30))
INSERT T1 (column_2, column_1) VALUES ('Row #1',1)
CREATE STATISTICS
Crea un histograma y los grupos de densidad asociados (colecciones) sobre la columna
o conjunto de columnas especificados.
A. Utilizar CREATE STATISTICS con SAMPLE number PERCENT
El ejemplo siguiente crea el grupo de estadísticas (colección) names, que calcula
estadísticas de muestreo aleatorio sobre el cinco por ciento de las columnas
CompanyName y ContactName de la tabla Customers.
CREATE STATISTICS names
ON Customers (CompanyName, ContactName)
WITH SAMPLE 5 PERCENT
GO
B. Utilizar CREATE STATISTICS con FULLSCAN y NORECOMPUTE
Este ejemplo crea el grupo de estadísticas (colección) names, que calcula estadísticas de
todas las columnas CompanyName y ContactName de la tabla Customers, y
deshabilita la capacidad de volver a calcular automáticamente las estadísticas.
CREATE STATISTICS names
13
ON Northwind..Customers (CompanyName, ContactName)
WITH FULLSCAN, NORECOMPUTE
GO
CREATE RULE
Crea un objeto denominado regla. Cuando se enlaza una regla a una columna o un tipo
de datos definido por el usuario, la regla especifica los valores aceptables que se pueden
insertar en esa columna. Una columna puede tener una regla y una o más restricciones
CHECK asociadas a ella. Cuando esto es así, se evalúan todas las restricciones.
A. Regla con un intervalo - restringe el intervalo de enteros
CREATE RULE range_rule
AS
@range >= $1000 AND @range < $20000
B. Regla con una lista
CREATE RULE list_rule
AS
@list IN ('1389', '0736', '0877')
C. Regla con un patrón
CREATE RULE pattern_rule
AS
@value LIKE '_ _-%[0-9]'
CREATE VIEW
Crea una tabla virtual que representa los datos de una o más tablas de una forma
alternativa. CREATE VIEW debe ser la primera instrucción en una secuencia de
consultas.
--create the view that combines all supplier tables
CREATE VIEW all_supplier_view
AS
SELECT *
FROM SUPPLY1
UNION ALL
SELECT *
FROM SUPPLY2
UNION ALL
SELECT *
FROM SUPPLY3
UNION ALL
SELECT *
FROM SUPPLY4
D. Utilizar funciones integradas en una vista
USE pubs
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_NAME = 'categories')
14
DROP VIEW categories
GO
CREATE VIEW categories (category, average_price)
AS
SELECT type, AVG(price)
FROM titles
GROUP BY type
GO
VER TAMBIEN
• DROP VIEW
• ALTER VIEW
CREATE TABLE
CREATE TABLE T1
( column_1 int identity,
column_2 varchar(30)
CONSTRAINT default_name DEFAULT ('column default'),
column_3 int NULL,
column_4 varchar(40)
)
INSERT INTO T1 (column_4)
VALUES ('Explicit value')
INSERT INTO T1 (column_2,column_4)
VALUES ('Explicit value', 'Explicit value')
INSERT INTO T1 (column_2,column_3,column_4)
VALUES ('Explicit value',-44,'Explicit value')
SELECT *
FROM T1
UPDATE
UPDATE Northwind.dbo.Products
SET UnitPrice = UnitPrice * 1.1
WHERE CategoryID = 2
UPDATE CON UN CURSOR
USE Northwind
GO
DECLARE abc CURSOR FOR
SELECT CompanyName
FROM Shippers
OPEN abc
GO
FETCH NEXT FROM abc
GO
15
UPDATE Shippers SET CompanyName = N'Speedy Express, Inc.'
WHERE CURRENT OF abc
GO
CLOSE abc
DEALLOCATE abc
GO
@@FETCH_STATUS
Devuelve el estado de la última instrucción FETCH de cursor ejecutada sobre cualquier
cursor que la conexión haya abierto.
Valor de retorno Descripción
0 La instrucción FETCH se ejecutó correctamente.
-1 La instrucción FETCH ha finalizado con error o la fila estaba más
allá del conjunto de resultados.
-2 Falta la fila recuperada.
Sintaxis
@@FETCH_STATUS
@@ERROR
Devuelve el número de error de la última instrucción Transact-SQL ejecutada.
Sintaxis
@@ERROR
Tipos devueltos
integer
A. Utilizar @@ERROR para detectar un error específico
USE pubs
GO
UPDATE authors SET au_id = '172 32 1176'
WHERE au_id = "172-32-1176"
IF @@ERROR = 547
print "A check constraint violation occurred"
B. Utilizar @@ERROR para salir condicionalmente de un procedimiento
16
-- Test the error value.
IF @@ERROR <> 0
BEGIN
-- Return 99 to the calling program to indicate failure.
PRINT "An error occurred loading the new author information"
RETURN(99)
END
ELSE
BEGIN
-- Return 0 to the calling program to indicate success.
PRINT "The new author information has been loaded"
RETURN(0)
END
C. Utilizar @@ERROR para comprobar el éxito de varias instrucciones
Este ejemplo depende de la ejecución con éxito de las instrucciones INSERT y
DELETE. Se establece el valor de @@ERROR en variables locales después de ambas
instrucciones y se utilizan las variables en una rutina de tratamiento de errores común
para la operación.
USE pubs
GO
DECLARE @del_error int, @ins_error int
-- Start a transaction.
BEGIN TRAN
-- Execute the DELETE statement.
DELETE authors
WHERE au_id = '409-56-7088'
-- Set a variable to the error value for
-- the DELETE statement.
SELECT @del_error = @@ERROR
-- Execute the INSERT statement.
INSERT authors
VALUES('409-56-7008', 'Bennet', 'Abraham', '415 658-9932',
'6223 Bateman St.', 'Berkeley', 'CA', '94705', 1)
-- Set a variable to the error value for
-- the INSERT statement.
SELECT @ins_error = @@ERROR
-- Test the error values.
IF @del_error = 0 AND @ins_error = 0
BEGIN
-- Success. Commit the transaction.
PRINT "The author information has been replaced"
COMMIT TRAN
END
ELSE
BEGIN
-- An error occurred. Indicate which operation(s) failed
-- and roll back the transaction.
IF @del_error <> 0
PRINT "An error occurred during execution of the DELETE
statement."
IF @ins_error <> 0
17
PRINT "An error occurred during execution of the INSERT
statement."
ROLLBACK TRAN
END
GO
@@ROWCOUNT
Devuelve el número de filas afectadas por la última instrucción.
Sintaxis
@@ROWCOUNT
Tipos devueltos
integer
detectar si se ha modificado alguna fila
UPDATE authors SET au_lname = 'Jones'
WHERE au_id = '999-888-7777'
IF @@ROWCOUNT = 0
print 'Warning: No rows were updated'
TRANSACCIONES
Ejemplos
En este ejemplo se modifica el reparto de derechos de autor entre los dos autores de The
Gourmet Microwave. Debido a que el estado de la base de datos sería incoherente entre
dos actualizaciones, éstas se deben agrupar en una transacción definida por el usuario.
BEGIN TRANSACTION royaltychange
UPDATE titleauthor
SET royaltyper = 65
FROM titleauthor, titles
WHERE royaltyper = 75
AND titleauthor.title_id = titles.title_id
AND title = 'The Gourmet Microwave'
UPDATE titleauthor
SET royaltyper = 35
FROM titleauthor, titles
WHERE royaltyper = 25
AND titleauthor.title_id = titles.title_id
AND title = 'The Gourmet Microwave'
SAVE TRANSACTION percentchanged
/*
After having updated the royaltyper entries for the two authors, the
user inserts the savepoint percentchanged, and then determines how a
10-percent increase in the book's price would affect the authors'
royalty earnings.
18
*/
UPDATE titles
SET price = price * 1.1
WHERE title = 'The Gourmet Microwave'
SELECT (price * royalty * ytd_sales) * royaltyper
FROM titles, titleauthor
WHERE title = 'The Gourmet Microwave'
AND titles.title_id = titleauthor.title_id
/*
The transaction is rolled back to the savepoint
with the ROLLBACK TRANSACTION statement.
*/
ROLLBACK TRANSACTION percentchanged
COMMIT TRANSACTION
/* End of royaltychange. */
DECLARE CURSOR
Define los atributos de un cursor de servidor Transact-SQL, como su comportamiento
de desplazamiento y la consulta utilizada para generar el conjunto de resultados sobre el
que opera el cursor. DECLARE CURSOR acepta la sintaxis basada en el estándar SQL-
92 y la sintaxis de un conjunto de extensiones de Transact-SQL.
Sintaxis extendida de Transact-SQL
DECLARE cursor_name CURSOR
[ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]
STATIC
Define un cursor que hace una copia temporal de los datos que utiliza. Todas las
peticiones al cursor se responden desde esta tabla temporal de tempdb; por ello, las
modificaciones realizadas en las tablas base no se reflejarán en los datos obtenidos en
las recuperaciones realizadas en el cursor y además este cursor no admite
modificaciones.
Observaciones
DECLARE CURSOR define los atributos de un cursor de servidor Transact-SQL,
como su comportamiento de desplazamiento y la consulta utilizada para generar el
conjunto de resultados en que opera el cursor. La instrucción OPEN llena el conjunto de
resultados y la instrucción FETCH devuelve una fila del conjunto de resultados. La
instrucción CLOSE libera el conjunto de resultados actual asociado con el cursor. La
instrucción DEALLOCATE libera los recursos que utiliza el cursor.
19
A. Utilizar cursores simples y su sintaxis
El conjunto de resultados generado al abrir este cursor contiene todas las filas y todas
las columnas de la tabla authors de la base de datos pubs. Este cursor se puede
actualizar, y todas las actualizaciones y eliminaciones se representan en las
recuperaciones realizadas contra el cursor. FETCH NEXT es la única recuperación
disponible debido a que no se ha especificado la opción SCROLL.
DECLARE authors_cursor CURSOR
FOR SELECT * FROM authors
OPEN authors_cursor
FETCH NEXT FROM authors_cursor
B. Utilizar cursores anidados para elaborar resultados de informes
Este ejemplo muestra cómo se pueden anidar los cursores para elaborar informes
complejos. El cursor interno se declara para cada autor.
SET NOCOUNT ON
DECLARE @au_id varchar(11), @au_fname varchar(20), @au_lname
varchar(40),
@message varchar(80), @title varchar(80)
PRINT "-------- Utah Authors report --------"
DECLARE authors_cursor CURSOR FOR
SELECT au_id, au_fname, au_lname
FROM authors
WHERE state = "UT"
ORDER BY au_id
OPEN authors_cursor
FETCH NEXT FROM authors_cursor
INTO @au_id, @au_fname, @au_lname
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT " "
SELECT @message = "----- Books by Author: " +
@au_fname + " " + @au_lname
PRINT @message
-- Declare an inner cursor based
-- on au_id from the outer cursor.
DECLARE titles_cursor CURSOR FOR
SELECT t.title
FROM titleauthor ta, titles t
WHERE ta.title_id = t.title_id AND
ta.au_id = @au_id -- Variable value from the outer cursor
OPEN titles_cursor
FETCH NEXT FROM titles_cursor INTO @title
20
IF @@FETCH_STATUS <> 0
PRINT " <<No Books>>"
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @message = " " + @title
PRINT @message
FETCH NEXT FROM titles_cursor INTO @title
END
CLOSE titles_cursor
DEALLOCATE titles_cursor
-- Get the next author.
FETCH NEXT FROM authors_cursor
INTO @au_id, @au_fname, @au_lname
END
CLOSE authors_cursor
DEALLOCATE authors_cursor
GO
-------- Utah Authors report --------
----- Books by Author: Anne Ringer
The Gourmet Microwave
Is Anger the Enemy?
----- Books by Author: Albert Ringer
Is Anger the Enemy?
Life Without Fear
BACKUP
-- Create the backup device for the full MyNwind backup.
USE master
EXEC sp_addumpdevice 'disk', 'MyNwind_2',
'c:\Program Files\Microsoft SQL Server\MSSQL\BACKUP\MyNwind_2.dat'
--Create the log backup device.
USE master
EXEC sp_addumpdevice 'disk', 'MyNwindLog1',
'c:\Program Files\Microsoft SQL
Server\MSSQL\BACKUP\MyNwindLog1.dat'
-- Back up the full MyNwind database.
BACKUP DATABASE MyNwind TO MyNwind_2
-- Update activity has occurred since the full database backup.
-- Back up the log of the MyNwind database.
BACKUP LOG MyNwind
TO MyNwindLog1
21
WHILE
WHILE Boolean_expression
{sql_statement | statement_block}
[BREAK]
{sql_statement | statement_block}
[CONTINUE]
A. Utilizar BREAK y CONTINUE con IF...ELSE y WHILE anidados
En este ejemplo, si el promedio de precio es menor de 30 $, el bucle WHILE dobla los
precios y, a continuación, selecciona el precio máximo. Si el precio máximo es menor o
igual que 50 $, el bucle WHILE se reinicia y dobla los precios de nuevo. Este bucle
continúa la duplicación de precios hasta que el precio máximo sea mayor que 50 $ y, a
continuación, sale del bucle WHILE e imprime un mensaje.
USE pubs
GO
WHILE (SELECT AVG(price) FROM titles) < $30
BEGIN
UPDATE titles
SET price = price * 2
SELECT MAX(price) FROM titles
IF (SELECT MAX(price) FROM titles) > $50
BREAK
ELSE
CONTINUE
END
PRINT 'Too much for the market to bear'
CASE
Evalúa una lista de condiciones y devuelve como resultado una de las distintas
expresiones posibles.
CASE tiene dos formatos:
• La función CASE sencilla compara una expresión con un conjunto de
expresiones sencillas para determinar el resultado.
• La función CASE de búsqueda evalúa un conjunto de expresiones booleanas
para determinar el resultado.
A. Utilizar una instrucción SELECT con una función CASE sencilla
USE pubs
GO
SELECT Category =
CASE type
WHEN 'popular_comp' THEN 'Popular Computing'
WHEN 'mod_cook' THEN 'Modern Cooking'
WHEN 'business' THEN 'Business'
WHEN 'psychology' THEN 'Psychology'
WHEN 'trad_cook' THEN 'Traditional Cooking'
22
ELSE 'Not yet categorized'
END,
CAST(title AS varchar(25)) AS 'Shortened Title',
price AS Price
FROM titles
WHERE price IS NOT NULL
ORDER BY type, price
COMPUTE AVG(price) BY type
GO
B. Utilizar una instrucción SELECT con una función CASE sencilla y otra de búsqueda
USE pubs
GO
SELECT 'Price Category' =
CASE
WHEN price IS NULL THEN 'Not yet priced'
WHEN price < 10 THEN 'Very Reasonable Title'
WHEN price >= 10 and price < 20 THEN 'Coffee Table Title'
ELSE 'Expensive book!'
END,
CAST(title AS varchar(20)) AS 'Shortened Title'
FROM titles
ORDER BY price
GO
GOTO
Altera el flujo de ejecución y lo dirige a una etiqueta. Las instrucciones GOTO y las
etiquetas se pueden utilizar en cualquier punto de un procedimiento, lote o bloque de
instrucciones. Las instrucciones GOTO se pueden anidar.
Definición de la etiqueta:
label :
Alteración de la ejecución:
GOTO label
USE pubs
GO
DECLARE @tablename sysname
SET @tablename = N'authors'
tableLoop:
IF (@@FETCH_STATUS <> -2)
BEGIN
SELECT @tablename = RTRIM(UPPER(@tablename))
EXEC ("SELECT """ + @tablename + """ = COUNT(*) FROM "
+ @tablename )
PRINT " "
END
FETCH NEXT FROM tnames_cursor INTO @tablename
IF (@@FETCH_STATUS <> -1) GOTO tableLoop
GO
23
WAITFOR
Especifica un tiempo, intervalo de tiempo o suceso que desencadena la ejecución de un
bloque de instrucciones, procedimiento almacenado o transacción.
Sintaxis
WAITFOR { DELAY 'time' | TIME 'time' }
A. Utilizar WAITFOR TIME
Este ejemplo ejecuta el procedimiento almacenado update_all_stats a las 10:20 p.m.
BEGIN
WAITFOR TIME '22:20'
EXECUTE update_all_stats
END
B. Utilizar WAITFOR DELAY
Se crea un procedimiento almacenado de forma que espere una cantidad de tiempo
variable y, a continuación, se devuelve al usuario la información como el número de
horas, minutos y segundos que han transcurrido.
CREATE PROCEDURE time_delay @@DELAYLENGTH char(9)
AS
DECLARE @@RETURNINFO varchar(255)
BEGIN
WAITFOR DELAY @@DELAYLENGTH
SELECT @@RETURNINFO = 'A total time of ' +
SUBSTRING(@@DELAYLENGTH, 1, 3) +
' hours, ' +
SUBSTRING(@@DELAYLENGTH, 5, 2) +
' minutes, and ' +
SUBSTRING(@@DELAYLENGTH, 8, 2) +
' seconds, ' +
'has elapsed! Your time is up.'
PRINT @@RETURNINFO
END
GO
-- This next statement executes the time_delay procedure.
EXEC time_delay '000:00:10'
GO
GRANT
Crea una entrada en el sistema de seguridad que permite a un usuario de la base de datos
actual trabajar con datos de la base de datos actual o ejecutar instrucciones Transact-
SQL específicas.
Sintaxis
Permisos de la instrucción:
24
GRANT { ALL | statement [ ,...n ] }
TO security_account [ ,...n ]
Permisos del objeto:
GRANT
{ ALL [ PRIVILEGES ] | permission [ ,...n ] }
{
[ ( column [ ,...n ] ) ] ON { table | view }
| ON { table | view } [ ( column [ ,...n ] ) ]
| ON { stored_procedure | extended_procedure }
| ON { user_defined_function }
}
TO security_account [ ,...n ]
[ WITH GRANT OPTION ]
[ AS { group | role } ]
statement
Es la instrucción para la que se concede el permiso. La lista de instrucciones puede
contener:
• CREATE DATABASE
• CREATE DEFAULT
• CREATE FUNCTION
• CREATE PROCEDURE
• CREATE RULE
• CREATE TABLE
• CREATE VIEW
• BACKUP DATABASE
• BACKUP LOG
A. Conceder permisos sobre instrucciones
GRANT CREATE DATABASE, CREATE TABLE
TO Mary, John, [Corporate\BobJ]
B. Conceder permisos de objeto dentro de la jerarquía de permisos
USE pubs
GO
GRANT SELECT
ON authors
TO funcion_public
25
GO
GRANT INSERT, UPDATE, DELETE
ON authors
TO Mary, John, Tom
GO
C. Conceder permisos a una función de SQL Server
En este ejemplo se conceden permisos CREATE TABLE a todos los miembros de la
función Accounting.
GRANT CREATE TABLE TO Accounting
D. Conceder permisos con la opción AS
/* User Jean */
GRANT SELECT ON Plan_Data TO Accounting WITH GRANT OPTION
/* User Jill */
GRANT SELECT ON Plan_Data TO Jack AS Accounting
VER TAMBIEN
• DENY
• REVOKE
Transact-SQL tiene estos tipos de datos base
Bigint Binario Bit char cursor
datetime Decimal float image int
Money Nchar ntext nvarchar real
smalldatetime Smallint smallmoney text timestamp
Tinyint Varbinary Varchar uniqueidentifier
bigint Datos enteros (números enteros) comprendidos entre -2^63
(-9223372036854775808) y 2^63 -1 (9223372036854775807).
int Datos enteros (números enteros) comprendidos entre -2^31 (-2.147.483.648) y
2^31 - 1 (2.147.483.647).
smallint Datos enteros comprendidos entre 215 (-32.768) y 215 - 1 (32.767).
tinyint Datos enteros comprendidos 0 y 255.
bit
26
bit Datos enteros con valor 1 ó 0.
Decimal y numeric
decimal Datos de precisión y escala numérica fijas comprendidos entre -1038 +1 y 1038
– 1.
numeric Funcionalmente equivalente a decimal.
money y smallmoney
money Valores de moneda comprendidos entre -263 (-922.337.203.685.477,5808) y 263
- 1 (+922.337.203.685.477,5807), con una precisión de una diezmilésima de la unidad
monetaria.
smallmoney Valores de moneda comprendidos entre -214.748,3648 y +214.748,3647,
con una precisión de una diezmilésima de la unidad monetaria.
Numéricos con aproximación
Números con precisión de coma flotante comprendidos entre -1,79E + 308 y 1,79E
float
+ 308.
real Números con precisión de coma flotante comprendidos entre -3,40E + 38 y 3,40E
+ 38.
datetime y smalldatetime
Datos de fecha y hora comprendidos entre el 1 de enero de 1753 y el 31 de
datetime
diciembre de 9999, con una precisión de 3,33 milisegundos.
smalldatetimeDatos de fecha y hora comprendidos entre el 1 de enero de 1900 y el 6 de
junio de 2079, con una precisión de un minuto.
Cadenas de caracteres
char Datos de caracteres no Unicode de longitud fija con una longitud máxima de 8.000
caracteres.
varchar Datos no Unicode de longitud variable con un máximo de 8.000 caracteres.
textDatos no Unicode de longitud variable con una longitud máxima de 231 - 1
(2.147.483.647) caracteres.
Cadenas de caracteres Unicode
nchar Datos Unicode de longitud variable con una longitud máxima de 4.000 caracteres.
nvarchar Datos Unicode de longitud variable con una longitud máxima de 4.000
caracteres. sysname es el tipo de datos suministrado por el sistema y definido por el
27
usuario que es funcionalmente equivalente a nvarchar(128) y que se utiliza para hacer
referencia a nombres de objetos de bases de datos.
ntext Datos Unicode de longitud variable con una longitud máxima de 230 - 1
(1.073.741.823) caracteres.
Cadenas binarias
binary Datos binarios de longitud fija con una longitud máxima de 8.000 bytes.
varbinary Datos binarios de longitud variable con una longitud máxima de 8.000 bytes.
image Datos binarios de longitud variable con una longitud máxima de 231 - 1
(2.147.483.647) bytes.
Otros tipos de datos
cursor Una referencia a un cursor.
Un tipo de datos que almacena valores de varios tipos de datos aceptados en
sql_variant
SQL Server, excepto text, ntext, timestamp y sql_variant.
tableUn tipo de datos especial que se utiliza para almacenar un conjunto de resultados
para un proceso posterior.
timestamp Un número único para toda la base de datos que se actualiza cada vez que se
actualiza una fila.
uniqueidentifier Un identificador exclusivo global (GUID).
CAST y CONVERT
Convierten explícitamente una expresión de un tipo de datos en otro. CAST y
CONVERT proporcionan funciones similares.
Sintaxis
Uso de CAST:
CAST ( expression AS data_type )
Uso de CONVERT:
CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
DECLARE @myval decimal (5, 2)
SET @myval = 193.57
---
28
SELECT CAST(CAST(@myval AS varbinary(20)) AS decimal(10,5))
-- Or, using CONVERT
SELECT CONVERT(decimal(10,5), CONVERT(varbinary(20), @myval))
C. Utilizar CAST para concatenar
Este ejemplo concatena expresiones que no son de texto ni tipo binary mediante la
función de conversión de tipos de datos CAST.
USE pubs
GO
SELECT 'The price is ' + CAST(price AS varchar(12))
FROM titles
WHERE price > 10.00
GO
Nota Como los datos Unicode siempre utilizan un número par de bytes, preste atención
al convertir binary o varbinary en tipos de datos aceptados en Unicode, y viceversa.
Por ejemplo, esta conversión no devuelve el valor hexadecimal 41, sino 4100: SELECT
CAST(CAST(0x41 AS nvarchar) AS varbinary)
COALESCE
Devuelve la primera expresión no NULL entre sus argumentos.
Sintaxis
COALESCE ( expression [ ,...n ] )
SELECT CAST(COALESCE(hourly_wage * 40 * 52,
salary,
commission * num_sales) AS money) AS 'Total Salary'
FROM wages
GO
29