File Group

35
FILE GROUP - SQL En SQL Server hay que distinguir entre Logins y Users. Los Logins se crean a nivel de servidor de base de datos. Pueden crearse como Logins de SQL Server, o pueden crearse a partir de una cuenta Windows, lo que en general es más seguro por utilizarse la autenticación integrada. En mi caso era precisamente eso lo que pretendía hacer, crearlos a partir de una determinada cuenta Windows. Esto es muy sencillo de hacer, basta un comando como el que se puede ver a continuación: USE [tu db] GO CREATE LOGIN [tu nombre de dominio para usuario] FROM WINDOWS GO Una vez creado el Login, ya podemos crear un usuario y asociarlo a él, vamos a la carpeta Users dentro de Security. El TSQL necesario sería algo así: CREATE USER [YourDomainYourDbUser] FROM LOGIN [YourDomainYourUser] GO Bien, con esto ya tendríamos nuestro usuario concreto de la base de datos creado, asociado a un Login a nivel del servidor. Roles y permisos El siguiente paso es crear el rol al que vamos a asociar el usuario que recién hemos creado. Este rol va a pertenecerle a dbo. No podemos darle sus permisos directamente en el script que se crea en la carpeta Database Roles de Security, esa parte tendremos que añadirla en un script de Post-deployment. Así que en el script de creación del rol simplemente tendríamos la siguiente sentencia TSQL: CREATE ROLE [YourNewRole] AUTHORIZATION [dbo] GO Quedarían dos pasos por ejecutar: darle los permisos al rol que necesite y asociarle el usuario que creamos al principio.

description

FILE GROUP en sql

Transcript of File Group

Page 1: File Group

FILE GROUP - SQL

En SQL Server hay que distinguir entre Logins y Users. Los Logins se crean a

nivel de servidor de base de datos. Pueden crearse como Logins de SQL Server,

o pueden crearse a partir de una cuenta Windows, lo que en general es más seguro

por utilizarse la autenticación integrada. En mi caso era precisamente eso lo que

pretendía hacer, crearlos a partir de una determinada cuenta Windows. Esto es

muy sencillo de hacer, basta un comando como el que se puede ver a continuación:

USE [tu db] GO CREATE LOGIN [tu nombre de dominio para usuario] FROM WINDOWS GO

Una vez creado el Login, ya podemos crear un usuario y asociarlo a él, vamos a la

carpeta Users dentro de Security. El TSQL necesario sería algo así:

CREATE USER [YourDomainYourDbUser] FROM LOGIN [YourDomainYourUser] GO

Bien, con esto ya tendríamos nuestro usuario concreto de la base de datos creado,

asociado a un Login a nivel del servidor.

Roles y permisos

El siguiente paso es crear el rol al que vamos a asociar el usuario que recién hemos creado.

Este rol va a pertenecerle a dbo. No podemos darle sus permisos directamente en el script

que se crea en la carpeta Database Roles de Security, esa parte tendremos que añadirla en

un script de Post-deployment. Así que en el script de creación del rol simplemente

tendríamos la siguiente sentencia TSQL:

CREATE ROLE [YourNewRole] AUTHORIZATION [dbo] GO

Quedarían dos pasos por ejecutar: darle los permisos al rol que necesite y asociarle el

usuario que creamos al principio.

Page 2: File Group

2 ADMINISTRACION DE BASE DE DATOS SQL

La primera parte se completa con una sentencia parecida a ésta. Sería necesario indicar

qué esquema de los existentes en la base de datos, va a poder el rol ejecutar sus SPs.

GRANT EXECUTE ON SCHEMA ::[YourSchema] TO [YourNewRole] GO

En cuanto a la segunda, bastaría algo como lo que sigue, apoyándonos en uno de los

procedimientos almacenados del sistema:

EXEC sp_addrolemember N'YourNewRole', N'YourDomainYourUser' GO

CREACION DE USUARIOS Y ROLES para BD Asistencia 2 USE [master] GO CREATE LOGIN [MARIO] WITH PASSWORD=N'12345', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON GO ALTER SERVER ROLE [bulkadmin] ADD MEMBER [MARIO] GO ALTER SERVER ROLE [dbcreator] ADD MEMBER [MARIO] GO ALTER SERVER ROLE [diskadmin] ADD MEMBER [MARIO] GO ALTER SERVER ROLE [processadmin] ADD MEMBER [MARIO] GO ALTER SERVER ROLE [securityadmin] ADD MEMBER [MARIO] GO ALTER SERVER ROLE [serveradmin] ADD MEMBER [MARIO] GO ALTER SERVER ROLE [setupadmin] ADD MEMBER [MARIO] GO ALTER SERVER ROLE [sysadmin] ADD MEMBER [MARIO] GO USE [Asistencia2] GO CREATE USER [MARIO] FOR LOGIN [MARIO] GO USE [master] GO CREATE USER [MARIO] FOR LOGIN [MARIO] GO USE [profesores] GO CREATE USER [MARIO] FOR LOGIN [MARIO] GO

Archivos y Configuraciones

Data Files: datos de la base de datos, está constituido por:

Primary Data Files (.mdf)

Secundary (.ndf)

Log files: datos y operaciones de las transacciones. Se constituye de un archivo .ldf

Page 3: File Group

3 ADMINISTRACION DE BASE DE DATOS SQL

Datos para configuración:

Nombre de archivo (filename)

Tamaño inicial (size): importante para evitar futuras fragmentaciones.

Tamaño máximo (maxsize)

Filegrowth (0 = not grow): incremento de crecimiento automático del archivo

Filegroups

Los filegroups (o grupos de archivos) son útiles para distribuir tablas con

alto volumen de información en diferentes discos para separar los índices de los datos.

Definen conjuntos de archivos para obtener paralelismo en distintas

unidades almacenamiento. Sólo se pueden asignar filegroups a los data files.

Por defecto viene el Filegroup Primary que se asignan automáticamente las tablas

del sistema y todas las tablas no asignadas a otro grupo.

FileGroup es un concepto muy importante sobre todo cuando vamos a crear una base de

datos ya que nos va ayudar mejorar el rendimiento de las consultas y la administracion de

la data en una BD.

Como concepto FileGroup es una unidad logica que almacena archivos fisicos que pueden

estar en distintas unidades de disco o en distintos discos fisicos, la idea del Filegroup es

la de aprovechar el procesamiento paralelo cuando el motor de BD requiere realizar

operaciones de I/O al disco duro.

Tener en cuenta que cuando creamos una BD el SQL crea un FileGroup por defecto ON

PRIMARY, en este FileGroup se almacenan todas las tablas del sistema(si es que no

sabias te lo cuento, cada vez que creamos una nueva Base de datos se hace ua copia de

todas las tablas de la BD Model) y todos los objetos que vayamos creando

La recomendación general es dejar a las tablas del sistema en el FileGroup por Defecto

(el que crea SQL) y crear un Filegroup para los objetos de usuario (las tablas, SP,

Trigger,etc creado por nosotros), adicionalmente también podrías crear un Filegroup para

almacenar data histórica que sabemos que no cambia en el tiempo.

Page 4: File Group

4 ADMINISTRACION DE BASE DE DATOS SQL

Por ultimo tener el cuenta que el archivo de transacciones no se asocia a ningún FileGroup

(Toda BD consta de un archivo mdf, opcionalmente archivos ndf y uno o mas archivos

ldf).

Este query asume que UD esta familiarizado con los conceptos de archivos mdf,ndf y ldf.

La idea es crear una BD LLamada Asistencia2 (preste atencion a los FileGroup creados

y las unidades de disco donde se guardan)

CREACION DE BASE DE DATOS (BD #1) Y FILEGROUP

CREATE DATABASE [Asistencia2] CONTAINMENT = NONE ON PRIMARY ( NAME = N'Asistencia2', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\Asistencia2.mdf' , SIZE = 5120KB , FILEGROWTH = 1024KB ), FILEGROUP [Secundary] ( NAME = N'Asistencia2_ndf', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\asistencia.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) LOG ON ( NAME = N'Asistencia2_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\Asistencia2_log.ldf' , SIZE = 1024KB , FILEGROWTH = 10%) GO ALTER DATABASE [Asistencia2] SET COMPATIBILITY_LEVEL = 110 GO ALTER DATABASE [Asistencia2] SET ANSI_NULL_DEFAULT OFF GO ALTER DATABASE [Asistencia2] SET ANSI_NULLS OFF GO ALTER DATABASE [Asistencia2] SET ANSI_PADDING OFF GO ALTER DATABASE [Asistencia2] SET ANSI_WARNINGS OFF GO ALTER DATABASE [Asistencia2] SET ARITHABORT OFF GO ALTER DATABASE [Asistencia2] SET AUTO_CLOSE OFF GO ALTER DATABASE [Asistencia2] SET AUTO_CREATE_STATISTICS ON GO ALTER DATABASE [Asistencia2] SET AUTO_SHRINK OFF GO ALTER DATABASE [Asistencia2] SET AUTO_UPDATE_STATISTICS ON GO ALTER DATABASE [Asistencia2] SET CURSOR_CLOSE_ON_COMMIT OFF GO ALTER DATABASE [Asistencia2] SET CURSOR_DEFAULT GLOBAL GO

Page 5: File Group

5 ADMINISTRACION DE BASE DE DATOS SQL

ALTER DATABASE [Asistencia2] SET CONCAT_NULL_YIELDS_NULL OFF GO ALTER DATABASE [Asistencia2] SET NUMERIC_ROUNDABORT OFF GO ALTER DATABASE [Asistencia2] SET QUOTED_IDENTIFIER OFF GO ALTER DATABASE [Asistencia2] SET RECURSIVE_TRIGGERS OFF GO ALTER DATABASE [Asistencia2] SET DISABLE_BROKER GO ALTER DATABASE [Asistencia2] SET AUTO_UPDATE_STATISTICS_ASYNC OFF GO ALTER DATABASE [Asistencia2] SET DATE_CORRELATION_OPTIMIZATION OFF GO ALTER DATABASE [Asistencia2] SET PARAMETERIZATION SIMPLE GO ALTER DATABASE [Asistencia2] SET READ_COMMITTED_SNAPSHOT OFF GO ALTER DATABASE [Asistencia2] SET READ_WRITE GO ALTER DATABASE [Asistencia2] SET RECOVERY SIMPLE GO ALTER DATABASE [Asistencia2] SET MULTI_USER GO ALTER DATABASE [Asistencia2] SET PAGE_VERIFY CHECKSUM GO ALTER DATABASE [Asistencia2] SET TARGET_RECOVERY_TIME = 0 SECONDS GO USE [Asistencia2] GO IF NOT EXISTS (SELECT name FROM sys.filegroups WHERE is_default=1 AND name = N'PRIMARY') ALTER DATABASE [Asistencia2] MODIFY FILEGROUP [PRIMARY] DEFAULT GO

INDICES CLUSTER Y NO CLUSTER

Los índices son objetos de la bases de datos, cuya función es optimizar el acceso a datos.

A medida que las tablas se van haciendo más grandes y se desea hacer consultar sobre

estas tablas, los índices son indispensables.

Internamente un índice normal es una estructura de árbol, que cuenta con una página

principal y luego esta con paginas hijas, que a su vez tiene más paginas hijas hasta llegar

a la pagina final del índice (leaf level).

La clave del índice está repartida en las páginas del índice, de modo tal que la búsqueda

se haga leyendo la menor cantidad posible de datos.

Estructura interna de un índice:

Page 6: File Group

6 ADMINISTRACION DE BASE DE DATOS SQL

Después de esta brevísima introducción, donde está la diferencia entre un índice clustered

y uno non-clustered? En la leaf level (la ultima pagina) del índice. En un índice non-

clustered, la clave por la que buscamos tiene un puntero a la página de datos donde se

encuentra el registro. Mientras que en índice clustered, la leaf level es la pagina de datos!.

Con lo cual, el SQL Server, se ahorra hacer un salto para leer los datos del registro

(Bookmark lookup). La diferencia es importante, ya que el uso de este tipo de índices al

evitar tener que hacer lecturas adicionales para traer el registro, son más performantes.

Búsqueda por clustered index:

Búsqueda por non-clustered index:

Pues solo puede haber 1 solo índice clustered por tabla. La razón es muy sencilla y lógica:

Los registros de la tabla físicamente son las paginas leaf-level del índice clustered. Los

datos de la tabla esta ordenados según el índice. Y obviamente una tabla no puede

simultáneamente estar físicamente ordenada de 2 maneras diferentes.

Por lo tanto, en tablas grandes y muy consultadas, tenemos que ser cuidadosos y analizar

a que campos vamos a seleccionar para ser llaves del índice clustered. Tenemos 1 solo

índice de este tipo por tabla, no hay que desperdiciarlo!

Este último punto es importante para saber en qué situaciones y para que campos se debe

utilizar un clustered index o un non-clustered.

Page 7: File Group

7 ADMINISTRACION DE BASE DE DATOS SQL

Guía general de uso de índices:

Campos autoincrementales (Identitys, newsequentialid, etc), deben

convenientemente ser del tipo clustered index. La razón es reducir el page split

(fragmentación) de la tabla.

Los clustered index son convenientes si se va seleccionar un rango de valores,

ordenar (ORDER BY) o agrupar (GROUP BY).

La PK es un buen candidato para un clustered index. Pero no siempre. Por

ejemplo, si tenemos una tabla de ventas, cuya PK es un identity en donde se

efectúan muchas consultar por rangos de fecha, el campo Fecha seria un mejor

candidato para el clustered que la PK.

Para búsquedas de valores específicos, conviene utilizar un non-clustered index.

Para índices compuestos, mejor utilizar non-clustered index (generalmente).

Usar SQL Server Management Studio

Para crear un índice clúster mediante el Explorador de objetos

1. En el Explorador de objetos, expanda la tabla en la que desea crear un índice

clúster.

2. Haga clic con el botón secundario en la carpeta Índices, apunte a Nuevo índice y

seleccione Índice clúster….

3. En el cuadro de diálogo Nuevo índice, en la página General, escriba el nombre

del nuevo índice en el cuadro Nombre de índice.

4. Debajo de Columnas de clave de índice, haga clic en Agregar.

5. En el cuadro de diálogo Seleccionar columnas detable_name, active la casilla de

la columna de tabla que se va a agregar al índice clúster.

6. Haga clic en Aceptar.

7. En el cuadro de diálogo Nuevo índice, haga clic en Aceptar.

Para crear un índice clúster mediante el Diseñador de tablas

1. En el Explorador de objetos, expanda la base de datos en la que desea crear una

tabla con un índice clúster.

2. Haga clic con el botón secundario en la carpeta Tablas y, a continuación, haga

clic en Nueva tabla….

3. Cree una tabla nueva como lo haría normalmente.

Page 8: File Group

8 ADMINISTRACION DE BASE DE DATOS SQL

4. Haga clic con el botón secundario en la nueva tabla creada anteriormente y, a

continuación, haga clic en Diseño.

5. En el menú Diseñador de tablas, haga clic en Índices o claves.

6. En el cuadro de diálogo Índices o claves, haga clic en Agregar.

7. Seleccione el nuevo índice en el cuadro de texto Índice o clave Primary/Unique

seleccionados.

8. En la cuadrícula, seleccione Crear como CLUSTERED y elija Sí en la lista

desplegable que aparece a la derecha de la propiedad.

9. Haga clic en Cerrar.

10. En el menú Archivo, haga clic en Guardartable_name.

Usar Transact-SQL

Para crear un índice clúster

1. En el Explorador de objetos, conéctese a una instancia del Motor de base de

datos.

2. En la barra Estándar, haga clic en Nueva consulta.

3. Copie y pegue el siguiente ejemplo en la ventana de consulta y haga clic

en Ejecutar.

(En este ejemplo estamos utilizando la Base de datos AdventureWorks2012)

USE AdventureWorks2012;

GO

-- Create a new table with three columns.

CREATE TABLE dbo.TestTable

(TestCol1 int NOT NULL,

TestCol2 nchar(10) NULL,

TestCol3 nvarchar(50) NULL);

GO

-- Create a clustered index called IX_TestTable_TestCol1

-- on the dbo.TestTable table using the TestCol1 column.

CREATE CLUSTERED INDEX IX_TestTable_TestCol1

ON dbo.TestTable (TestCol1);

GO

CRECION DE INDICES CLUSTER Y NO CLUSTER

BEGIN TRANSACTION SET QUOTED_IDENTIFIER ON

Page 9: File Group

9 ADMINISTRACION DE BASE DE DATOS SQL

SET ARITHABORT ON SET NUMERIC_ROUNDABORT OFF SET CONCAT_NULL_YIELDS_NULL ON SET ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON COMMIT BEGIN TRANSACTION GO CREATE TABLE dbo.Table_1 ( id_profesor numeric(18, 0) NOT NULL, nombre_profesor nchar(10) NOT NULL, materia_profesor nchar(10) NOT NULL ) ON [PRIMARY] GO ALTER TABLE dbo.Table_1 ADD CONSTRAINT PK_Table_1 PRIMARY KEY NONCLUSTERED ( id_profesor ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO CREATE NONCLUSTERED INDEX IX_Table_1 ON dbo.Table_1 ( id_profesor ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON Secundary GO ALTER TABLE dbo.Table_1 SET (LOCK_ESCALATION = TABLE) GO COMMIT

Mecanismos de Migración

Backup – Restore: es el más limpio y presenta el menor riesgo. Es sencillo ya que crea

un único archivo con todo.

BACKUP Y RESTORE

BACKUP DATABASE [master] TO DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\Backup\master.bak' WITH NOFORMAT, NOINIT, NAME = N'master-Completa Base de datos Copia de seguridad', SKIP, NOREWIND, NOUNLOAD, STATS = 10 GO USE [master] RESTORE DATABASE [master] FROM DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\Backup\master.bak' WITH FILE = 2, NOUNLOAD, STATS = 5 GO

BASE DE DATOS PERSONAL (BD #2)

USE [master] GO

Page 10: File Group

10 ADMINISTRACION DE BASE DE DATOS SQL

/****** Object: Database [PERSONAL] Script Date: 30/10/2014 11:57:38 ******/ CREATE DATABASE [PERSONAL] CONTAINMENT = NONE ON PRIMARY ( NAME = N'PERSONAL', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\PERSONAL.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ), FILEGROUP [SECUNDARY] ( NAME = N'PERSONAL_NDF', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\personal.ndf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'PERSONAL_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\PERSONAL_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%) GO ALTER DATABASE [PERSONAL] SET COMPATIBILITY_LEVEL = 110 GO IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) begin EXEC [PERSONAL].[dbo].[sp_fulltext_database] @action = 'enable' end GO ALTER DATABASE [PERSONAL] SET ANSI_NULL_DEFAULT OFF GO ALTER DATABASE [PERSONAL] SET ANSI_NULLS OFF GO ALTER DATABASE [PERSONAL] SET ANSI_PADDING OFF GO ALTER DATABASE [PERSONAL] SET ANSI_WARNINGS OFF GO ALTER DATABASE [PERSONAL] SET ARITHABORT OFF GO ALTER DATABASE [PERSONAL] SET AUTO_CLOSE OFF GO ALTER DATABASE [PERSONAL] SET AUTO_CREATE_STATISTICS ON GO ALTER DATABASE [PERSONAL] SET AUTO_SHRINK OFF GO ALTER DATABASE [PERSONAL] SET AUTO_UPDATE_STATISTICS ON GO ALTER DATABASE [PERSONAL] SET CURSOR_CLOSE_ON_COMMIT OFF GO ALTER DATABASE [PERSONAL] SET CURSOR_DEFAULT GLOBAL GO ALTER DATABASE [PERSONAL] SET CONCAT_NULL_YIELDS_NULL OFF GO ALTER DATABASE [PERSONAL] SET NUMERIC_ROUNDABORT OFF GO ALTER DATABASE [PERSONAL] SET QUOTED_IDENTIFIER OFF GO ALTER DATABASE [PERSONAL] SET RECURSIVE_TRIGGERS OFF GO ALTER DATABASE [PERSONAL] SET DISABLE_BROKER GO ALTER DATABASE [PERSONAL] SET AUTO_UPDATE_STATISTICS_ASYNC OFF GO ALTER DATABASE [PERSONAL] SET DATE_CORRELATION_OPTIMIZATION OFF GO ALTER DATABASE [PERSONAL] SET TRUSTWORTHY OFF GO ALTER DATABASE [PERSONAL] SET ALLOW_SNAPSHOT_ISOLATION OFF GO

Page 11: File Group

11 ADMINISTRACION DE BASE DE DATOS SQL

ALTER DATABASE [PERSONAL] SET PARAMETERIZATION SIMPLE GO ALTER DATABASE [PERSONAL] SET READ_COMMITTED_SNAPSHOT OFF GO ALTER DATABASE [PERSONAL] SET HONOR_BROKER_PRIORITY OFF GO ALTER DATABASE [PERSONAL] SET RECOVERY SIMPLE GO ALTER DATABASE [PERSONAL] SET MULTI_USER GO ALTER DATABASE [PERSONAL] SET PAGE_VERIFY CHECKSUM GO ALTER DATABASE [PERSONAL] SET DB_CHAINING OFF GO ALTER DATABASE [PERSONAL] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) GO ALTER DATABASE [PERSONAL] SET TARGET_RECOVERY_TIME = 0 SECONDS GO USE [PERSONAL] GO /****** Object: Table [dbo].[administracion] Script Date: 30/10/2014 11:57:38 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[administracion]( [id_admin] [numeric](18, 0) IDENTITY(1,1) NOT NULL, [area_admin] [nvarchar](50) NOT NULL, [nom_admin] [nvarchar](50) NOT NULL, [tiempo_laborable] [nvarchar](50) NOT NULL, [identificacion] [nvarchar](11) NOT NULL, CONSTRAINT [PK_administracion] PRIMARY KEY CLUSTERED ( [id_admin] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO /****** Object: Table [dbo].[profesores] Script Date: 30/10/2014 11:57:38 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[profesores]( [id_profesores] [numeric](18, 0) IDENTITY(1,1) NOT NULL, [identificacion] [nvarchar](11) NOT NULL, [nombre_profesor] [nvarchar](50) NOT NULL, [facultad] [nvarchar](50) NOT NULL, [materia] [nvarchar](50) NOT NULL, CONSTRAINT [PK_profesores] PRIMARY KEY CLUSTERED ( [id_profesores] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING ON GO

Page 12: File Group

12 ADMINISTRACION DE BASE DE DATOS SQL

/****** Object: Index [NonClusteredIndex-20141030-115525] Script Date: 30/10/2014 11:57:38 ******/ CREATE NONCLUSTERED INDEX [NonClusteredIndex-20141030-115525] ON [dbo].[administracion] ( [area_admin] ASC, [nom_admin] ASC, [tiempo_laborable] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO SET ANSI_PADDING ON GO /****** Object: Index [NonClusteredIndex-20141030-115618] Script Date: 30/10/2014 11:57:38 ******/ CREATE NONCLUSTERED INDEX [NonClusteredIndex-20141030-115618] ON [dbo].[profesores] ( [nombre_profesor] ASC, [facultad] ASC, [materia] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO USE [master] GO ALTER DATABASE [PERSONAL] SET READ_WRITE GO

BASE DE DATOS NOTAS (BD #3) USE [master] GO /****** Object: Database [NOTAS] Script Date: 30/10/2014 11:25:08 ******/ CREATE DATABASE [NOTAS] CONTAINMENT = NONE ON PRIMARY ( NAME = N'NOTAS', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\NOTAS.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ), FILEGROUP [SECUNDARY] ( NAME = N'NOTAS_NDF', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\notas.ndf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'NOTAS_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\NOTAS_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%) GO ALTER DATABASE [NOTAS] SET COMPATIBILITY_LEVEL = 110 GO IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) begin EXEC [NOTAS].[dbo].[sp_fulltext_database] @action = 'enable' end GO ALTER DATABASE [NOTAS] SET ANSI_NULL_DEFAULT OFF GO ALTER DATABASE [NOTAS] SET ANSI_NULLS OFF GO ALTER DATABASE [NOTAS] SET ANSI_PADDING OFF

Page 13: File Group

13 ADMINISTRACION DE BASE DE DATOS SQL

GO ALTER DATABASE [NOTAS] SET ANSI_WARNINGS OFF GO ALTER DATABASE [NOTAS] SET ARITHABORT OFF GO ALTER DATABASE [NOTAS] SET AUTO_CLOSE OFF GO ALTER DATABASE [NOTAS] SET AUTO_CREATE_STATISTICS ON GO ALTER DATABASE [NOTAS] SET AUTO_SHRINK OFF GO ALTER DATABASE [NOTAS] SET AUTO_UPDATE_STATISTICS ON GO ALTER DATABASE [NOTAS] SET CURSOR_CLOSE_ON_COMMIT OFF GO ALTER DATABASE [NOTAS] SET CURSOR_DEFAULT GLOBAL GO ALTER DATABASE [NOTAS] SET CONCAT_NULL_YIELDS_NULL OFF GO ALTER DATABASE [NOTAS] SET NUMERIC_ROUNDABORT OFF GO ALTER DATABASE [NOTAS] SET QUOTED_IDENTIFIER OFF GO ALTER DATABASE [NOTAS] SET RECURSIVE_TRIGGERS OFF GO ALTER DATABASE [NOTAS] SET DISABLE_BROKER GO ALTER DATABASE [NOTAS] SET AUTO_UPDATE_STATISTICS_ASYNC OFF GO ALTER DATABASE [NOTAS] SET DATE_CORRELATION_OPTIMIZATION OFF GO ALTER DATABASE [NOTAS] SET TRUSTWORTHY OFF GO ALTER DATABASE [NOTAS] SET ALLOW_SNAPSHOT_ISOLATION OFF GO ALTER DATABASE [NOTAS] SET PARAMETERIZATION SIMPLE GO ALTER DATABASE [NOTAS] SET READ_COMMITTED_SNAPSHOT OFF GO ALTER DATABASE [NOTAS] SET HONOR_BROKER_PRIORITY OFF GO ALTER DATABASE [NOTAS] SET RECOVERY SIMPLE GO ALTER DATABASE [NOTAS] SET MULTI_USER GO ALTER DATABASE [NOTAS] SET PAGE_VERIFY CHECKSUM GO ALTER DATABASE [NOTAS] SET DB_CHAINING OFF GO ALTER DATABASE [NOTAS] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) GO ALTER DATABASE [NOTAS] SET TARGET_RECOVERY_TIME = 0 SECONDS GO USE [NOTAS] GO

AGREGANDO USUARIO /****** Object: User [jenni] Script Date: 30/10/2014 11:25:09 ******/ CREATE USER [jenni] FOR LOGIN [jenni] WITH DEFAULT_SCHEMA=[dbo] GO ALTER ROLE [db_accessadmin] ADD MEMBER [jenni] GO ALTER ROLE [db_securityadmin] ADD MEMBER [jenni]

Page 14: File Group

14 ADMINISTRACION DE BASE DE DATOS SQL

GO /****** Object: Table [dbo].[anual] Script Date: 30/10/2014 11:25:09 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[anual]( [id_notas] [numeric](18, 0) IDENTITY(1,1) NOT NULL, [id_estudiante] [nchar](11) NOT NULL, [materia] [nvarchar](50) NOT NULL, [año] [nvarchar](50) NOT NULL, [condicion] [nvarchar](50) NULL, [1 parcial] [numeric](18, 0) NOT NULL, [2 parcial] [numeric](18, 0) NOT NULL, [3 parcial] [numeric](18, 0) NOT NULL, [total] [numeric](18, 0) NOT NULL, [recuperacion] [nchar](10) NULL, [promedio] [numeric](18, 0) NOT NULL, CONSTRAINT [PK_anual] PRIMARY KEY CLUSTERED ( [id_notas] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO /****** Object: Table [dbo].[semestre] Script Date: 30/10/2014 11:25:09 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[semestre]( [id_notas] [numeric](18, 0) IDENTITY(1,1) NOT NULL, [id_estudiante] [nchar](11) NOT NULL, [materia] [nchar](10) NOT NULL, [nivel] [nchar](10) NOT NULL, [1 parcial] [numeric](18, 0) NOT NULL, [2 parcial] [numeric](18, 0) NOT NULL, [recuperacion] [numeric](18, 0) NULL, [total] [numeric](18, 0) NOT NULL, [promedio] [numeric](18, 0) NOT NULL, CONSTRAINT [PK_semestre] PRIMARY KEY CLUSTERED ( [id_notas] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING ON GO /****** Object: Index [NonClusteredIndex-20141030-105300] Script Date: 30/10/2014 11:25:09 ******/ CREATE NONCLUSTERED INDEX [NonClusteredIndex-20141030-105300] ON [dbo].[anual] ( [materia] ASC, [año] ASC, [condicion] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

Page 15: File Group

15 ADMINISTRACION DE BASE DE DATOS SQL

GO SET ANSI_PADDING ON GO /****** Object: Index [NonClusteredIndex-20141030-104505] Script Date: 30/10/2014 11:25:09 ******/ CREATE NONCLUSTERED INDEX [NonClusteredIndex-20141030-104505] ON [dbo].[semestre] ( [materia] ASC, [nivel] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO USE [master] GO ALTER DATABASE [NOTAS] SET READ_WRITE GO

USUARIOS PARA BASES DE DATOS

USE [master] GO CREATE LOGIN [lopez] WITH PASSWORD=N'lopez', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF GO ALTER SERVER ROLE [bulkadmin] ADD MEMBER [lopez] GO ALTER SERVER ROLE [serveradmin] ADD MEMBER [lopez] GO ALTER SERVER ROLE [sysadmin] ADD MEMBER [lopez] GO USE [Asistencia2] GO CREATE USER [lopez] FOR LOGIN [lopez] GO USE [Asistencia2] GO ALTER ROLE [db_accessadmin] ADD MEMBER [lopez] GO USE [Asistencia2] GO ALTER ROLE [db_ddladmin] ADD MEMBER [lopez] GO USE [Asistencia2] GO ALTER ROLE [db_securityadmin] ADD MEMBER [lopez] GO USE [NOTAS] GO CREATE USER [lopez] FOR LOGIN [lopez] GO USE [NOTAS] GO ALTER ROLE [db_accessadmin] ADD MEMBER [lopez] GO USE [NOTAS] GO ALTER ROLE [db_ddladmin] ADD MEMBER [lopez] GO USE [NOTAS] GO ALTER ROLE [db_securityadmin] ADD MEMBER [lopez]

Page 16: File Group

16 ADMINISTRACION DE BASE DE DATOS SQL

GO

Procedimientos almacenados Un procedimiento almacenado (stored procedure en inglés) es un programa (o

procedimiento) almacenado físicamente en una base de datos. Su implementación varía

de un gestor de bases de datos a otro. La ventaja de un procedimiento almacenado es que

al ser ejecutado, en respuesta a una petición de usuario, es ejecutado directamente en el

motor de bases de datos, el cual usualmente corre en un servidor separado. Como tal,

posee acceso directo a los datos que necesita manipular y sólo necesita enviar sus

resultados de regreso al usuario, deshaciéndose de la sobrecarga resultante de comunicar

grandes cantidades de datos salientes y entrantes.

Usos típicos para procedimientos almacenados incluyen la validación de datos siendo

integrados a la estructura de base de datos (los procedimientos almacenados utilizados

para este propósito a menudo son llamados disparadores; triggers en inglés), o encapsular

un proceso grande y complejo. El último ejemplo generalmente ejecutará más rápido

como un procedimiento almacenado que de haber sido implementado como, por ejemplo,

un programa corriendo en el sistema cliente y comunicándose con la base de datos

mediante el envío de consultas SQL y recibiendo sus resultados.

Los procedimientos pueden ser ventajosos: Cuando una base de datos es manipulada

desde muchos programas externos. Al incluir la lógica de la aplicación en la base de datos

utilizando procedimientos almacenados, la necesidad de embeber la misma lógica en

todos los programas que acceden a los datos es reducida. Esto puede simplificar la

creación y, particularmente, el mantenimiento de los programas involucrados.

Para crear un procedimiento en el Explorador de objetos

1. En el Explorador de objetos, conéctese a una instancia de Motor de base de datos

y expándala.

2. Expanda Bases de datos, la base de datos AdventureWorks2012 y, por

último, Programación.

3. Haga clic con el botón secundario en Procedimientos almacenados y, a

continuación, haga clic en Nuevo procedimiento almacenado.

Page 17: File Group

17 ADMINISTRACION DE BASE DE DATOS SQL

4. En el menú Consulta, haga clic en Especificar valores para parámetros de plantilla.

5. En el cuadro de diálogo Especificar valores para parámetros de plantilla,

especifique los siguientes valores para los parámetros mostrados.

6. Haga clic en aceptar

7. En el Editor de consultas, reemplace la instrucción SELECT por la siguiente

instrucción:

8. Para probar la sintaxis, en el menú Consulta, haga clic en Analizar. Si se

devuelve un mensaje de error, compare las instrucciones con la información

anterior y corrija lo que sea necesario.

9. Para crear el procedimiento, en el menú Consulta, haga clic en Ejecutar. El

procedimiento se crea como un objeto de la base de datos.

10. Para ver el procedimiento que aparece en el Explorador de objetos, haga clic con

el botón secundario en Procedimientos almacenados y seleccione Actualizar.

11. Para ejecutar el procedimiento, en el Explorador de objetos, haga clic con el botón

secundario en el nombre del procedimiento

almacenadoHumanResources.uspGetEmployeesTest y seleccione Ejecutar

procedimiento almacenado.

Page 18: File Group

18 ADMINISTRACION DE BASE DE DATOS SQL

12. En la ventana Ejecutar procedimiento, escriba Margheim como valor del

parámetro @LastName y Diane como valor del parámetro @FirstName.

Crear un procedimiento en el editor de consultas

Para crear un procedimiento en el Editor de consultas

En el Explorador de objetos, conéctese a una instancia de Motor de base de datos.

En el menú Archivo, haga clic en Nueva consulta.

Copie y pegue el ejemplo siguiente en la ventana de consulta y haga clic en

Ejecutar. En este ejemplo se crea el mismo procedimiento almacenado que antes

con otro nombre diferente.

Para ejecutar el procedimiento, copie y pegue el ejemplo siguiente en una nueva ventana

de consulta y haga clic en Ejecutar. Observe que se muestran diferentes métodos para

especificar los valores de parámetro.

Procedimientos Almacenados en SQL

Calcular Costos Promedios de Productos de Ingresos

Page 19: File Group

19 ADMINISTRACION DE BASE DE DATOS SQL

Calcular Costos Promedios de Productos de Ventas

Calcular Precios de Ventas al Público 15% más del precio de compra

Page 20: File Group

20 ADMINISTRACION DE BASE DE DATOS SQL

Calcular Total Ingresos (Compras) Periodo comprendido desde Diciembre 2013 a

Abril 2014

Calcular Total Egresos (Ventas) Periodo comprendido desde Diciembre 2013 a Abril

2014

Page 21: File Group

21 ADMINISTRACION DE BASE DE DATOS SQL

Calcular Utilidad de Ventas Mensual de las Ventas de Abril

Actualizar el stock de productos. (Compras)

Page 22: File Group

22 ADMINISTRACION DE BASE DE DATOS SQL

Actualizar el stock de productos. (Ventas)

Page 23: File Group

23 ADMINISTRACION DE BASE DE DATOS SQL

Procedimientos Almacenados en SQL

Calcular Costos Promedios de Productos de Ingresos

Calcular Costos Promedios de Productos de Ventas

Calcular Precios de Ventas al Público 15% más del precio de compra

Page 24: File Group

24 ADMINISTRACION DE BASE DE DATOS SQL

Calcular Total Ingresos (Compras) Periodo comprendido desde Diciembre 2013 a

Abril 2014

Calcular Total Egresos (Ventas) Periodo comprendido desde Diciembre 2013 a Abril

2014

Page 25: File Group

25 ADMINISTRACION DE BASE DE DATOS SQL

Calcular Utilidad de Ventas Mensual de las Ventas de Abri

Page 26: File Group

26 ADMINISTRACION DE BASE DE DATOS SQL

Actualizar el stock de productos. (Compras)

Actualizar el stock de productos. (Ventas)

Page 27: File Group

27 ADMINISTRACION DE BASE DE DATOS SQL

Tablas temporales En el mundo de las bases de datos es muy común la utilización de tablas temporales. A

pesar de que todo el mundo sabe que este tipo de estructuras ralentizan el funcionamiento

de nuestras consultas, los programadores no pueden evitar recurrir a ellas porque muchas

veces facilitan la resolución de problemas. Almacenar datos para usarlos posteriormente,

guardar resultados parciales, analizar grandes cantidades de filas. Hay muchos casos en

los que podemos necesitar estas tablas temporales, ¡Pero hay que utilizarlas

correctamente.

Como crear una tabla temporal

CREATE TABLE #nombreTabla

Creamos una tabla temporal de la misma forma que una tabla común, con la sentencia

CREATE TABLE la única diferencia es el símbolo # antes del nombre de la tabla:

?

1 CREATE TABLE #tablaTemporal( productDescriptionID INT , description NVARCHAR(400) )

Estas tablas son creadas en la base de datos tempdb, en la carpeta llamada Temporary Tables:

Page 28: File Group

28 ADMINISTRACION DE BASE DE DATOS SQL

Cabe aclarar que si cerramos la conexión actual, esta tabla se eliminará. Por ello, este tipo

de tablas temporales es conocida como Tablas Temporales Locales.

CREATE TABLE ##nombreTabla

?

1 CREATE TABLE ##tablaTemporal( productDescriptionID INT , description NVARCHAR(400) )

Al igual que las Tablas Temporales Locales, las Tablas Temporales Globales son creadas en la base de

datos tempdb, en la carpeta Temporary Tables.

Este tipo de tablas temporales se eliminan cuando todas las conexiones ligadas a ella se desconectan.

CTE ( Common Table Expressions )

A diferencia de las anteriores, este tipo de tabla temporal solo puede ser utilizado durante la ejecución del

bloque de código y solo en una ocasión después de haber declarado el CTE.

?

1

2

3

4

5

6

7

USE AdventureWorks2012

;WITH nombreCTE ( idProducto , Descripcion )

AS

(

SELECT ProductDescriptionID, Description FROM Production.ProductDescription

)

SELECT * FROM nombreCTE;

Page 29: File Group

29 ADMINISTRACION DE BASE DE DATOS SQL

O también de la siguiente forma, solo que así nos tendremos que adaptar a los nombres de columna que

nuestro query arroje:

?

1

2

3

4

5

6

7

USE AdventureWorks2012

;WITH nombreCTE

AS

(

SELECT ProductDescriptionID, Description FROM Production.ProductDescription

)

SELECT * FROM nombreCTE;

Page 30: File Group

30 ADMINISTRACION DE BASE DE DATOS SQL

Declarando varios CTE:

?

1

2

3

4

5

6

7

8

9

10

11

USE AdventureWorks2012

;WITH nombreCTE

AS

(

SELECT ProductDescriptionID, Description FROM Production.ProductDescription

)

, nombreCTE2

AS

(

select * from HumanResources.Department

)

SELECT * FROM nombreCTE, nombreCTE2;

Page 31: File Group

31 ADMINISTRACION DE BASE DE DATOS SQL

12

VARIABLES TIPO TABLA

Desde hace algunas versiones de SQL SERVER, se agregó la variable tipo TABLA, al

igual que los CTE, solo están vigente durante la ejecución del bloque de código.

?

1

2

3

4

5

6

DECLARE @nombreTabla TABLE( idDescripcion INT, Descripcion NVARCHAR(400) )

INSERT INTO @nombreTabla

SELECT ProductDescriptionID, Description FROM Production.ProductDescription

SELECT * FROM @nombreTabla

En resumen, existen tablas temporales locales y globales que pueden ser creadas a partir

de CREATE TABLE #nombreTabla y CREATE TABLE ##nombreTabla y pueden ser

eliminadas con DROP TABLE y solo están vigentes durante la conexión o conexiones

que fueron abiertas.

Page 32: File Group

32 ADMINISTRACION DE BASE DE DATOS SQL

Cursores

Los cursores son una herramienta de SQL que nos permite recorrer el resultado de una

consulta SQL y realizar operaciones en cada paso de ésta. Es así como nos ayuda a realizar

operaciones que de otro modo serían más complejas o irrealizables. A continuación

coloco el código de un cursor muy simple para el Analizador de Consultas de SQl Server.

/* Este cursor deja las contraseñas iguales al nombre de usuario.

La tabla Cliente tiene estos tres campos: CliCod, CliUser, CliPass */

-- declaramos las variables

declare @cod as int

declare @user as varchar(50)

declare @pass as varchar(50)

-- declaramos un cursor llamado "CURSOR".

El select debe contener sólo los campos a utilizar.

declare CURSOR cursor for

select CliCod, CliUser, CliPass from Cliente

open CURSOR

-- Avanzamos un registro y cargamos en las variables los valores encontrados en el primer registro

fetch next from CURSOR

into @cod, @user, @pass

while @@fetch_status = 0

begin

update Cliente set CliPass= @user where CliCod=@cod

-- Avanzamos otro registro

fetch next from CURSOR

into @cod, @user, @pass

end

-- cerramos el cursor

close CURSOR

deallocate CURSOR

Rollback

En tecnologías de base de datos, un rollback es una operación que devuelve a la base de

datos a algún estado previo. Los Rollbacks son importantes para la integridad de la base

de datos, a causa de que significan que la base de datos puede ser restaurada a una copia

limpia incluso después de que se han realizado operaciones erróneas. Son cruciales para

la recuperación de crashes de un servidor de base de datos; realizando rollback(devuelto)

cualquier transacción que estuviera activa en el tiempo del crash, la base de datos es

restaurada a un estado consistente.

Page 33: File Group

33 ADMINISTRACION DE BASE DE DATOS SQL

En SQL, ROLLBACK es un comando que causa que todos los cambios de datos desde la

última sentencia BEGIN WORK, o START TRANSACTION sean descartados por el

sistema de gestión de base de datos relacional (RDBMS), para que el estado de los datos

sea "rolled back"(devuelto) a la forma en que estaba antes de que aquellos cambios

tuvieran lugar.

Una sentencia ROLLBACK también publicará cualquier savepoint existente que pudiera

estar en uso.

En muchos dialectos de SQL, ROLLBACKs son específicos de la conexión. Esto

significa que si se hicieron dos conexiones a la misma base de datos, un ROLLBACK

hecho sobre una conexión no afectará a cualesquiera otras conexiones. Esto es vital para

el buen funcionamiento de la Concurrencia.

La funcionalidad de rollback está normalmente implementada con un Log de

transacciones, pero puede también estar implementada mediante control de concurrencia

multiversión.

Cuando se ejecuta un ROLLBACK de la unidad de trabajo se liberan todos los bloqueos

mantenidos. Se cierran todos los cursores abiertos. Se liberan todos los localizadores de

LOB.

La ejecución de la sentencia ROLLBACK no afecta a las sentencias SET que cambian

los valores del registro especial ni a la sentencia RELEASE.

Si el programa finaliza de forma anómala, la unidad de trabajo se retrotrae implícitamente.

El almacenamiento en antememoria de sentencias se ve afectado por la operación de

retrotracción.

El efecto que una sentencia ROLLBACK TO SAVEPOINT tiene sobre los cursores

depende de las sentencias contenidas en el punto de salvaguarda.

Si el punto de salvaguarda contiene un DDL del cual depende un cursor, el cursor se

marca como no válido. Los intentos para utilizar ese cursor dan lugar a un error

(SQLSTATE 57007).

En otro caso:

Page 34: File Group

34 ADMINISTRACION DE BASE DE DATOS SQL

Si se hace referencia al cursor en el punto de salvaguarda, el cursor permanece abierto y

se coloca delante de la primera fila lógica de la tabla de resultados. (FETCH debe

realizarse antes de emitirse una sentencia UPDATE o DELETE con posición.)

En otro caso, el cursor no queda afectado por ROLLBACK TO SAVEPOINT (permanece

abierto y posicionado).

Las sentencias de SQL dinámico preparadas en un paquete vinculado con la opción

KEEPDYNAMIC YES se conservan en el contexto SQL después de una sentencia

ROLLBACK. La sentencia se puede volver a preparar de forma implícita, como resultado

de operaciones DDL que se retrotraen dentro de la unidad de trabajo.

Las sentencias de SQL dinámico preparadas en un paquete vinculado con

KEEPDYNAMIC NO se elimina del contexto SQL tras una operación de retrotracción.

La sentencia debe volver a prepararse antes de que se pueda ejecutar en una transacción

nueva.

Las sentencias de SQL dinámico siguientes pueden estar activas durante la operación

ROLLBACK:

ROLLBACK, sentencia

Sentencias CALL en las que se ha ejecutado la sentencia ROLLBACK

Una operación ROLLBACK TO SAVEPOINT descartará las tablas temporales creadas

que se hayan creado en el punto de salvaguarda. Si una tabla temporal creada se modifica

en el punto de salvaguarda y esa tabla se ha definido como no anotada cronológicamente,

todas las filas de la tabla se suprimen.

Una operación ROLLBACK TO SAVEPOINT descartará las tablas temporales

declaradas que se hayan declarado en el punto de salvaguarda. Si una tabla temporal

declarada se modifica en el punto de salvaguarda y esa tabla se ha definido como no

anotada cronológicamente, todas las filas de la tabla se suprimen.

Después de una sentencia ROLLBACK TO SAVEPOINT se conservan todos los

bloqueos.

Después de una operación ROLLBACK TO SAVEPOINT se conservan todos los

localizadores de LOB.

Page 35: File Group

35 ADMINISTRACION DE BASE DE DATOS SQL