Anda di halaman 1dari 17

CREAR UNA TABLA CREATE TABLE

Para crear una nueva tabla se emplea la sentencia CREATE TABLE.


Se necesita el permiso CREATE TABLE en la base de datos y el permiso ALTER en el esquema en que se
crea la tabla.
Si las columnas de la instruccin CREATE TABLE se definen como un tipo definido por el usuario CLR, se
necesita la propiedad del tipo o el permiso REFERENCES.
Si las columnas de la instruccin CREATE TABLE tienen una coleccin de esquemas XML asociada, se
necesita la propiedad de la coleccin de esquemas XML o el permiso REFERENCES.

Empezaremos por una sintaxis reducida:

CREATE TABLE
[ nbBaseDatos.[nbEsquema].| nbEsquema.]nbTabla
( { <definicion_columna> | < definicion_colCalc > } [ ,...n ]
[ <restriccion_tabla> ] [ ,...n ] )
[ ; ]
nbBaseDatos Es el nombre de la base de datos en la que se crea la tabla. Debe ser el nombre de una base
de datos existente. Si no se especifica nbBaseDatos, se utiliza de manera predeterminada la base de datos
actual. El inicio de sesin de la conexin actual debe estar asociado a un Id. de usuario existente en la base
de datos especificada por nbBaseDatos, y ese Id. de usuario debe tener permisos CREATE TABLE.
nbEsquema Es el nombre del esquema al que pertenece la nueva tabla.
nbTabla Es el nombre de la nueva tabla. Los nombres de tablas deben seguir las reglas de los
identificadores. nbTabla puede contener un mximo de 128 caracteres excepto para los nombres de tablas
temporales locales (nombres precedidos por un nico signo de nmero (#)) que no pueden superar los 116
caracteres.
Despus de indicar el nombre de la tabla, entre parntesis definimos, separadas por una coma, cada una de
las columnas de la tabla y al final las restricciones a nivel de tabla si las hay.

Definir columnas fsicas

< definicion_columna > ::=
nbCol <tipo_dato>
[ COLLATE nbIntercalacion ]
[ NULL | NOT NULL ]
[
[ CONSTRAINT nbRestriccion ] DEFAULT exp_constante ]
| [ IDENTITY [( semilla, incremento )] [NOT FOR REPLICATION] ]
]
[ ROWGUIDCOL ]
[ <restriccion_columna> [ ...n ] ]
Como mnimo debemos indicar el nombre de la columna nbCol y su tipo de datos.

Los nombres de columnas deben seguir las reglas de los identificadores y deben ser nicos en la tabla. nbCol
puede contener de 1 a 128 caracteres. nbCol se puede omitir en las columnas creadas con un tipo de datos
timestamp, en tal caso, si no se especifica nbCol, el nombre de la columna timestamp ser de manera
predeterminada timestamp.
En cuanto al tipo de dato, esta es la sintaxis:

<tipo_dato> ::=
[nbEsquema_tipo. ] nbtipo
[ ( precision [ , escala ] | max |
[ { CONTENT | DOCUMENT } ] xml_schema_collection ) ]
[ nbEsquema_tipo. ] nbtipo
nbtipo Especifica el tipo de datos de la columna y nbEsquema_tipo el esquema al que pertenece el tipo. El
tipo de datos puede ser uno de los siguientes:

Un tipo de datos del sistema de SQL Server 2005 como los que ya conocemos.
Un tipo de alias basado en un tipo de datos del sistema de SQL Server. Los tipos de datos de alias se crean
con la instruccin CREATE TYPE para poder utilizarlos en una definicin de tabla. La asignacin NULL o
NOT NULL de un tipo de datos de alias puede anularse durante la instruccin CREATE TABLE. No obstante,
la especificacin de longitud no se puede cambiar; la longitud del tipo de datos de alias no se puede
especificar en una instruccin CREATE TABLE.
Un tipo definido por el usuario CLR. Los tipos definidos por el usuario CLR se crean con la instruccin
CREATE TYPE para poder utilizarlos en una definicin de tabla.
Si no se especifica el parmetro nbEsquema_tipo, el SQL Server Database Engine (Motor de base de datos
de SQL Server) hace referencia a nbtipo en el siguiente orden:

El tipo de datos del sistema de SQL Server.
El esquema predeterminado del usuario actual en la base de datos actual.
El esquema de dbo de la base de datos actual.
Precision es la precisin del tipo de datos especificado.

Escala es la escala del tipo de datos especificado.

Max slo se aplica a los tipos de datos varchar, nvarchar y varbinary para almacenar 231 bytes de datos de
caracteres y binarios, y 230 bytes de datos Unicode.

INSERCIN DE DATOS

Insertar en una tabla existente
INSERT INTO
La insercin de nuevos datos en una tabla, se realiza aadiendo filas enteras a la tabla, la sentencia SQL que
lo permite es la orden INSERT (o tambin denominada INSERT INTO.

SintaXIS
NSERT INTO <Tabla>(campo1,campo2) VALUES (valor1,valor2)
Ejemplo.
INSERT INTO oficinas (oficina, ciudad) VALUES (26, 'Elx')
INSERT INTO oficinas VALUES (27,'Mstoles','Centro',default ,null, default)
inserta datos en una tabla existente
insert into Empleado(cod_emppleado,nombre) select * from
empleadocopia

INSERT INTO(copiar tabla)
Copia una tabla existente creando una tabla con la misma estructura
Sintaxis
SELECT * INTO newtable FROM table1 WHERE <Criterio>

UPDATE
La sentencia UPDATE modifica los valores de una o ms columnas en las filas seleccionadas de una
nica tabla.
Para modificar los datos de una tabla es necesario disponer del privilegio UPDATE sobre dicha tabla.
UPDATE
[ TOP ( expression ) [ PERCENT ] ]
<destino>
SET { nbcolumna = { expresion | DEFAULT | NULL }
} [ ,...n ]
[ FROM{ <origen> }]
[ WHERE <condicion> ]
[;]
<destino> ::=
{
[nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTablaVista
}
Con <destino> indicamos la tabla que se va a actualizar.
La clusula SET especifica qu columnas van a modificarse y con qu valor, el valor se puede
expresar mediante una expresin, la palabra DEFAULT que equivale al valor predeterminado de la
columna, o el valor nulo NULL.
Las columnas de identidad no se pueden actualizar.
Expresin en cada asignacin debe generar un valor del tipo de dato apropiado para la columna
indicada. La expresin debe ser calculable basada en los valores de la fila actualmente en actualizacin.
Si para el clculo se utiliza una columna que tambin se modifica, el valor que se utilizar es el de antes
de la modificacin, lo mismo para la condicin del WHERE.
Expresin tambin puede ser una sub consulta siempre y cuanto devuelva un nico valor y cumpla las
condiciones anteriormente expuestas.
Ejemplo
UPDATE oficinas SET ventas = DEFAULT
UPDATE oficinas SET ventas = 0, objetivo = 0

Si no queremos actualizar todas las filas de la tabla sino unas cuantas, utilizaremos la clusula TOP, o
unas determinadas, utilizaremos la clusula WHERE.

TOP (expresin) [ PERCENT ]

Ejemplo

UPDATE TOP (10) PERCENT oficinas
SET ventas = 0;

Cuando el campo de la otra tabla se utiliza para la clusula SET, entonces debemos utilizar la
clusula FROM.
La clusula FROM permite definir un origen de datos basado en varias tablas, y ese origen ser el
utilizado para realizar la actualizacin.

Por ejemplo queremos actualizar el importe de los pedidos con el precio de la tabla productos.

UPDATE pedidos SET importe = cant * precio
FROM pedidos INNER JOIN productos
ON fab = idfab AND producto = idproducto;

EJERCICIO

Subir un 5% el precio de todos los productos del fabricante QSA. (3 filas afectadas)
Poner a cero las ventas y cuota del empleado Luis Garcia, si hay varios con el mismo nombre
actualizarlos todos. (1 filas afectadas)
Cambiar los empleados de la oficina 40 a la oficina 30

LA SENTENCIA DELETE
La sentencia DELETE elimina filas de una tabla. Si se borran todas las filas, o se borra la nica fila de
una tabla, la definicin de la tabla no desaparece, slo que la tabla se queda vaca.

DELETE
[ TOP ( expression ) [ PERCENT ] ] [ FROM ] <destino>
[ FROM <origen>]
[ WHERE < condicion>]
[; ]
<destino> ::=
{
[nbBaseDatos. nbEsquema. | nbEsquema.]nbTablaVista
}
Con esta instruccin podemos eliminar una o varias filas de una tabla.

La palabra FROM (la primera) es opcional (originalmente era obligatorio) y no aade funcionalidad
slo sirve para introducir el destino.
<destino> es el nombre de la tabla de donde queremos eliminar las filas, puede ser un nombre de
tabla o un nombre de vista (de momento basada en una slo tabla).
La segunda clusula FROM sirve para indicar un origen que permita una condicin de WHERE sobre
una tabla diferente de destino.
La instruccin bsica sera pues:

Ejemplo
DELETE FROM oficinas;
DELETE oficinas WHERE region = Este;
DELETE FROM empleados FROM empleados INNER JOIN oficinas ON empleados.oficina =
oficinas.oficina WHERE region = 'Este';


BORRADO MASIVO - TRUNCATE
Si queremos eliminar todas las filas de una tabla podemos utilizar tambin la instruccin TRUNCATE
TABLE.

TRUNCATE TABLE
[nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTabla [; ]
Esta sentencia quita todas las filas de una tabla sin registrar las eliminaciones individuales de filas.
Desde un punto de vista funcional, TRUNCATE TABLE es equivalente a la instruccin DELETE sin una
clusula WHERE; no obstante, TRUNCATE TABLE es ms rpida y utiliza menos recursos de registros
de transacciones y de sistema.

En comparacin con la instruccin DELETE, TRUNCATE TABLE ofrece las siguientes ventajas:

Se utiliza menos espacio del registro de transacciones.
La instruccin DELETE quita una a una las filas y graba una entrada en el registro de transacciones
por cada fila eliminada.
TRUNCATE TABLE quita los datos al cancelar la asignacin de las pginas de datos utilizadas para
almacenar los datos de la tabla y slo graba en el registro de transacciones las cancelaciones de
asignacin de pginas.
Por regla general, se utilizan menos bloqueos.
Si se ejecuta la instruccin DELETE con un bloqueo de fila, se bloquea cada fila de la tabla para su
eliminacin. TRUNCATE TABLE siempre bloquea la tabla y la pgina, pero no cada fila.
Las pginas cero se conservan en la tabla sin excepciones.
Despus de ejecutar una instruccin DELETE, la tabla puede seguir conteniendo pginas vacas. Por
ejemplo, no se puede cancelar la asignacin de las pginas vacas de un montn sin un bloqueo de
tabla exclusivo como mnimo. Si en la operacin de eliminacin no se utiliza un bloqueo de tabla, la tabla
contiene muchas pginas vacas. En el caso de los ndices, la operacin de eliminacin puede dejar
pginas vacas, aunque la asignacin de estas pginas se puede cancelar rpidamente mediante un
proceso de limpieza en segundo plano.
Si la tabla contiene una columna de identidad, el contador para dicha columna se restablece al valor
de inicializacin definido para ella. Si no se define ningn valor de inicializacin, se utiliza el valor
predeterminado 1. Para conservar el contador de identidad, se utiliza DELETE.

Pero no todo son ventajas, no se puede utilizar TRUNCATE TABLE en las siguientes tablas:

Tablas a las que se hace referencia mediante una restriccin FOREIGN KEY (las tablas que entran
como principales en una relacin).
Tablas que participan en una vista indizada.





Definir una base de datos CREATE DATABASE
Estructura interna

Como ya vimos en el primer tema, las bases de datos de SQL Server 2005 utilizan tres tipos de
archivos:

Archivos de datos principales (.mdf): Archivo requerido.
Archivos de datos secundarios (.ndf): Archivo opcional.
Archivos de registro (.ldf): Archivo requerido.
Y se deben situar en sistemas de archivos FAT o NTFS. Se recomienda NTFS.

CREATE DATABASE

CREATE DATABASE nbBasedeDatos
[ ON
[ PRIMARY ] [ <esp_fichero> [ ,...n ]
[ , <grupo> [ ,...n ] ]
[ LOG ON { < esp_fichero > [ ,...n ] } ]
]
[ COLLATE nbintercalacion]
[ WITH <external_access_option> ]
]
[;]
Como vemos la instruccin mnima es:

CREATE DATABASE nbBasedeDatos
nbBasedeDatos: Es el nombre de la nueva base de datos. Los nombres de base de datos deben ser
nicos en una instancia de SQL Server y cumplir las reglas de los identificadores. Puede tener 128
caracteres como mximo, excepto en un caso que veremos ms adelante.

Con la clusula ON especificamos los ficheros utilizados para almacenar los archivos de datos.

[ ON
[ PRIMARY ] [ <esp_fichero> [ ,...n ]
[ , <grupo> [ ,...n ] ]
<esp_fichero> ::=
(
NAME = nbfichero_logico ,
FILENAME = 'nbfichero_fisico'
[ , SIZE = tamao [ KB | MB | GB | TB ] ]
[ , MAXSIZE = { max_size [ KB | MB | GB | TB ] | UNLIMITED } ]
[ , FILEGROWTH = incremento_crecimiento [ KB | MB | GB | TB | % ] ]
)
nbfichero_logico es el nombre que se utiliza para hacer referencia al archivo en todas las
instrucciones Transact-SQL. El nombre de archivo lgico tiene que cumplir las reglas de los
identificadores de SQL Server y tiene que ser nico entre los nombres de archivos lgicos de la base de
datos.

nbfichero_fisico es el nombre del archivo fsico que incluye la ruta de acceso al directorio. Debe seguir
las reglas para nombres de archivos del sistema operativo.

Con la clusula SIZE indicamos el tamao original del archivo.
Los archivos de SQL Server 2005 pueden crecer automticamente a partir del tamao originalmente
especificado. Con FILEGROWTH se puede especificar un incremento de crecimiento y cada vez que se
llena el archivo, el tamao aumentar en la cantidad especificada.

Cada archivo tambin puede tener un tamao mximo especificado con MAXSIZE. Si no se especifica
un tamao mximo, el archivo puede crecer hasta utilizar todo el espacio disponible en el disco. Esta
caracterstica es especialmente til cuando SQL Server se utiliza como una base de datos incrustada en
una aplicacin para la que el usuario no dispone fcilmente de acceso a un administrador del sistema. El
usuario puede dejar que los archivos crezcan automticamente cuando sea necesario y evitar as las
tareas administrativas de supervisar la cantidad de espacio libre en la base de datos y asignar ms
espacio manualmente.



MODIFICAR , ADICONAR Y ELIMINAR CAMPOS
Aadir campos ALTER TABLE(ADD)
Para aadir una nueva columna o restriccin utilizamos la clusula ADD
Sintaxis
Alter table <nombre tabla> ADD <campo tipo y tamao>
ejemplo
ALTER TABLE Clientes ADD email varchar(50);


Modificar Campos ALTER TABLE(Column)
Para modificar una columna utilizamos la clusula COLUMN
Sintaxis
Alter table <nombre tabla> ALTER column <campo nuevo(tipo y tamao)>
Ejemplo
ALTER TABLE Clientes ALTER COLUMN direccion VARCHAR(40);


Eliminar campos ALTER TABLE(DROP COLUMN)
Elimina un campo de la tabla
Sintaxis
ALTER TABLE <nombre tabla> DROP COLUMN <nombre campo a eliminar>;
ejemplo
ALTER TABLE Clientes DROP COLUMN email;







CREAR UNA VISTA CREATE VIEW
Una vista es una tabla virtual que representa los datos de una o ms tablas de una forma alternativa.
Para crear una nueva vista se emplea la sentencia CREATE VIEW, debe ser la primera instruccin en un
lote de consultas.

Una vista slo se puede crear en la base de datos actual.

Para ejecutar CREATE VIEW, se necesita, como mnimo, el permiso CREATE VIEW en la base de
datos y el permiso ALTER en el esquema en el que se est creando la vista.

Sintaxis:

CREATE VIEW [nbEsquema.] nbVista
[ (columna [ ,...n ] ) ]
AS ( sentencia_select ) [ ; ]
nbEsquema Es el nombre del esquema al que pertenece la nueva tabla.

nbVista Es el nombre de la nueva vista. Los nombres de vistas deben seguir las reglas de los
identificadores.

sentencia_select Es la instruccin SELECT que define la vista. Dicha instruccin puede utilizar ms de
una tabla y otras vistas. Se necesitan permisos adecuados para seleccionar los objetos a los que se
hace referencia en la clusula SELECT de la vista que se ha creado.
Una vista no tiene por qu ser un simple subconjunto de filas y de columnas de una tabla
determinada. Es posible crear una vista que utilice ms de una tabla u otras vistas mediante una
clusula SELECT de cualquier complejidad.
Tambin se pueden utilizar funciones y varias instrucciones SELECT separadas por UNION o UNION
ALL.
Una vista puede tener como mximo 1.024 columnas.

Ejemplos:

CREATE VIEW oficinas_este
AS SELECT * FROM oficinas WHERE region = Este;

Crea una vista con las oficinas del este.

CREATE VIEW oficinas_empleados
AS
SELECT oficinas.oficina AS ofi, ciudad, dir, region, objetivo, oficinas.ventas AS ventas_ofi,
empleados.*
FROM oficinas INNER JOIN empleados
ON oficinas.oficina = empleados.oficina;
Crea una vista con los datos de todos los empleados y de sus oficinas.
En este caso hemos tenido que definir alias de campo porque en el origen de la sentencia SELECT
existe duplicidad de nombres.

CREATE VIEW oficinas_EO
AS
SELECT * FROM oficinas WHERE region = Este;
UNION ALL
SELECT * FROM oficinas WHERE region = Oeste;
Por defecto las columnas de la vista heredan los nombres de las columnas de la sentencia SELECT
asociada, pero podemos cambiar estos nombres indicando una lista de columnas despus del nombre
de la vista.

CREATE VIEW oficinas_este (Eoficina, Eciudad, Eregion, Edir, Eobjetivo,Eventas)
AS SELECT * FROM oficinas WHERE region = Este;
Utilizando una lista de columnas ya no tenemos que definir alias de columna en la sentencia SELECT
como pasaba en el caso de la vista oficinas_empleados.

Normalmente se utiliza la lista de columnas cuando una columna proviene de una expresin
aritmtica, una funcin o una constante; cuando dos o ms columnas puedan tener el mismo nombre,
normalmente debido a una combinacin; o cuando una columna de una vista recibe un nombre distinto
al de la columna de la que proviene.

En definitiva se puede optar por utilizar la lista de columnas o definir alias de campo en la sentencia
SELECT.

Cuando utilizamos una vista en una operacin de actualizacin (INSERT, UPDATE, DELETE), la vista
debe ser actualizable, para ello debe seguir las siguientes reglas:

Cualquier modificacin, incluida en las instrucciones UPDATE, INSERT y DELETE, debe hacer
referencia a las columnas de una nica tabla base.

Las columnas que se vayan a modificar en la vista deben hacer referencia directa a los datos
subyacentes de las columnas de la tabla, es decir que las columnas no se pueden obtener de otra
forma, como con una funcin de agregado: AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV,
STDEVP, VAR y VARP, o un clculo.

Las columnas formadas mediante los operadores de conjunto UNION, UNION ALL, CROSSJOIN,
EXCEPT e INTERSECT equivalen a un clculo y tampoco son actualizables.

Las columnas que se van a modificar no se ven afectadas por las clusulas GROUP BY, HAVING o
DISTINCT.

Las restricciones anteriores se aplican a cualquier subconsulta de la clusula FROM de la vista, al
igual que a la propia vista. Normalmente, el Database Engine (Motor de base de datos) debe poder
realizar un seguimiento sin ambigedades de las modificaciones de la definicin de la vista a una tabla
base.


ELIMINAR UNA VISTA DROP VIEW
Para eliminar una vista de una base de datos tenemos la sentencia DROP TABLE.
Sintaxis:

DROP VIEW [nbEsquema.]nbVista[ ,...n ] [ ; ]
Se eliminan las vista de la base de datos actual. Cuando eliminamos una vista eliminamos su
definicin y los permisos asociados a ella.

Se pueden quitar varias vistas en una misma sentencia DROP VIEW escribiendo los nombres de las
vistas a eliminar separados por comas.

Para ejecutar DROP VIEW, como mnimo, se necesita el permiso ALTER en SCHEMA o el permiso
CONTROL en OBJECT.

Ejemplo:

DROP VIEW oficinas_este, oficinas_EO;

Elimina las vistas oficinas_este y oficinas_EO.

Si eliminamos una tabla mediante DROP TABLE, se deben quitar explcitamente, con DROP VIEW,
las vistas basadas en esta tabla ya que no se quitarn por s solas.

DEFINICIN DE NDICE
Un ndice es una estructura de datos definida sobre una columna de tabla (o varias) y que permite
localizar de forma rpida las filas de la tabla en base a su contenido en la columna indexada adems de
permitir recuperar las filas de la tabla ordenadas por esa misma columna.
Funciona de forma parecida al ndice de un libro donde tenemos el ttulo del captulo y la pgina
donde empieza dicho captulo, en un ndice definido sobre una determinada columna tenemos el
contenido de la columna y la posicin de la fila que contiene dicho valor dentro de la tabla.

La definicin de los ndices de la base de datos es tarea del administrador de la base de datos, los
administradores ms experimentados pueden disear un buen conjunto de ndices, pero esta tarea es
muy compleja, consume mucho tiempo y est sujeta a errores, incluso con cargas de trabajo y bases de
datos con un grado de complejidad no excesivo.

TIPOS DE NDICES

NDICE SIMPLE Y COMPUESTO.

Un ndice simple est definido sobre una sla columna de la tabla mientras que un ndice compuesto
est formado por varias columnas de la misma tabla (tabla sobre la cual est definido el ndice.
Cuando se define un ndice sobre una columna, los registros que se recuperen utilizando el ndice
aparecern ordenados por el campo indexado. Si se define un ndice compuesto por las columnas col1 y
col2, las filas que se recuperen utilizando dicho ndice aparecern ordenadas por los valores de col1 y
todas las filas que tengan el mismo valor de col1 se ordenarn a su vez por los valores contenidos en
col2, funcin igual que la clusula ORDER BY vista en el tema de consultas simples.
Por ejemplo si definimos un ndice compuesto basado en las columnas (provincia, localidad), las filas
que se recuperen utilizando este ndice aparecern ordenadas por provincia y dentro de la misma
provincia por localidad.

ndice agrupado y no agrupado,

El trmino ndice agrupado no se debe confundir con ndice compuesto, el significado es totalmente
diferente.
Un ndice agrupado (CLUSTERED) es un ndice en el que el orden lgico de los valores de clave
determina el orden fsico de las filas correspondientes de la tabla. El nivel inferior, u hoja, de un ndice
agrupado contiene las filas de datos en s de la tabla. Una tabla o vista permite un solo ndice agrupado
al mismo tiempo.
Los ndices no agrupados existentes en las tablas se vuelven a generar al crear un ndice agrupado,
por lo que es conveniente crear el ndice agrupado antes de crear los ndices no agrupados.
Un ndice no agrupado especifica la ordenacin lgica de la tabla. Con un ndice no agrupado, el
orden fsico de las filas de datos es independiente del orden indizado.

ndice nico

ndice nico es aquel en el que no se permite que dos filas tengan el mismo valor en la columna de
clave del ndice. Es decir que no permite valores duplicados.


VENTAJAS E INCONVENIENTES DE LOS NDICES
VENTAJAS
La utilizacin de ndices puede mejorar el rendimiento de las consultas, ya que los datos necesarios
para satisfacer las necesidades de la consulta existen en el propio ndice. Es decir, slo se necesitan las
pginas de ndice y no las pginas de datos de la tabla o el ndice agrupado para recuperar los datos
solicitados; por tanto, se reduce la E/S global en el disco. Por ejemplo, una consulta de las columnas a y
b de una tabla que dispone de un ndice compuesto creado en las columnas a, b y c puede recuperar los
datos especificados del propio ndice.

Los ndices en vistas pueden mejorar de forma significativa el rendimiento si la vista contiene
agregaciones, combinaciones de tabla o una mezcla de agregaciones y combinaciones.

INCONVENIENTES

Las tablas utilizadas para almacenar los ndices ocupan espacio.
Los ndices consumen recursos ya que cada vez que se realiza una operacin de actualizacin,
insercin o borrado en la tabla indexada, se tienen que actualizar todas las tablas de ndice definidas
sobre ella (en la actualizacin slo es necesaria la actualizacin de los ndices definidos sobre las
columnas que se actualizan).
Por estos motivos no es buena idea definir ndices indiscriminadamente.

Consideraciones a tener en cuenta

A la hora de definir ndices se deben de tener en cuenta estas consideraciones:

Hay que evitar crear demasiados ndices en tablas que se actualizan con mucha frecuencia y procurar
definirlos con el menor nmero de columnas posible.
Es conveniente utilizar un nmero mayor de ndices para mejorar el rendimiento de consultas en
tablas con pocas necesidades de actualizacin, pero con grandes volmenes de datos. Un gran nmero
de ndices contribuye a mejorar el rendimiento de las consultas que no modifican datos, como las
instrucciones SELECT, ya que el optimizador de consultas dispone de ms ndices entre los que elegir
para determinar el mtodo de acceso ms rpido.
La indizacin de tablas pequeas puede no ser una solucin ptima, porque puede provocar que el
optimizador de consultas tarde ms tiempo en realizar la bsqueda de los datos a travs del ndice que
en realizar un simple recorrido de la tabla. De este modo, es posible que los ndices de tablas pequeas
no se utilicen nunca; sin embargo, sigue siendo necesario su mantenimiento a medida que cambian los
datos de la tabla.
Se recomienda utilizar una longitud corta en la clave de los ndices agrupados. Los ndices agrupados
tambin mejoran si se crean en columnas nicas o que no admitan valores NULL.
Un ndice nico en lugar de un ndice no nico con la misma combinacin de columnas proporciona
informacin adicional al optimizador de consultas y, por tanto, resulta ms til.
Hay que tener en cuenta el orden de las columnas si el ndice va a contener varias columnas. La
columna que se utiliza en la clusula WHERE en una condicin de bsqueda igual a (=), mayor que (>),
menor que (<) o BETWEEN, o que participa en una combinacin, debe situarse en primer lugar. Las
dems columnas deben ordenarse basndose en su nivel de diferenciacin, es decir, de ms distintas a
menos distintas.


DEFINIR UN NDICE CREATE INDEX
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX nombre_indice
ON <objeto> (columna [ ASC | DESC ] [ ,...n ] )
[ ; ]
<objeto> ::=
{
[nbBaseDatos.[nbEsquema].| nbEsquema.]nbTablaVista
}
Esta es la sintaxis simplicada de la instruccin CREATE INDEX que permite crear un ndice en una
tabla sobre una o varias columnas.

nbBaseDatos Es el nombre de la base de datos.
nbEsquema Es el nombre del esquema al que pertenece la tabla/vista.
nbTablaVista Es el nombre de la tabla o vista sobre la que se quiere crear el ndice.
nombre_indice Es el nombre del ndice que estamos creando.
Columna Es el nombre de la columna que forma parte del ndice. Se pueden definir ndices
compuestos escribiendo entre parntesis los nombres de las columnas separados por comas.
ASC los valores de la columna se ordenarn de forma ASCendente o DESCendente. Por defecto se
asume ASC.
UNIQUE permite definir un ndice nico (no admite valores repetidos).
CLUSTERED el ndice ser agrupado.
NONCLUSTERED (valor por defecto) el ndice ser no agrupado.

Ejemplos:

CREATE INDEX I_clientes_nombre ON Clientes (nombre)
Crea un ndice no agrupado sobre la columna nombre de la tabla Clientes en la base de datos actual,
las filas se ordenarn de forma ascendente.

CREATE INDEX I_clientes_ApeNom ON Clientes (apellidos, nombre)
Crea un ndice no agrupado sobre las columnas apellidos y nombre de la tabla Clientes en la base de
datos actual, las filas se ordenarn de forma ascendente por apellido y dentro del mismo apellido por
nombre.

CREATE INDEX I_clientes_EdadApe ON Clientes (edad DESC,apellidos)
Crea un ndice no agrupado sobre las columnas edad y apellidos de la tabla Clientes en la base de
datos actual, las filas se ordenarn de forma descendente por edad y ascendente por apellido.
Aparecern los clientes de mayor a menor edad y los clientes de la misma edad se ordenarn por
apellido (por orden alfabtico).

CREATE CLUSTERED INDEX I_clientes_cod ON Clientes (codigo)
Crea un ndice agrupado sobre la columna codigo de la tabla Clientes en la base de datos actual, las
filas se ordenarn y almacenarn por orden de cdigo.

CREATE UNIQUE INDEX U_clientes_col ON Clientes (col)
Crea un ndice nico sobre la columna col de la tabla Clientes en la base de datos actual, la columna
col no podr contener valores duplicados.


ELIMINAR UN NDICE DROP INDEX
Para eliminar un ndice tenemos la sentencia DROP INDEX.
La instruccin DROP INDEX no es aplicable a los ndices creados mediante la definicin de
restricciones PRIMARY KEY y UNIQUE. Para quitar la restriccin y el ndice correspondiente, se tiene
que ejecutar un ALTER TABLE con la clusula DROP CONSTRAINT.

Sintaxis simplificada:

DROP INDEX <indice> [ ,...n ] [ ; ]
<indice>::=
{
nbindice ON [nbBaseDatos.[nbEsquema].|nbEsquema.]nbTablaVista
}
nbBaseDatos Es el nombre de la base de datos.
nbEsquema Es el nombre del esquema al que pertenece la tabla/vista.
nbTablaVista Es el nombre de la tabla o vista de la que se quiere eliminar el ndice.
nbindice Es el nombre del ndice a eliminar.

Ejemplo:

DROP INDEX U_clientes_col ON Clientes;
Elimina el ndice U_clientes_col definido sobre la tabla Clientes.





PROGRAMACIN EN TRANSACT SQL (I)

Introduccin
Hasta ahora hemos estudiado sentencias SQL orientadas a realizar una determinada tarea sobre la
base de datos como definir tablas, obtener informacin de las tablas, actualizarlas; estas sentencias las
hemos ejecutado desde el editor de consultas del MSSMS de una en una o a lo sumo una a
continuacin de la otra dentro de la misma consulta formando un lote de instrucciones.
Las sentencias que ya conocemos son las que en principio forman parte de cualquier lenguaje SQL.
Ahora veremos que TRANSACT-SQL va ms all de un lenguaje SQL cualquiera ya que aunque no
permita:

Crear interfaces de usuario.
Crear aplicaciones ejecutables, sino elementos que en algn momento llegarn al servidor de datos y
sern ejecutados.
Incluye caractersticas propias de cualquier lenguaje de programacin, caractersticas que nos
permiten definir la lgica necesaria para el tratamiento de la informacin:

Tipos de datos.
Definicin de variables.
Estructuras de control de flujo.
Gestin de excepciones.
Funciones predefinidas.
Elementos para la visualizacin, que permiten mostrar mensajes definidos por el usuario gracias a la
clusula PRINT.
Estas caractersticas nos van a permitir crear bloques de cdigo orientados a realizar operaciones
ms complejas. Estos bloques no son programas sino procedimientos o funciones que podrn ser
llamados en cualquier momento.
En SQL Server 2005 podemos definir tres tipos de bloques de cdigo, los procedimientos
almacenados, los desencadenadores (o triggers) y funciones definidas por el usuario.
Nosotros estudiaremos los dos primeros.
Empezaremos por los procedimientos almacenados, veremos primero las sentencias para crear y
eliminar procedimientos almacenados, luego estudiaremos las instrucciones Transact-SQL ms propias
de un lenguaje de programacin nombradas en el tema de Introduccin al Transact-SQL como son por
ejemplo los bucles y estructuras condicionales. Estas instrucciones las utilizaremos dentro de
procedimientos almacenados pero veremos que tambin nos servirn para definir otros bloques de
cdigo.
Terminaremos esta unidad de programacin estudiando los disparadores o Triggers muy similares a
los procedimientos almacenados que difieren bsicamente en la forma en que entran en funcionamiento.

PROCEDIMIENTOS ALMACENADOS STORE PROCEDURE
Un procedimiento almacenado (STORE PROCEDURE) est formado por un conjunto de instrucciones
Transact-SQL que definen un determinado proceso, puede aceptar parmetros de entrada y devolver un
valor o conjunto de resultados. Este procedimiento se guarda en el servidor y puede ser ejecutado en
cualquier momento.

Los procedimientos almacenados se diferencian de las instrucciones SQL ordinarias y de los lotes de
instrucciones SQL en que estn precompilados. La primera vez que se ejecuta un procedimiento, el
procesador de consultas de SQL Server lo analiza y prepara un plan de ejecucin que se almacena en
una tabla del sistema. Posteriormente, el procedimiento se ejecuta segn el plan almacenado. Puesto
que ya se ha realizado la mayor parte del trabajo de procesamiento de consultas, los procedimientos
almacenados se ejecutan casi de forma instantnea por lo que el uso de procedimientos almacenados
mejora notablemente la potencia y eficacia del SQL.

SQL Server incorpora procedimientos almacenados del sistema, se encuentran en la base de datos
master y se reconocen por su nombre, todos tienen un nombre que empieza por sp_. Permiten
recuperar informacin de las tablas del sistema y pueden ejecutarse en cualquier base de datos del
servidor.

Tambin estn los procedimientos de usuario, los crea cualquier usuario que tenga los permisos
oportunos.

Se pueden crear tambin procedimiento temporales locales y globales. Un procedimiento temporal
local se crea por un usuario en una conexin determinada y slo se puede utilizar en esa sesin, un
procedimiento temporal global lo pueden utilizar todos los usuarios, cualquier conexin puede ejecutar
un procedimiento almacenado temporal global. ste existe hasta que se cierra la conexin que el
usuario utiliz para crearlo, y hasta que se completan todas las versiones del procedimiento que se
estuvieran ejecutando mediante otras conexiones. Una vez cerrada la conexin que se utiliz para crear
el procedimiento, ste ya no se puede volver a ejecutar, slo podrn finalizar las conexiones que hayan
empezado a ejecutar el procedimiento.

Tanto los procedimientos temporales como los no temporales se crean y ejecutan de la misma forma,
el nombre que le pongamos indicar de qu tipo es el procedimiento.

Los procedimientos almacenados se crean mediante la sentencia CREATE PROCEDURE y se
ejecutan con EXEC (o EXECUTE). Para ejecutarlo tambin se puede utilizar el nombre del
procedimiento almacenado slo, siempre que sea la primera palabra del lote. Para eliminar un
procedimiento almacenado utilizamos la sentencia DROP PROCEDURE.

ELIMINAR PROCEDIMIENTOS ALMACENADOS
Aunque no sabemos todava crear un procedimiento comentaremos aqu la instruccin para eliminar
procedimientos y as podremos utilizarla en los dems ejercicios.

DROP {PROC|PROCEDURE} [nombreEsquema.]nombreProcedimiento [,...n ].
Transact-SQL permite abreviar la palabra reservada PROCEDURE por PROC sin que ello afecte a la
funcionalidad de la instruccin.
Ejemplos:

DROP PROCEDURE Dice_Hola;
Elimina el procedimiento llamado Dice_Hola.

DROP PROC Dice_Hola;
Es equivalente, PROC y PROCEDURE indican lo mismo.

Para eliminar varios procedimientos de golpe, indicamos sus nombres separados por comas:

DROP PROCEDURE Dice_Hola, Ventas_anuales;
Elimina los procedimientos Dice_Hola y Ventas_anuales.

TRANSACT SQL (II)
CREAR Y EJECUTAR UN PROCEDIMIENTO
CREATE PROCEDURE

Para crear un procedimiento almacenado como hemos dicho se emplea la instruccin CREATE
PROCEDURE:

CREATE {PROC|PROCEDURE} [NombreEsquema.]NombreProcedimiento
[{@parametro tipo} [VARYING] [= valorPredet] [OUT|OUTPUT] ] [,...n]
AS { <bloque_instrucciones> [ ...n] }[;]
<bloque_instrucciones> ::=
{[BEGIN] instrucciones [END] }
Las instrucciones CREATE PROCEDURE no se pueden combinar con otras instrucciones SQL en el
mismo lote.
Despus del verbo CREATE PROCEDURE indicamos el nombre del procedimiento, opcionalmente
podemos incluir el nombre del esquema donde queremos que se cree el procedimiento, por defecto se
crear en dbo. Ya que Sqlserver utiliza el prefijo sp_ para nombrar los procedimientos del sistema se
recomienda no utilizar nombres que empiecen por sp_.
Como se puede deducir de la sintaxis (no podemos indicar un nombre de base de datos asociado al
nombre del procedimiento) slo se puede crear el procedimiento almacenado en la base de datos actual,
no se puede crear en otra base de datos.
Si queremos definir un procedimiento temporal local el nombre deber empezar por una almohadilla
(#) y si el procedimiento es temporal global el nombre debe de empezar por ##.
El nombre completo de un procedimiento almacenado o un procedimiento almacenado temporal
global, incluidas ##, no puede superar los 128 caracteres. El nombre completo de un procedimiento
almacenado temporal local, incluidas #, no puede superar los 116 caracteres.

Transact-SQL permite abreviar la palabra reservada PROCEDURE por PROC sin que ello afecte a la
funcionalidad de la instruccin.

CREATE PROC Calcula_comision AS
Es equivalente a

CREATE PROCEDURE calcula_comision AS
@parametro: representa el nombre de un parmetro. Se pueden declarar uno o ms parmetros
indicando para cada uno su nombre (debe de empezar por arroba) y su tipo de datos, y opcionalmente
un valor por defecto (=valorPredet) este valor ser el asumido si en la llamada el usuario no pasa ningn
valor para el parmetro. Un procedimiento almacenado puede tener un mximo de 2.100 parmetros.
Los parmetros son locales para el procedimiento; los mismos nombres de parmetro se pueden
utilizar en otros procedimientos. De manera predeterminada, los parmetros slo pueden ocupar el lugar
de expresiones constantes; no se pueden utilizar en lugar de nombres de tabla, nombres de columna o
nombres de otros objetos de base de datos.

VARYING Slo se aplica a los parmetros de tipo cursor por lo que se explicar cuando se expliquen
los cursores.
OUTPUT | OUT (son equivalentes)
Indica que se trata de un parmetro de salida. El valor de esta opcin puede devolverse a la
instruccin EXECUTE que realiza la llamada.
El parmetro variable OUTPUT debe definirse al crear el procedimiento y tambin se indicar en la
llamada junto a la variable que recoger el valor devuelto del parmetro. El nombre del parmetro y de la
variable no tienen por qu coincidir; sin embargo, el tipo de datos y la posicin de los parmetros deben
coincidir a menos que se indique el nombre del parmetro en la llamada de la forma @parametro=valor.

Procedimiento bsico

CREATE PROCEDURE Dice_Hola
AS
PRINT Hola;
GO - Indicamos GO para cerrar el lote que crea el procedimiento y empezar otro lote.
EXEC Dice_Hola; -- De esta forma llamamos al procedimiento (se ejecuta).
En este caso, como la llamada es la primera del lote (va detrs del GO) podamos haber obviado la
palabra EXEC y haber escrito directamente.


PROGRAMACIN EN TRANSACT SQL (III)

Con un parmetro de entrada (la palabra que queremos que escriba)

CREATE PROCEDURE Dice_Palabra @palabra CHAR(30)
AS
PRINT @palabra;
GO
EXEC Dice_Palabra Lo que quiera;
EXEC Dice_Palabra Otra cosa;
Aqu hemos hecho dos llamadas, una con el valor Lo que quiera y otra con el valor Otra cosa.

Con varios parmetros

Si queremos indicar varios parmetros los separamos por comas.

USE Biblio;
--DROP PROC VerUsuariosPoblacion; --La comentamos la primera vez
GO
CREATE PROCEDURE VerUsuariosPoblacion @pob CHAR(30),@pro CHAR(30)
AS
SELECT * FROM usuarios WHERE poblacion=@pob AND provincia = @pro;
GO
EXEC VerUsuariosPoblacion Madrid, Valencia
En la llamada podemos indicar los valores de los parmetros de varias formas,
indicando slo el valor de los parmetros (en este caso los tenemos que indicar en el mismo orden en
que estn definidos) como en el ejemplo anterior, o bien indicando el nombre del parmetro:

EXEC VerUsuariosPoblacion @pob=Madrid, @pro=Valencia
Indicar el nombre del parmetro en la llamada tambin nos permite indicar los valores en cualquier
orden, la siguiente llamada es equivalente a la anterior, hemos invertido el orden y se ejecuta igual:

EXEC VerUsuariosPoblacion @pro=Valencia, @pob=Madrid
En este procedimiento todos los parmetros son obligatorios, no deja llamar con un solo parmetro.

EXEC VerUsuariosPoblacion Madrid
Da error.

Con parmetros opcionales

Para definir un parmetro opcional tenemos que asignarle un valor por defecto en la definicin del
procedimiento.

DROP PROC VerUsuariosPoblacion2;
GO
CREATE PROCEDURE VerUsuariosPoblacion2 @pob CHAR(30),@pro CHAR(30)='Madrid'
AS
SELECT * FROM usuarios WHERE poblacion=@pob AND provincia = @pro;
GO
EXEC VerUsuariosPoblacion2 Madrid
En este caso, en la llamada slo hemos indicado un valor, para el primer parmetro, el paramtro
opcional no lo hemos indicado y se rellenar con el valor por defecto que indicamos en la definicin.
Lo podemos hacer as porque el parmetro opcional es el ltimo de la lista de parmetros. Cuando el
parmetro opcional no es el ltimo la llamada tiene que ser diferente, tenemos que nombrar los
parmetros en la llamada, al menos a partir del parmetro opcional.

DROP PROC VerUsuariosPoblacion3;
GO
CREATE PROCEDURE VerUsuariosPoblacion3 @a CHAR(2),@pob CHAR(30)='Madrid',@pro
CHAR(30)
AS
SELECT * FROM usuarios WHERE poblacion=@pob AND provincia = @pro;
GO
EXEC VerUsuariosPoblacion3 a,@pro='Madrid'
En este caso el parmetro opcional es el segundo de la lista de parmetros, cuando hacemos la
llamada no podemos hacer como en otros lenguajes de dejar un hueco:

EXEC VerUsuariosPoblacion3 a, ,'Madrid'
Da error.
Esta forma da error, debemos utilizar la palabra DEFAULT o indicar el nombre de todos los
parmetros que van detrs del opcional.

EXEC VerUsuariosPoblacion3 a,DEFAULT,'Madrid'

PROGRAMACIN EN TRANSACT SQL (IV)

Con parmetros de salida

Un procedimiento almacenado puede tambin devolver resultados, definiendo el paramtro como
OUTPUT o bien utilizando la instruccin RETURN que veremos en el siguiente apartado.
Para poder recoger el valor devuelto por el procedimiento, en la llamada se tiene que indicar una
variable donde guardar ese valor.
Ejemplo:
Definimos el procedimiento ultimo_contrato que nos devuelte la fecha en que se firm el ltimo
contrato en una determinada oficina. El procedimiento tendr pues dos parmetros, uno de entrada para
indicar el nmero de la oficina a considerar y uno de salida que devolver la fecha del contrato ms
reciente de entre los empleados de esa oficina.

USE Gestion
GO
CREATE PROC ultimo_contrato @ofi INT, @fecha DATETIME OUTPUT
AS
SELECT @fecha=(SELECT MAX(contrato) FROM empleados WHERE oficina=@ofi)
GO
Con @fecha DATETIME OUTPUT indicamos que el parmetro @fecha es de salida, el proceso que
realice la llamada podr recoger su valor despus de ejecutar el procedimiento.

En la llamada, para los parmetros de salida, en vez de indicar un valor de entrada se indica un
nombre de variable, variable que recoger el valor devuelto por el procedimiento sin olvidar la palabra
OUTPUT:

DECLARE @ultima AS DATETIME;
EXEC ultimo_contrato 12,@ultima OUTPUT;
PRINT @ultima;
RETURN

RETURN ordena salir incondicionalmente de una consulta o procedimiento, se puede utilizar en
cualquier punto para salir del procedimiento y las instrucciones que siguen a RETURN no se ejecutan.
Adems los procedimientos almacenados pueden devolver un valor entero mediante esta orden.

RETURN [expresion_entera]

Expresion_entera es el valor entero que se devuelve.
A menos que se especifique lo contrario, todos los procedimientos almacenados del sistema
devuelven el valor 0. Esto indica que son correctos y un valor distinto de cero indica que se ha producido
un error.
Cuando se utiliza con un procedimiento almacenado, RETURN no puede devolver un valor NULL. Si
un procedimiento intenta devolver un valor NULL (por ejemplo, al utilizar RETURN @var si @var es
NULL), se genera un mensaje de advertencia y se devuelve el valor 0.
Si queremos recoger el valor de estado devuelto por el procedimiento la llamada debe ser distinta, y
seguir el siguiente modelo:

EXECUTE @variable_donde_recogemos_estado = nombre_procedimiento @par, ...
Con el procedimiento del punto anterior no se puede utilizar esta forma de devolver un resultado
porque lo que se devuelve es una fecha, no es un valor entero, pero si quisiramos definir un
procedimiento que nos devuelva el nmero de empleados de una oficina podramos hacerlo de dos
formas:

De la forma normal con un parmetro de salida:

USE Gestion
GO
CREATE PROC trabajadores @ofi INT, @num INT OUTPUT
AS
SELECT @num=(SELECT COUNT(*) FROM empleados WHERE oficina=@ofi)
GO
Para obtener en la variable @var el resultado devuelto por el procedimiento la llamada sera:

DECLARE @var INT;
EXEC trabajadores 12, @var OUTPUT
Utilizando return en vez de un parmetro de salida:

CREATE PROC trabajadores2 @ofi INT
AS
RETURN (SELECT COUNT(*) FROM empleados WHERE oficina=@ofi)
GO
Para obtener en la variable @var el resultado devuelto por el procedimiento la llamada sera:

DECLARE @var INT;
EXEC @var= trabajadores2 12
PRINT @var
Nos visualiza el nmero de trabajadores de la oficina nmero 12.

Anda mungkin juga menyukai