Está en la página 1de 249

Visual Basic 6.0 y SQLServer 7.

Introducción......................................................................................................................................3
1 Visual Basic versión 6.0................................................................................................................4
1.1 Entorno de Visual Basic.........................................................................................................4
1.1.1 Exploración del ambiente de V.B....................................................................................4
1.1.2 Barra de herramientas.....................................................................................................6
1.1.3 Herramienta de Objetos (ToolBox)..................................................................................7
1.1.4 Ventana de depuración (Debuger)..................................................................................7
1.1.5 Ventana de proyecto (Explorer Window).........................................................................8
1.1.6 Ventana de presentación de las Formas (Form Layout)..................................................8
1.1.7 Registro de componentes................................................................................................8
1.1.8 Registro de referencias ................................................................................................10
1.2 Conceptos Básicos: Variables, Identificadores, Constantes, Tipos de datos, Elección del
tipo de variables..........................................................................................................................12
1.2.1 Declaración de Variables...............................................................................................12
1.2.2 Alcance y Tiempo de vida de las Variables...................................................................12
1.2.3 Tipos de datos................................................................................................................14
1.2.4 Constantes....................................................................................................................17
1.2.5 Etiquetas.......................................................................................................................18
1.3 Operadores...........................................................................................................................19
1.4 Estructuras de control .........................................................................................................28
1.5 Procedimientos Sub y Funciones ........................................................................................34
1.6 Procedimientos con argumentos opcionales.........................................................................37
1.7 Arrays: estáticos y dinámicos............................................................................................40
1.8 Funciones internas de VB ...................................................................................................42
1.9 Eventos, propiedades y Controles.......................................................................................48
1.10 Control de Errores .............................................................................................................59
1.11 Modelo de Objetos de Sistemas de Archivos (FSO)...........................................................64
1.12 Objetos del sistema de archivos: Drive, Folder y Files.......................................................72
1.13 Manejo de API's..................................................................................................................78
1.14 Interactuar con Word y Excel..............................................................................................79
1.15 Activar Animación en los procesos.....................................................................................83
2 Desarrollo de aplicaciones bajo el modelo C/S...........................................................................86
2.1 Modelo cliente / Servidor.......................................................................................................86
2.2 Que es ODBC.....................................................................................................................103
2.3 Conexiones Cliente – Servidor............................................................................................105
2.4 Establecimiento de conexiones cliente-servidor.................................................................106
2.5 Estrategias de bloqueo.......................................................................................................107
3 SQL Server 7.0..........................................................................................................................108
3.1 Permisos.............................................................................................................................113
3.2 Utilizar las opciones de SQL Server...................................................................................114
3.2.1 Opciones SET..............................................................................................................115
3.2.2 Opciones de base de datos..........................................................................................118
3.2.3 Opciones de servidor....................................................................................................120
3.2.4 Sugerencias.................................................................................................................122
3.3.5 Opción del nivel de compatibilidad de la base de datos...............................................123
3.3.6 Comportamiento cuando ARITHABORT y ARITHIGNORE están activadas................123
3.3 Implementación y el mantenimiento de bases de datos.....................................................124
3.3.1 Componentes de una base de datos............................................................................124
3.3.2 Archivos y grupos de archivos......................................................................................125
3.3.2.2 Usar archivos y grupos de archivos...........................................................................126
3.3.3.3 Usar archivos y grupos de archivos para administrar el crecimiento de las bases de
datos.....................................................................................................................................128
3.3.4 Grupos de archivos de sólo lectura..............................................................................128
3.3.4 Registros de transacciones..........................................................................................130
3.3.4.1 Operaciones no registradas......................................................................................130
3.3.4.2 Archivos de registro virtuales....................................................................................131

Material de estudio Página: 1 de 249


Visual Basic 6.0 y SQLServer 7.0

3.4 Crear Bases de datos ....................................................................................................143


3.5 Creación de Tablas.............................................................................................................151
3.5.1 Restricciones PRIMARY KEY......................................................................................153
3.5.2 Restricciones FOREIGN KEY......................................................................................154
3.5.3 Restricciones de no duplicados (UNIQUE)...................................................................155
3.5.4 Restricciones CHECK..................................................................................................156
3.5.5 Dfiniciones DEFAULT...................................................................................................157
3.5.6 Columnas de identificadores.......................................................................................157
3.5.7 SET ANSI_NULLS (T-SQL)..........................................................................................158
3.5.8 EJEMPLOS..................................................................................................................160
3.6 Elementos de sintaxis de Transact-SQL.............................................................................166
1.5.1 Conversión de tipos de datos...........................................................................................166
1.5.2 Utilizar funciones.........................................................................................................173
1.5.3 Programar tareas en Transac-SQL .............................................................................174
1.5.4 Variables y parámetros.................................................................................................175
1.5.5 Control de flujo.............................................................................................................176
1.5.5.1 BEGIN…END............................................................................................................176
1.5.5.2 GOTO........................................................................................................................177
1.5.5.3 IF…ELSE..................................................................................................................177
1.5.5.4 RETURN...................................................................................................................178
1.5.5.5 CASE.........................................................................................................................180
1.6 Transacciones.....................................................................................................................181
1.6.1 Controlar las transacciones..........................................................................................181
1.6.2 Transacciones explícitas..............................................................................................183
1.6.3 Transacciones de confirmación automática.................................................................184
1.7 Cursores.............................................................................................................................185
1.7.1 Cursores de Transact-SQL...........................................................................................186
1.7.2 Tipos de cursores.........................................................................................................189
1.7.3 DECLARE CURSOR ..................................................................................................190
1.7.4 Bloqueo de cursores.....................................................................................................195
1.7.5 Obtener metadatos de cursores de servidor................................................................197
1.8 Procedimientos almacenados ............................................................................................198
1.8.1 Programar procedimientos almacenados.........................................................................200
1.8.1.1 Devolver datos de un procedimiento almacenado.....................................................205
1.8.1.2 Devolver datos mediante parámetros OUTPUT........................................................205
1.8.2.2 Devolver datos mediante un código de retorno.........................................................206
1.8.2.3 Ejecutar un procedimiento almacenado....................................................................208
1.9 Trigger (Desencadenadores)..............................................................................................209
1.9.1 Type (Trigger) (SQL-DMO) (Propiedad).......................................................................210
1.9.2 Desencadenadores anidados (recursive).....................................................................210
1.9.3 CREATE TRIGGER (Creación de Disparadores).........................................................213
Anexos.........................................................................................................................................223
I.1 SQL (Lenguaje Estructurado de Consultas “ Structured Query Language”)........................223
I.2 Nomenclatura de Objetos....................................................................................................245
I.3 Convenciones de nombres de variables para Visual Basic..................................................247

Material de estudio Página: 2 de 249


Visual Basic 6.0 y SQLServer 7.0

Introducción

Con la aparición de Windows 3.1, se incrementó sensiblemente la cantidad de usuarios adeptos a


este ambiente operativo. Sin embargo, los usuarios de perfil técnico habían permanecido al
margen de la utilización de dicho ambiente, por no contar con una herramienta para desarrollar
sus aplicaciones.

Como una solución para ello, surgió en Microsoft: Visual Basic. El sistema de programación de
Visual Basic, permite desarrollar aplicaciones útiles y atractivas, que utilizan y explotan
completamente la interfase gráfica del usuario (GUI).

Visual Basic 6.0 hace más productivo el uso de Microsoft Windows, ya que provee de
herramientas apropiadas para diferentes aspectos del desarrollo del GUI. Se puede crear la
interfase gráfica con sólo dibujar objetos en una aplicación en el mismo modo gráfico, y definir las
propiedades de esos objetos, así como manejar su comportamiento escribiendo código que
responda a los eventos que ocurren en la interfase.

• Usando Visual Basic 6.0, se pueden crear poderosas aplicaciones que exploten las
características claves de Microsoft Windows, tales como:
• Desarrollar aplicaciones sólo para ambientes de 32 bits.
• MDI (Multiple-Document Interface) interfase de documentos múltiples.
• La nueva tecnología de Microsoft llamada OLE (Object Linking & Embedding).
• El DDE (Dynamic Data Exchange).
• El manejo de Gráficos.
• La posibilidad de extenderse añadiendo Custom Control y por llamada de procedimientos
en "Dynamic-Link Libraries" (DLLs).
• La facilidad de poder generar un archivo ejecutable (.EXE), que use al tiempo de
ejecución DLLs que pueden ser libremente distribuidos.
• Creación de controles personalizados Activex y clases.
• Manejo de múltiples proyectos en forma simultánea.

Visual Basic es tan fácil de usar. El programa inicia con la pantalla elemental de Windows
nombrada Forma por sus creadores, y se utiliza una caja de herramientas similar a la de los
programas de dibujo, para añadir los controles: botones de comandos, textos, dibujos, entre otros
elementos. Cada programa puede tener tantos controles como requiera el usuario. Controlar el
tamaño y la posición de la Forma, es como hacer click con el mouse y arrastrar la ventana en
cualquier lugar de la pantalla.

Material de estudio Página: 3 de 249


Visual Basic 6.0 y SQLServer 7.0

1 Visual Basic versión 6.0

1.1 Entorno de Visual Basic

1.1.1 Exploración del ambiente de V.B.

La versión de Visual Basic 6.0 está disponible en tres ediciones.

1. La edición de aprendizaje
2. La edición profesional.
3. La edición empresarial.

La diferencia básica entre las versiones, consiste en que se agregan herramientas (como:
SourseSafe “control de versiones de aplicaciones”, Crystal Report “reporteador para VB”, entre
otras) en cada versión, pero los ambientes de desarrollo son los mismos.

Con la nueva idea de mercado que ha implantado MicroSoft de incluir sus herramientas de
desarrollo más populares en un paquete empresarial llamado Visual Studio 6.0 donde se incluyen
las siguientes herramientas de desarrollo en 6 discos:

Visual C++
 Visual FoxPro
 Visual Basic
 Visual J++
 Viasual Interdev
 MSDN (Microsoft Development Network)
Para instalar VB se utiliza el Disco 1, el cual instala Internet Explorer 5.0 y a continuación solicita
se seleccione las herramientas de desarrollo deseadas.

Para instalara la ayuda MSDN se utilizan los discos 3 y 4, ejecutando del disco 3 el programa de
instalación. En la instalación se solicita se seleccione las ayudas para las herramientas deseadas,
si sólo se desea instalar la ayuda de VB se deberá elegir esta opción.

Material de estudio Página: 4 de 249


Visual Basic 6.0 y SQLServer 7.0

Al igual que otro lenguaje de programación, Visual Basic requiere una comprensión de alguna
terminología común. La siguiente lista contiene algunos términos usados en Visual Basic.

Termino en Termino en Definición


Inglés Español
Design Time Tiempo de En cualquier momento cuando no se está ejecutando la
Diseño aplicación.

Run Time Tiempo de Momento en que la aplicación se está ejecutando


Ejecución

Form Forma Ventana personalizable para incrustar objetos, desplegar


diálogos

Control Control Representación gráfica de objetos (Botones, cajas de lista,


etc) que el usuario manipula para proveer información de a
la aplicación.
Object Objeto Término genérico usado para describir cualquier cosa en
Visual Basic (Formas, controles, Activex, etc.)

Properties Propiedades Características de un objeto color, tamaño, nombre, etc.

Methodos Método Acción invocada que un objeto puede desarrollar

Events Evento Acción que desarrolla un objeto en forma automática


provocada por el usuario al interactuar con la aplicación,
sistema operativo o por la misma aplicación.
Event-Driven Programación Código que se ejecuta en respuesta a eventos invocados
Programming orientada a (usuario, sistema operativo o la aplicación). Esta difiere de
eventos la programación procedural donde el programa inicia en la
primera línea de código y seguida por las rutas de
ejecución de cada línea por el programa.

Material de estudio Página: 5 de 249


Visual Basic 6.0 y SQLServer 7.0

1.1.2 Barra de herramientas

La siguiente figura muestra el ambiente de desarrollo que se despliega en tiempo de diseño de


una aplicación.
Barra de
herramientas
(Toolbar)
ToolBo
x

Explorad
Formulari or
o De
proyecto

Ventana
de
Propieda
des

Ventana Código
de
depuraci
ón
(Debugg
er)
Ventana de
Posición
del
formulario

Material de estudio Página: 6 de 249


Visual Basic 6.0 y SQLServer 7.0

La barra de herramientas (toolbar) contiene botones para muchas de los órdenes más comúnes
usadas en VB, como para abrir la ventana del explorador del proyecto, el depurador, la
presentación de formas, etc., así como otros elementos en el ambiente de desarrollo.

El Toolbar puede personalizarse para que contenga los botones que deseamos así como la
posición donde se desplegarán.

Pulse el botón derecho en el Toolbar y seleccione la opción de personalizar: elija las opciones
deseadas en cada una de las pestañas para que aparezcan en la barra de herramientas.

El ToolBar también puede ser desplazado en el área de la pantalla. Para realizar esta operación
de click izquierdo y sin dejar de pulsarlo arraste el toolbar hasta la posición deseada. Lo mismo
puede hacer para otros objetos del ambiente (ToolBox, Form Window, Property Window, etc.)

1.1.3 Herramienta de Objetos (ToolBox)

La caja de herramientas de controles (ToolBox) contiene los objetos y controles que pueden ser adicionados
en las formas para crear las interfaces gráficas (GUI) de la aplicación. Se pueden adicionar controles al
ToolBox por medio del comando Project\Components, situado en el menú del proyecto. Para invocar la caja
de herramientas es a través del menú View\ToolBox o pulsando el siguiente icono:

1.1.4 Ventana de depuración (Debuger)

La ventana de depuración (Debuger) se usa para consultar o asignar datos (valores de objetos, variables, el
objeto activo en una forma, etc.), ejecutar código. La forma de invocar la ventana de depuración (Inmediate
Window) es a través del menú View \ Inmediate Window o pulsando CTRL-G.

La ventana de depuración sólo puede tener acción cuando se establece un punto de ruptura en el código
que se está ejecutando; en tiempo de diseño no tiene efecto.

El alcance de la ventana de depuración está limitado al procedimiento actual donde ocurre el punto de
evaluación. Para evaluar la siguiente línea del código presione F8, si la siguiente línea de código a evaluar
es una llamada a un procedimiento o función presione Sifth-F8 si no desea seguir paso a paso el bloque de
código del procedimiento o función.

La barra de herramientas asociada al debuger se muestra en la siguiente figura:

la siguiente tabla describe cada uno de los elementos de la figura.

Botón Descripción

Start Inicia la ejecución de la aplicación. Tecla rápida F5.


Detiene temporalmente la ejecución del código.
Break Presione Start o F5 para ejecutar la aplicación.
Presione F8 para ejecutar la aplicación línea a línea.

End Finaliza la ejecución de la aplicación.


Establece/Elimina un punto de ruptura (el código se detiene en la
Toggle Breakpoint línea que se establece) Tecla rápida F9.
Step Info Ejecuta paso a paso cada línea de código. Tecla rápida F8.

No ejecuta paso a paso la siguiente línea de código si es una llamada


Step Over a un procedimiento o función.

Local Window Despliega el valor actual de variables locales.

Material de estudio Página: 7 de 249


Visual Basic 6.0 y SQLServer 7.0

Inmediate Window Despliega la ventana del debuger.

Watch window Despliega el valor de la expresión.


Despliega el valor actual de la expresión en donde se encuentra el
Quick Watch cursor. También este valor puede ser visualizado ubicando el cursor
sobre la expresión y se desplegará el tooltip con el valor actual.
Muestra el diálogo con los procedimientos contenidos en la forma y
Call Stack
pendientes de evaluar. La lista inicia con el activo.

1.1.5 Ventana de proyecto (Explorer Window)

La ventana de exploración del proyecto (Explorer Window) lista la colección de archivos usados
en la aplicación. La colección de archivos (formas, módulos, clases) usados se llama proyecto. Se
puede desplegar el código o la forma con los botones de “View Code” o “View Object”. Para
invocar la forma de proyecto pulse View\Proyect Explorer o CTRL – R o el icono:

1.1.6 Ventana de presentación de las Formas (Form Layout)

Despliega visualmente la posición de como aparecerá la forma en la pantalla. La ventana


contendrá un monitor el cual simula la pantalla, tome y arraste el icono de la ventana que aparece
en la pantalla simulada, sitúelo en la posición que desea que aparezca en el momento de ejecutar
la aplicación. Para desplegar la ventana correspondiente pulse:

1.1.7 Registro de componentes

Los controles ActiveX tienen la extensión de archivo.ocx. Puede usar los controles ActiveX
suministrados con Visual Basic 6.0 o bien puede conseguir controles adicionales desarrollados
por otros programadores.

Puede utilizar controles ActiveX y otros objetos insertables en el proyecto si los agrega al cuadro
de herramientas.

Nota Los controles ActiveX de Visual Basic son controles de 32 bits. Algunos programadores
ofrecen controles ActiveX de 16 bits, que no se pueden usar en la versión 6.0 de Visual Basic.

Para agregar un control al cuadro de herramientas de un proyecto:

Material de estudio Página: 8 de 249


Visual Basic 6.0 y SQLServer 7.0

1 En el menú Proyecto, haga clic en Componentes para mostrar el cuadro de diálogo


Componentes, como se ve en la siguiente figura.

Figura 1.4 El cuadro de diálogo Componentes

Sugerencia También puede ver el cuadro de diálogo si hace clic con el botón secundario del
mouse (ratón) en el cuadro de herramientas (toolbox).

2 Los elementos que se muestran en este cuadro de diálogo incluyen todos los objetos
insertables, diseñadores y controles ActiveX registrados.

3 Para agregar un control ActiveX al cuadro de herramientas, active la casilla de verificación


que hay a la izquierda del nombre del control.

4 Haga clic en Aceptar para cerrar el cuadro de diálogo Componentes. Todos los controles
ActiveX que haya seleccionado aparecerán ahora en el cuadro de herramientas.

Para agregar controles ActiveX al cuadro de diálogo Componentes, haga clic en el botón
Examinar y busque los archivos que tengan la extensión .ocx. Estos archivos suelen estar
instalados en el directorio \Windows\System o System32. Al agregar un control ActiveX a la lista
de controles disponibles, Visual Basic activa automáticamente su casilla de verificación en el
cuadro de diálogo Componentes.

Material de estudio Página: 9 de 249


Visual Basic 6.0 y SQLServer 7.0

1.1.8 Registro de referencias

También puede utilizar objetos de otras aplicaciones, como los incluidos en la biblioteca de
objetos de Microsoft Excel, ya sea como controles del cuadro de herramientas o como objetos
programables en el código.

Para que los objetos de otra aplicación estén disponibles en el código, pero no como controles,
defina una referencia a la biblioteca de objetos de esa aplicación.

Para agregar una referencia a la biblioteca de objetos de otra aplicación:

1. En el menú Proyecto, elija Referencias.

Aparecerá el cuadro de diálogo Referencias, como se muestra en la figura 1.4

2. Active la casilla de verificación correspondiente a la referencia que desea agregar al


proyecto.

Para agregar referencias a aplicaciones no enumeradas en el cuadro de diálogo Referencias,


elija el botón Examinar y seleccione la aplicación.

3. Elija Aceptar para agregar al proyecto las referencias seleccionadas.

Figura 1.4 El cuadro de diálogo Referencias

Si no va a usar ningún objeto de una biblioteca a la que se hace referencia, es conveniente


desactivar la casilla de verificación de dicha referencia para reducir al mínimo posible el número
de referencias a objetos que Visual Basic debe resolver, con lo que se reduce el tiempo de
compilación del proyecto.

Material de estudio Página: 10 de 249


Visual Basic 6.0 y SQLServer 7.0

Una vez que ha definido las referencias a las bibliotecas de objetos que desea, puede buscar un
objeto específico, junto con sus métodos y propiedades, en el Examinador de objetos; para ello,
elija Examinador de objetos en el menú Ver. Puede utilizar en el código cualquier objeto
enumerado en el Examinador de objetos.

Material de estudio Página: 11 de 249


Visual Basic 6.0 y SQLServer 7.0

1.2 Conceptos Básicos: Variables, Identificadores, Constantes, Tipos de datos,


Elección del tipo de variables.

Visual Basic integra diferente tipos de datos, que permiten optimizar el código en velocidad y en
tamaño. En este punto se ve su aplicación.

1.2.1 Declaración de Variables

Para declarar una variable se utiliza la sentencia Dim, dando un nombre a la variable.

Dim variablenombre [As type]

Reglas para determinar el nombre de una variable:


• Necesita empezar con una letra
• Necesita contener sólo caracteres, números y el carácter subrayado (_).
Caracteres de puntuación y espacios, no son permitidos.
• Necesita no exceder de 40 caracteres.
• No puede ser una palabra reservada.

La cláusula opcional As type en la declaración Dim, permite definir el tipo de dato de la variable
que se declara. Si ésta se omite, Visual Basic define el tipo de variable como Variant (variante).

Nota: Los estándares para nombres de variables y objetos se definen en los anexos de:

 Convenciones de nombres de Variables para Visual Basic


 Convenciones de nombres de Objetos para Visual Basic

1.2.2 Alcance y Tiempo de vida de las Variables

Cuando se declara una variable dentro de un procedimiento, solamente el código dentro del
procedimiento puede tener acceso o cambiar el valor de esta variable. Esta tiene un alcance local
para este procedimiento. Sin embargo, algunas veces se necesita usar una variable que tenga un
alcance extenso, cuyo valor esté disponible para todos los procedimientos dentro de la misma
Forma, Módulos de código o los eventos para todos los procedimientos en la aplicación. Visual
Basic permite especificar el alcance de una variable, cuando ésta se declara.

Alcance de Variables
Dependiendo de cómo se declara, una variable es alcanzada en uno de los tres caminos:

Alcance Declaración

Local Dim, Static, o Redim (dentro de un procedimiento)

Módulo Dim (dentro de la sección Declarations de una Forma o módulo de código)

Global Global (dentro de la sección Declaratlons de un módulo)

Material de estudio Página: 12 de 249


Visual Basic 6.0 y SQLServer 7.0

Variables Locales
Una variable local, es reconocida sólo dentro del procedimiento en el cual aparece, y son
declaradas con la declaración Dim. Las variables locales declaradas con Dim, existen sólo
mientras el procedimiento es ejecutado

Variables de Módulo
Las variables definidas en la sección Declarations, son reconocidas en todos los procedimientos
que forman parte de una Forma o, en su caso; en un módulo.

Variables Globales
Las variables globales tienen un alcance extenso. Los valores dentro de las variables globales,
están disponibles para cada Forma y Módulo en la aplicación. A diferencia de las variables de
módulo, las variables globales son declaradas dentro de la sección Declarations de un módulo.
Para declarar variables globales, se utiliza la declaración Global en lugar de la declaración Dim.

Figura 1.5 Visibilidad de variables con diferentes alcances

Variables Estáticas
En adición al alcance, las variables tienen un tiempo de vida. El valor, en módulos y variables
globales, es preservado por el tiempo de vida de la aplicación. Sin embargo, las variables locales
declaradas con Dim, existen sólo mientras el procedimiento, en el cual fueron declaradas; es
ejecutado. Normalmente, cuando un procedimiento finaliza su ejecución, el valor de estas
variables locales no es preservado. La siguiente vez que el procedimiento es ejecutado, todas
estas variables locales son reinicializadas.

Sin embargo, se puede hacer que Visual Basic conserve el valor de una variable local, declarando
la variable como estática (static).

Material de estudio Página: 13 de 249


Visual Basic 6.0 y SQLServer 7.0

Por ejemplo, la siguiente función total, calcula un valor, añadiendo una nueva cantidad al total de
previos valores almacenados en la variable estática acumula

Sub Command1_Click ( )
sumatotal = total(2)
Print sumatotal
End Sub

Function total (num)


Static acumula
acumula = acumula + num
total = acumula
End Funetion

1.2.3 Tipos de datos

Cuando se declara una variable, se le puede asignar un tipo de dato. Por default, si no se asigna
el tipo de dato a la variable, ésta obtiene un tipo de dato Variant (variante).

Tipo de dato Variant (variante).


El tipo de dato Variant, puede almacenar algunos tipos de datos como son: números, strings de
textos ó de fecha y hora. Visual Basic desarolla automáticamente, cualquier conversión
necesaria. Por ejemplo:

Dim Valor
Valor = "94"
Valor = Valor+1900
Valor = "México, D.F. a " & Valor

Las variables Variant, mantienen una representación interna del valor que ésta representa. Con
esta representación interna Visual Basic determina cómo tratar estos valores. Si se quiere
determinar la representación de una variable, se usa la función VarType. La siguiente tabla, lista
el valor regresado de la variable VarType.

VarType Valores regresados


Valor regresado Representación Interna
0 Empty
1 Null
2 lnteger
3 Long
4 Single
5 Double
6 Currency
7 Date/Time
8 String

Ejemplo : lf VarType(Y) = 5 Then X = CSng(Y)

Material de estudio Página: 14 de 249


Visual Basic 6.0 y SQLServer 7.0

Generalmente, almacenar un string en una variable Variant, puede crear pocos problemas.
Algunas veces, el resultado del operador + puede ser ambiguo cuando se usa con dos valores
Variant. Si ambos valores contienen números, el operador + desarrolla una adición. Si ambos
valores contienen un string, desarrolla una concatenación. Pero si uno de los valores representa
un número y otro un string, la situación es más complicada. Visual Basíc, primero intenta
convertir el string en un valor. Si la conversión es exitosa, entonces el operador + agrega el nuevo
valor. De lo contrario, si no es exitosa; éste concatena el número con el string, para producir un
nuevo string.

Cuando se quiera estar seguro de que ocurra una concatenación, se debe usar el operador &.
Por ejemplo:

Dim Valor
Valor = "94"
Valor = Valor+1900
Valor = "México, D.F. a " & Valor

Los rangos de fechas almacenados en variables Variant, son desde Enero 1, 0000 a Diciembre
31, 9999. Se puede usar fecha/hora literalmente en el código, cerrando éstos con el signo (#). Por
ejemplo :

lf fecha = #1/5/94 9:15am# then

Visual Basic acepta una variedad de formatos de fechas y horas en forma literal. Estos son todos
los valores válidos de fecha/hora

Fecha = #2-5-94 15:30#


Fecha = #March 2,1994 9:15am#
Fecha = #Dec-31-94#
Fecha = #31 December 1994#

Se puede usar la función lsdate para determinar si una variable Variant, puede ser considerada
como valor de fecha/hora. También se puede usar la función CVDate, para convertir la variable a
un valor de fecha/hora . Ejemplo

Sub Command1_Click ()
Dim Fecha
lf IsDate(Text1.Text) Then
Fecha = CVDate(Text1.Text)
MsgBox "Fecha correcta ' & Fecha, 48, "Fecha"
Else
MsgBox Text1.Text & "no es una fecha valida", 48, "Fecha"
End lf
End Sub

Algunas veces, se necesita saber si el valor de la variable ha sido asignado. Una variable Variant,
tiene un valor vacío antes de que se le asigne un valor, ya sea un cero (0) o un string. Para probar
si el valor es vacío, se utiliza la función IsEmpty.

lf IsEmpty(Valor) Then Valor = 100

Material de estudio Página: 15 de 249


Visual Basic 6.0 y SQLServer 7.0

El tipo de dato Variant, maneja todos los tipos fundamentales de datos y hace conversiones entre
ellos automáticamente. Sin embargo, si se quiere crear un conciso y rápido código, se pueden
usar otros tipos de datos apropiados. Por ejemplo, si una variable siempre contiene un pequeño
valor, se puede salvar algunos bytes, incrementar la velocidad en el código cuando se desarrollan
operaciones aritméticas, utilizando un Integer (entero) en lugar de una variable Variant.

En la siguiente tabla se muestra una lista de siete tipos de datos fundamentales.

Tipos de datos fundamentales de Visual Basic.


Tamaño de
Tipo de dato Sufijo Almacenamiento Rango

Integer % 2 bytes -32,768 a 32,767.

Long(long integer) & 4 bytes -2,147,483,648 a 2,147,483,647.

Single ! 4 bytes -3.402823E38 a -1.401298E-45 para


valores negativos

(single-precision 1.401298E-45 a 3.402823E38 para


values.floating-point) valores positivos

Double
(double-precision
floating-point) # 8 bytes -1.79769313486232E308 a
-4.94065645841247E-324 para valores
negativos
4.94065645841247E-324 a
1,79769313486232E308 para valores
positivos.

Currency
(scaled integer) @ 8 bytes -922,337,203,685,477.5808 a
922,337,203,685,477.5807.

String $ 1 byte 0 aproximadamente a 65,500 bytes.

Variant None El apropiado Cualquier valor númerico, string o de fecha

Antes de usar una variable No-Variant, se debe usar la declaración Dim, Global o Static para
declararla As tipodato. Por ejemplo, la siguiente declaración, declara un tipo lnteger, Double,
String y Currency, respectivamente.

Dim Valor As lnteger


Dim Resta As Double
Static Regresa As String
Global Flag As Currency
Dim Nombre As String, Total As Currency

Material de estudio Página: 16 de 249


Visual Basic 6.0 y SQLServer 7.0

Tipos Numéricos
Si se sabe que una variable siempre almacena un valor entero, es mejor declararla como un tipo
lnteger o Long. Las operaciones con enteros son más rápidas y consumen menos memoria que
una de tipo Variant. Si una variable contiene una fracción, es mejor declararla como Single,
Double, o Currency. El tipo de dato Currency, soporta hasta cuatro dígitos a la derecha del
punto decimal y 15 hasta la derecha del punto decimal. Números de Punto-Flotante (Single y
Double), tienen un rango más largo que el tipo Currency.

Tipos String
Si se tiene una variable que siempre contiene un string y nunca un valor numérico, es mejor
declarada como un tipo String, además de poder manipular la variable con funciones de string.

Dim Curso As String

Curso = "Visual Basic"


Curso = Left( Curso , 6 )

Para declarar el tamaño de un string se utiliza la sintaxis

String * tamaño

Por ejemplo, para declarar un string que siempre va a contener 45 caracteres

Dim Nombre As String * 45

También, para quitar los espacios en un string se utilizan las funciones Trim y Rtrim

Curso = "Visual Basic 6.0“


Curso = Rtrim(Curso)

1.2.4 Constantes

Frecuentemente, se verán valores constantes en el código (éstos, aparecen una y otra vez) o se
encontrará que el código depende de un cierto valor que es difícil de recordar.

En estos casos, se debe usar la declaración Const. Esta declaración, permite asignar una
constante simbólica en lugar de un número

La sintaxis para la declaración Const, es la siguiente:

[Global] Const constnombre = expresión

Una declaración Const, puede representar una cantidad matemática o de fecha/hora:

Const Pl = 3.14159265
Global Const Juegos = 2
Const Fec-Ent = #2-5-94#
Const Codigo = "Enigma"

Material de estudio Página: 17 de 249


Visual Basic 6.0 y SQLServer 7.0

1.2.5 Etiquetas

Una etiqueta de línea puede ser cualquier combinación de caracteres, pero debe iniciar con una
letra y finalizar con dos puntos “:”. El nombre de la etiqueta no es sensitiva a minúsculas/
mayúsculas, esta debe estar en la primera columna. Es usada para identificar una línea en
especial, su uso sólo se recomienda para el tratamiento de errores.

Ejemplo:
Sub Ini_Mat (Var1, Var2, Var3, Var4)
On Error GoTo ManejadordeError
Código
. . .
Exit Sub
ManejadordeError:
Resume Next
End Sub

Material de estudio Página: 18 de 249


Visual Basic 6.0 y SQLServer 7.0

1.3 Operadores

En el siguiente punto se dará una idea de los operadores que se manejan en VB6 pero es
importante verificar las comentarios que existen en cada uno de estos.

Operador: &
Se utiliza para forzar la concatenación de las cadenas de dos expresiones.

Sintaxis
resultado = expresión1 & expresión2

La sintaxis del operador & consta de las siguientes partes:

Parte Descripción
Resultado Obligatorio; cualquier variable tipo String o Variant.
Expresión 1 Obligatorio; cualquier expresión.
Expresión 2 Obligatorio; cualquier expresión.

Comentarios

Si una expresión no es una cadena de caracteres, se convierte en un tipo String tipo variant. El
tipo de dato del resultado es String si ambas expresiones son expresiones de cadena; de lo
contrario, el resultado es una String tipo variant. Si ambas expresiones son Null, el resultado es
también Null. Sin embargo, si sólo una expresión es Null, esa expresión se considera como una
cadena de longitud cero ("") al concatenarse con la otra expresión. Cualquier expresión Empty se
considera también una cadena de longitud cero.

Operador: *
Se utiliza para multiplicar dos números.

Sintaxis
resultado = número1*número2

La sintaxis del operador * consta de las siguientes partes:

Parte Descripción
Resultado Obligatorio; cualquier variable numérica.
Número 1 Obligatorio; cualquier expresión numérica.
Número 2 Obligatorio; cualquier expresión numérica.

Comentarios

El tipo de dato del resultado es generalmente el de la expresión más exacta. El orden de


precisión, de menos exacto a más exacto, es Byte, Integer, Long, Single, Double, Currency y
Decimal.

Material de estudio Página: 19 de 249


Visual Basic 6.0 y SQLServer 7.0

Esta regla tiene las siguientes excepciones:


Si Resultado es:
La multiplicación implica un tipo Single y un tipo Long. Se convierte a un tipo Double.
El tipo de dato de resultado es un tipo variant Long, Se convierte a un Variant que
Single o Date que se sale del intervalo válido. contiene un tipo Double
El tipo de dato de resultado es un Byte tipo variant que Se convierte a un Integer tipo
se sale del intervalo válido. variant
El tipo de dato de resultado es un Integer tipo variant
Se convierte a un Long tipo variant.
que se sale del intervalo válido.

Si una o ambas de las expresiones son de tipo Null, el tipo de datos del resultado es Null. Si una
expresión es del tipo Empty, se considera como 0.

Nota El orden de precisión utilizado por la suma y la resta no es igual que el orden de precisión
utilizado por la multiplicación.

Operador: +
Se utiliza para sumar dos números.

Sintaxis
resultado = expresión 1 + expresión 2

La sintaxis del operador + consta de las siguientes partes:

Parte Descripción
Resultado Obligatorio; cualquier variable numérica.
Expresión1 Obligatorio; cualquier expresión.
Expresión2 Obligatorio; cualquier expresión.

Comentarios

Cuando utilice el operador + , quizá no pueda determinar si se va a realizar una suma o una
concatenación de cadenas. Utilice el operador & para la concatenación, de modo que se eviten
ambigüedades y se suministren programas claros y explícitos.

Si hay al menos una expresión que no sea de tipo Variant, se aplican las siguientes reglas:
Si Entonces
Ambas expresiones son tipos de datos numéricos (Byte, Boolean, Suma.
Integer, Long, Single, Double, Date, Currency o Decimal)
Ambas expresiones son del tipo String Concatenación.
Una expresión es de un tipo de datos numérico y la otra cualquier Suma.
tipo Variant excepto Null
Una expresión es del tipo String y la otra cualquier tipo Variant Concatenación.
excepto Null
Una expresión es del tipo Empty Variant Devuelve sin modificacio-
nes la expresión restante
como resultado.
Una expresión es de un tipo de datos numérico y la otra de tipo Puede ocurrir un Error
String de tipos.
Cualquiera de las expresiones es Null resultado es Null.
Si ambas expresiones son del tipo Variant, se aplican las siguiente reglas:

Material de estudio Página: 20 de 249


Visual Basic 6.0 y SQLServer 7.0

Si Entonces
Ambas expresiones tipo Variant son numéricas Suma.
Ambas expresiones tipo Variant son cadenas de caracteres Concatenación.
Una expresión tipo Variant es numérica y la otra es una cadena de Suma.
caracteres

En adiciones aritméticas simples de expresiones de tipos de datos numéricos únicamente, el tipo


de dato de resultado es habitualmente el mismo que el de la expresión con mayor precisión. El
orden de precisión, de menos exacto a más exacto, es Byte, Integer, Long, Single, Double,
Currency y Decimal.

Esta regla tiene las siguientes excepciones:


Si result es
Se suman un tipo Single y un tipo Long, un tipo Double.
El tipo de dato de resultado es Long, Single o Date tipo variant se convierte a un Double
que desborda su intervalo válido, tipo variant.
El tipo de dato de resultado es un Byte tipo variant que se sale del se convierte a un Integer
intervalo válido, tipo variant.
El tipo de dato de resultado es un Integer tipo variant que se sale se convierte a un Long
del intervalo válido, tipo variant.
Un Date se agrega a cualquier tipo de dato, un tipo Date.

Si una de las expresiones o ambas son expresiones de tipo Null, resultado es Null. Si ambas
expresiones son Empty, el resultado es Integer. Sin embargo, sólo una de las expresiones es
Empty, se devuelve la otra sin modificaciones como resultado.

Nota El orden de precisión utilizado por la suma y la resta no es igual que el orden de precisión
utilizado por la multiplicación.

Operador: -
Se utiliza para hallar la diferencia entre dos números o para indicar el valor negativo de una
expresión numérica.

Sintaxis 1

resultado = número1-número2

Sintaxis 2
–número

La sintaxis del operador – consta de las siguientes partes:

Parte Descripción
Resultado Obligatorio; cualquier variable numérica.
Número Obligatorio; cualquier expresión numérica.
Número 1 Obligatorio; cualquier expresión numérica.
Número 2 Obligatorio; cualquier expresión numérica.

Comentarios

Material de estudio Página: 21 de 249


Visual Basic 6.0 y SQLServer 7.0

En la sintaxis 1, – es el operador de substracción aritmética utilizado para hallar la diferencia entre


dos números. En la sintaxis 2, – se utiliza como el operador de negación unaria para indicar el
valor negativo de una expresión.

El tipo de dato de resultado es generalmente el de la expresión más exacta. El orden de


precisión, de menos exacto a más exacto, es Byte, Integer, Long, Single, Double, Currency y
Decimal. Este orden tiene las siguientes excepciones:

Si result es
Es una substracción de un tipo Single y un tipo Long, se convierte a tipo
Double.
El tipo de dato de resultado es un tipo variant Long, Single o Date se convierte a un
que se sale del intervalo válido, Variant que contiene un
tipo Double.
El tipo de dato de resultado es un Byte tipo variant que se sale del se convierte a un
intervalo válido, Integer tipo variant.
El tipo de dato de resultado es un Integer tipo variant que se sale del se convierte a un Long
intervalo válido, tipo variant.
La substracción implica a un tipo Date y cualquier otro tipo de dato, es un tipo Date.
La substracción implica dos expresiones tipo Date, es un tipo Double.

Si una o ambas de las expresiones son de tipo Null, el tipo de datos del resultado es Null. Si una
expresión es del tipo Empty, se considera como si fuera 0.

Nota El orden de precisión utilizado por la suma y la resta no es igual que el orden de precisión
utilizado por la multiplicación.

Material de estudio Página: 22 de 249


Visual Basic 6.0 y SQLServer 7.0

Operador: /
Se utiliza para dividir dos números y obtener un resultado de signo flotante.

Sintaxis

resultado = número 1 / número 2

La sintaxis del operador / consta de las siguientes partes:


Parte Descripción
Resultado Obligatorio; cualquier variable numérica.
Número 1 Obligatorio; cualquier expresión numérica.
Número 2 Obligatorio; cualquier expresión numérica.

Comentarios
El tipo de dato de resultado es normalmente un Double tipo variant o un tipo Double. Esta regla
tiene las siguientes excepciones:

Si Resultado es
Ambas expresiones son expresiones de tipo Un tipo Single a menos que salga de su
Byte, Integer o Single, intervalo válido, en cuyo caso se produce un
error.
Ambas expresiones son Byte, Integer o Un tipo Single a menos que salga de su
Single tipo variant, intervalo válido; en este caso resultado es un
tipo Variant que contiene un tipo Double.
La división contiene un tipo Decimal y Un tipo Decimal.
cualquier otro tipo de dato,

Si una o ambas de las expresiones son de tipo Null, el tipo de datos del resultado es Null. Si una
expresión es del tipo Empty, se considera 0

Operador: \
Se utiliza para dividir dos números y obtener un resultado entero.
Sintaxis
resultado = número 1 \ número 2

La sintaxis del operador \ consta de las siguientes partes:

Parte Descripción
Resultado Obligatorio; cualquier variable numérica.
Número 1 Obligatorio; cualquier expresión numérica.
Número 2 Obligatorio; cualquier expresión numérica.

Material de estudio Página: 23 de 249


Visual Basic 6.0 y SQLServer 7.0

Comentarios

Antes de efectuar la división se redondean las expresiones numéricas para convertirlas en


expresiones tipo Byte, Integer o Long.

Normalmente, el tipo de dato del resultado es tipo Byte, Byte tipo variant, tipo Integer o Integer
tipo variant, tipo Long o Long tipo variant, independientemente de si el resultado es un número
entero o no. La parte fraccionaria se trunca. Sin embargo, si cualquiera de las expresiones es
Null, resultado es Null. Toda expresión que sea Empty se considera como 0.

Operador: ^

Se utiliza para elevar un número a la potencia del exponente.

Sintaxis
resultado = número ^ exponente

La sintaxis del operador ^ consta de las siguientes partes:

Parte Descripción
Resultado Obligatorio; cualquier variable numérica.
Número Obligatorio; cualquier expresión numérica.
Exponente Obligatorio; cualquier expresión numérica.

Comentarios

Un número puede ser negativo sólo si exponente es un entero. Cuando se efectúa más de una
exponenciación en una única expresión, el operador ^ se resuelve en el orden en que esté, de
izquierda a derecha.

Generalmente, el tipo de dato del resultado es un Double o un Variant que contiene un Double.
Sin embargo, si número o exponente es una expresión Null resultado es también Null.

Material de estudio Página: 24 de 249


Visual Basic 6.0 y SQLServer 7.0

Operadores de comparación.
Se utilizan para comparar expresiones.

Sintaxis
resultado = expresión1 operadorcomparación expresión2
resultado = objeto1 Is objeto2
resultado = cadena Like patrón

Los operadores de comparación constan de las siguientes partes:


Parte Descripción
Resultado Obligatorio; cualquier variable numérica.
Expresión Obligatorio; cualquier expresión.
Operador de comparación Obligatorio; cualquier operador de comparación.
Objeto Obligatorio; cualquier nombre de objeto.
Cadena Obligatorio; cualquier expresión de cadena.
Patrón Obligatorio; cualquier expresión de cadena o intervalo de
caracteres.

Comentarios
Esta tabla contiene una lista de los operadores de comparación y de las condiciones que
determinan si el resultado es True, False o Null:

OPERADOR TRUE SI FALSE SI NULL SI


< (Menor que) expresión1 < expresión2 expresión1 >= expresión2 expresión1 ó
expresión2 = Null
<= (Menor o expresión1 <= expresión2 expresión1 > expresión2 expresión1 ó
igual que) expresión2 = Null
> (Mayor que) expresión1 > expresión2 expresión1 <= expresión2 expresión1 ó
expresión2 = Null
>= (Mayor o expresión1 >= expresión2 expresión1 < expresión2 expresión1 ó
igual que) expresión2 = Null
= (Igual a) expresión1 = expresión2 expresión1 <> expresión2 expresión1 ó
expresión2 = Null
<> (Distinto de) expresión1 <> expresión2 expresión1 = expresión2 expresión1 ó
expresión2 = Null

Nota Los operadores Is y Like tienen funciones de comparación específicas que difieren de
las de los operadores incluidos en la siguiente tabla.

Cuando se comparan dos expresiones, puede ser difícil determinar si éstas se comparan
como números o como cadenas de caracteres. En la siguiente tabla se muestra el modo en
que se comparan expresiones y cuál es el resultado cuando cualquiera de las expresiones no
es del tipo Variant:

Material de estudio Página: 25 de 249


Visual Basic 6.0 y SQLServer 7.0

Si Entonces
Ambas expresiones son de tipos de datos Se efectúa una comparación numérica.
numéricos (Byte, Boolean, Integer, Long,
Single, Double, Date, Currency o Decimal)
Ambas expresiones son de tipo String Se efectúa una comparación de cadenas.
Una expresión es de tipo de datos numérico y la Se efectúa una comparación numérica.
otra es un tipo Variant que es, o puede ser, un
número
Una expresión es de tipo de datos numérico y la Provoca un error de Error de tipos.
otra es un tipo Variant de cadena de caracteres
que no se puede convertir en un número
Una expresión es de tipo String y la otra es Se efectúa una comparación de cadenas.
cualquier tipo Variant, con excepción de Null
Una expresión es Empty y la otra es del tipo de Se efectúa una comparación numérica,
datos numérico usando 0 como la expresión Empty.
Una expresión es Empty y la otra es del tipo Se efectúa una comparación de cadenas,
String utilizando una cadena de caracteres de
longitud cero ("") como la expresión Empty.

Si tanto expresión1 como expresión2 son del tipo Variant, el tipo subyacente de las mismas
es el que determina la manera en que se comparan. En la siguiente tabla se muestra el modo
en que se comparan las expresiones y cuál es el resultado de la operación de acuerdo con el
tipo subyacente de Variant:

Si Entonces
Ambas expresiones tipo Variant son Se efectúa una comparación numérica.
numéricas
Ambas expresiones tipo Variant son cadenas Se efectúa una comparación de cadenas.
de caracteres
Una expresión tipo Variant es numérica y la La expresión numérica es menor que la
otra es una cadena de caracteres expresión de cadena.
Una expresión tipo Variant es Empty y la otra Se efectúa una comparación numérica, usando
es numérica 0 como la expresión Empty.
Una expresión tipo Variant es Empty y la otra Se efectúa una comparación de cadenas,
es una cadena de caracteres utilizando una cadena de caracteres de longitud
cero ("") como la expresión Empty.
Ambas expresiones tipo Variant son Empty Las expresiones son iguales.

Cuando se compara un tipo Single con un tipo Double, éste se redondea al grado de
precisión del tipo Single.
Si una expresión tipo Currency se compara con una de tipo Single o Double, ésta se
convierte al tipo Currency. De igual forma, cuando un tipo Decimal se compara con un tipo
Single o Double, el tipo Single o el Double se convierten a tipo Decimal. Para el tipo
Currency, cualquier valor fraccionario menor que 0,0001 se pierde; para el tipo Decimal,
cualquier valor fraccionario menor que 1E-28 se pierde y puede ocurrir un error de
desbordamiento. Perder valores fraccionarios puede hacer que dos valores se comparen
como iguales cuando en realidad no lo son.

Material de estudio Página: 26 de 249


Visual Basic 6.0 y SQLServer 7.0

Prioridad de Operadores
Cuando hay varias operaciones en una misma expresión, cada parte de la misma se evalúa y
se resuelve en un orden predeterminado según la prioridad de los operadores.

Cuando hay expresiones que contienen operadores de más de una categoría, se resuelven
antes las que tienen operadores aritméticos, a continuación las que tienen operadores de
comparación y por último las de operadores lógicos. Los operadores de comparación tienen
todos la misma prioridad; es decir, se evalúan de izquierda a derecha, en el orden en que
aparecen. Los operadores lógicos y aritméticos se evalúan en el siguiente orden de prioridad:

Aritméticos Comparación Lógicos


Exponenciación (^) Igualdad (=) Not
Negación (–) Desigualdad (<>) And
Multiplicación y división (*, /) Menor que (<) Or
División de enteros (\) Mayor que (>) Xor
Módulo aritmético (Mod) Menor o igual que (<=) Eqv
Adición y substracción (+, –) Mayor o igual que (>=) Imp
Concatenación de cadenas (&) Like
Is

Cuando hay multiplicación y división en la misma expresión, cada operación se evalúa a


medida que aparece, de izquierda a derecha. Del mismo modo, cuando se presentan
adiciones y substracciones en una misma expresión, cada operación se evalúa tal como
aparecen de izquierda a derecha. Es posible usar paréntesis para saltar el orden de
preferencia y forzar que algunas partes de una expresión se evalúen antes que otras. Las
operaciones entre paréntesis se realizan antes que las de fuera. Sin embargo, dentro de los
paréntesis, la precedencia de los operadores se mantiene.

El operador de concatenación de cadenas (&) no es realmente un operador aritmético, pero


en orden de prioridad se encuentra a continuación de todos los operadores aritméticos y
antes que todos los operadores de comparación.

El operador Like, a pesar de tener la misma prioridad que los operadores de comparación, es
en realidad un operador de coincidencia de patrones.

El operador Is es un operador de comparación de referencia de objetos. No compara objetos


ni valores de objetos; sólo determina si dos referencias de objeto se refieren al mismo objeto.

Material de estudio Página: 27 de 249


Visual Basic 6.0 y SQLServer 7.0

1.4 Estructuras de control

Las declaraciones que controlan las decisiones y los loops en Visual Basic, son llamadas
estructuras de control. Las estructuras de control de Visual Basic, son similares a los controles
encontrados en C y Pascal. Las estructuras de control más usadas en Visual Basic son las
siguientes:

• lf-Then blocks
• lf-Then-Else blocks
• IIf(expresión, parte verdadera, parte falsa)
• Select Case declaraciones
• Do loops
• For loops

Estructuras de Decisión
En Visual Basic, los procedimientos pueden contener una condición de prueba, y ésta, depender
del resultado de la prueba para desarrollar diferentes acciones. Las estructuras de decisión que
Visual Basic soporta, incluyen:

• lf... Then
• lf... Then ... Else
• IIf(expresión, parte verdadera, parte falsa)
• Select Case

lf ... Then
Usar lf ... Then para ejecutar una o más declaraciones condicionalmente. Se puede usar una
línea sencilla ó múltiple. La sintaxis es la siguiente:

lf condición Then declaración

lf condición Then
declaración
End lf

Ejemplo:

lf algunvalor > 8 Then Bandera = True

lf algunvalor > 8 Then


Bandera = True
End lf

Material de estudio Página: 28 de 249


Visual Basic 6.0 y SQLServer 7.0

lf ... Then ... Else

Usar lf ... Then ... Else para definir varios bloques de declaraciones, una de las cuales; se
ejecuta. La sintaxis es la siguiente

lf condición1 Then
declaración1
[Elself condicion2 Then
[declaración 2]]...
[Else
[declaración n ]]
End lf

Ejemplo:

Sub Form
Dim X,Y ' Declaración de variables.
X = lnputBox("Teclear un número mayor que 0 y menor que 1000,")
lf X < 10 Then
Y=1 ' 1 digito,
Elself X < 100 Then
Y=2 '2digitos.
Else
Y=3 ' 3 digitos.
End lf
lf Y > 1 Then Unit = “digitos." Else Unit = “digito.”
MsgBox "El número que tu tecleaste tiene ” & Y & Unit
End Sub

IIf (expresión, parte verdadera, parte falsa)

Evalúa una expresión y retorna un valor. IIf siempre evalúa la parte verdadera y la parte falsa.
Por esta razón, deberá vigilar que no se produzcan efectos no deseados.

Ejemplo:
Mivar = IIF(A > 8 , “A es mayor”, “A es menor”)

Material de estudio Página: 29 de 249


Visual Basic 6.0 y SQLServer 7.0

Select Case
Usar Select Case para seleccionar una o más declaraciones condicionalmente. Es similar al lf ...
Then ... Else, pero Select Case hace al código más eficiente La sintaxis es la siguiente

Select Case expresionprueba


[Case listaexpresión1]
[declaración l]]
[Case listaexpresión2)
[declaración 2]]
[Case Else
[declaración n]]
End Select Ejemplo

Sub mnuBackColorItem_Click (index As lnteger)


Select Case lndex
Case0 'Coloca la propiedad BackColor a Rojo
txtEdit.BackColor = RGB(255, 0, 0)
Case 1 'Coloca la propiedad BackColor a Verde
txtEdit.BackColor = RGB(0, 255, 0)
Case 2 ' Coloca la propiedad BackColor a Azul
txtEdit.BackColor = RGB(0, 0, 255)
End Select

Material de estudio Página: 30 de 249


Visual Basic 6.0 y SQLServer 7.0

Estructuras Continuas
Las estructuras continuas permiten ejecutar más de una línea de código repetitivamente. Las
estructuras continuas que Visual Basic soporta, incluyen:

• Do... Loop
• For... Next

Do ... Loop
Se utiliza Do ... Loop para ejecutar un bloque de declaraciones, en un número infinito de veces.
Cada vez que se ejecuta la declaración, es evaluada, permitiendo determinar la continuación de
la misma. Como con lf .... Then, la condición debe ser un valor o una expresión que evalúe si es
verdadero (True) ó falso (False).

En el siguiente Do .... Loop, la declaración es ejecutada mientras la condición es verdadera


(True):

Do While condición
declaraciones
Loop

Ejemplo:

Sub Command1_Click ( )

Dim Respuesta ' Declaración de variable

Do While Respuesta = 0 Or Respuesta > 9


Respuesta = lnputBox("Teclear un número mayor que 1 y menor que 9.")
Loop

End Sub

Variación del Ejemplo anterior:

Sub Command1_Click ( )

Dim Respuesta 'Declaración de la variable


Do Respuesta
Respuesta = InputBox("Teclear un número mayor que 1 y menor que 9.")
lf Respuesta > 1 And Respuesta < 9 Then Checa el rango.
Exit Do ' Exit Do Loop
End If
Loop

End Sub

Material de estudio Página: 31 de 249


Visual Basic 6.0 y SQLServer 7.0

Otra variación del Do ... Loops, es cuando la condición es evaluada al final de cada ejecución.
Esta variación garantiza al menos, una ejecución de las declaraciones.

Do
declaración
Loop While condición

Las siguientes declaraciones son análogas a las dos anteriores:

Do Until condición Do
declaración declaración
Loop Loop Until condición

For ... Next

Do ... Loop trabaja muy bien, cuando no se sabe cuántas veces se necesita ejecutar
declaraciones en el Loop, Sin embargo, se necesita ejecutar un número de veces específico, es
más eficiente usar un loop For ... Next. A diferencia de un Do ... Loop, un loop For ... Next usa
un contador que incrementa o decrementa un valor, durante cada repetición del loop

La sintaxis es la siguiente

For contador = principio To Final [Step incremento]


declaraciones
Next [contador]

Nota : el argumento "incremento", puede ser negativo o positivo

Ejemplo:

Sub Command1_Ciick ( )
Dim I, Msg, NL, Rep

NL = Chr(13) & Chr(10)


For Rep = 5 To 1 Step -1
For I = Asc("A") To Asc("Z")
Msg = Msg & Chr(I)
Next I
Msg = Msg & NL
NextRep
MsgBox Msg

End Sub

Material de estudio Página: 32 de 249


Visual Basic 6.0 y SQLServer 7.0

Salir de una Estructura de Control


La declaración Exit, permite salir directamente desde un For...Loop, Do ... Loop, procedimiento
Sub o un procedimiento Function. Sintácticamente, la declaración Exit es simple: Exit For
puede aparecer tantas veces como sea necesario dentro de un For...Loop, y un Exit Do puede
aparecer tantas veces como sea necesario dentro de un Do...Loop.:

For contador = principio To Final [Step ¡ncremento)


[declaraciones]
[Exit Forl
[declaraciones]
Next [contador, [contador] [,....]]

Do [{While  Until }] condicion]


[declaraciones]
[Exít do]
[declaraciones]
Loop

Ejemplo

Sub Form_Click()

Dim I, Num 'Declaración de variables,


Do 'loop infinito

For I = 1 To 1000
Num = Int(Rnd * 100) 'Genera un número random
Select Case Num ‘Evalua el número random
Case 7 : Exit For ‘Si 7, exit For...Next.
Case 29: Exit Do ‘Si 29, exit Do...Loop
Case 54 : Exit Sub ‘Si 54, exit Sub procedure.
End Select
Nexi I
Loop
End Sub

Ejemplo: salida en una función.

Function SquareRoot (X As Double) As Double


Select Case Sgn(X) 'Evalua el signo del argumento.
Case 1 'OK si es positivo.
SquareRoot = Sqr(X)
Exit Function
Case 0 ' Notify user if 0
SquareRoot = 0
Case -1 ' Notifica al usuario si es negativo.
SquareRoot = -1
End Select
End Function

Material de estudio Página: 33 de 249


Visual Basic 6.0 y SQLServer 7.0

1.5 Procedimientos Sub y Funciones

Un evento (event), es una acción reconocida por una Forma ó Control. Las aplicaciones Event-
Driven, ejecutan un código en respuesta a un evento. Cada Forma y Control, en Visual Basic;
tiene un conjunto de eventos predefinidos. Si uno de estos eventos ocurre, Visual Basic invoca
el código asociado con el procedimiento del evento (event procedure). Cuando se quiera que una
Forma ó Control responda a un evento,se debe escribir un código llamado event procedure.

Por ejemplo, un evento click ocurre cuando un usuario hace click en un objeto. Si un usuario
hace click en un command button nombrado Command1, el procedimiento del evento
Command1_Click es ejecutado.

Módulos
Los módulos son muy útiles, ya que ellos permiten llamar procedimientos que sean comunes,
entre más de una Forma o Control. Esto permite reducir líneas de código de programación y evita
duplicar el código. Además, esto puede permitir la construcción de librerías de Módulos de
código, que son muy útiles.

Cada módulo puede contener:

• Declaraciones. Se pueden poner constantes, tipos, variables y declaraciones de


procedimientos DLL.

• Event procedures. Son procedimientos Sub, que responden a los eventos de los
controles.

• Procedimientos Generales. Todos los procedimientos en un módulo, son


procedimientos generales; y en una aplicación, pueden ser llamados desde el código. Los
procedimientos generales también pueden ser procedimientos Sub o Function.

Material de estudio Página: 34 de 249


Visual Basic 6.0 y SQLServer 7.0

Procedimientos

Los procedimientos pueden ser Sub o Function. Un procedimiento Sub no puede retornar un
valor, así que un procedimiento Sub es una completa declaración.

Un procedimiento Function puede retornar un valor, así entonces, es parte de una expresión.

Nota: Los eventos de procedimiento son siempre procedimientos Sub, nunca procedimientos
Function.

Procedimientos Sub
La sintaxis para el procedimiento Sub es:

Sub nombreprocedimiento (arglist)


declaraciones
End Sub

El arglist es una lista de nombres de argumentos, separados por comas (,) si hay más de uno. La
sintaxis de un argumento es:

[ByVal] nombrevariable [( )] [As tipo]

Ejemplo

Sub File1_MouseDown (Button As lnteger, Shift As lnteger, X As Single, Y As Single)


file1.DragIcon = Drive1.DragIcon
fiie1.Drag
End Sub

Cada vez que el procedimiento es llamado, la declaración entre Sub y End Sub es ejecutada.
Visual Basic sustituye cada referencia, a una partida en la lista de los argumentos, con el
correspondiente argumento. Cuando se llama a un procedimiento general, se necesita pasar el
valor para cada argumento. Por ejemplo, si se necesita mover una imagen a la izquierda

Sub Muevelmagen (Mover)


lmagen1.Move lmagen1+Mover,imagen1,Top
End Sub

La declaración anterior necesita ser llamada con un argumento. Ejemplo:

Muevelmagen 50

El procedimiento sustituye 50 por Mover (éste aparece en la lista de argumentos)

Material de estudio Página: 35 de 249


Visual Basic 6.0 y SQLServer 7.0

Function

La sintaxis para el procedimiento Fuction es;

Function nombreprocedimiento (argumentos) [As tipo]


declaraciones
End Function

Los argumentos en procedimiento Function, trabajan exactamente igual que en los


procedimientos Sub.

Diferencias del procedimiento Function:

• Siempre se usan paréntesis con cada llamada de función.


• El procedimiento Function tiene tipos de datos, como las variables.
• Se puede retornar un valor, asignándolo al nombre del procedimiento.

Por ejemplo, se puede escribir esta función para calcular el IVA de una cantidad:

Function CalcIva (Monto)


CalcIva = Monto *.1
End Function

Se puede llamar la función de la siguiente manera: X = Calclva(5000)

Mecanismos de comentarios, números y declaraciones.


En Visual Basic, el símbolo ( ‘ ), se utiliza para las líneas de comentario. Ejemplo:

'Este texto es asignado al control Text1l


Text1.Text = "Curso de Visual Basic 3.0" 'Aparece en la caja del texto.

Algunos números se usan para asignar valores a las propiedades de algunos controles. Éstos
pueden ser en base 10 (decimal), base 16 (hexadecimal) que en Visual Basic se representa con
un prefijo &H ó base 8 (octal) que se representa con un prefijo &O.

En Visual Basic, las declaraciones son normalmente una por línea. Sin embargo. se puede poner
más de una declaración en una línea, utilizando los dos puntos ( : ), como separador. Ejemplo

Text1.Text = " Curso de Visual Basic " : Fuente=16 : Text1.FontSize= Fuente

Reglas de nombres en Visual Basic


El nombre de procedimientos, variables y constantes, debe seguir la siguiente regla:

• Comenzar con una letra


• Debe contener sólo letras y números. Los signos de puntuación y los espacios, no son
permitidos.
• No puede ser más largo de 40 caracteres,
• No usar los nombres de las palabras reservadas para el lenguaje de Visual Basic.

Material de estudio Página: 36 de 249


Visual Basic 6.0 y SQLServer 7.0

1.6 Procedimientos con argumentos opcionales.

Normalmente el código de un procedimiento necesita cierta información sobre el estado del


programa para realizar su trabajo. Esta información consiste en variables que se pasan al
procedimiento cuando se le llama. Cuando se pasa una variable a un procedimiento, se llama
argumento.

Tipos de datos de los argumentos


Los argumentos de los procedimientos tienen el tipo de dato Variant de forma
predeterminada. Sin embargo, puede declarar otros tipos de datos para los argumentos. Por
ejemplo, la función siguiente acepta una cadena y un entero:
Function QuéComer (DíaSemana As String, Hora _
As Integer) As String
' Devuelve el menú del almuerzo basándose en el día y la hora.
If DíaSemana = "Viernes" then
QuéComer = "Pescado"
Else
QuéComer = "Pollo"
End If
If Hora > 4 Then QuéComer = "Demasiado tarde"
End Function

Paso de argumentos por valor


Sólo se pasa una copia de la variable cuando se pasa un argumento por valor. Si el
procedimiento cambia el valor, el cambio afecta sólo a la copia y no a la variable propiamente
dicha. Utilice la palabra clave ByVal para indicar un argumento pasado por valor. Por
ejemplo:
Sub Cuentas (ByVal intNumCuenta as Integer)

. ' Ponga aquí sus instrucciones.

End Sub

Paso de argumentos por referencia


Al pasar argumentos por referencia se permite al procedimiento el acceso al contenido real de
la variable en su ubicación de dirección de memoria. Como resultado, el procedimiento al que
se ha pasado el valor de la variable se puede modificar de forma permanente. La forma
predeterminada de pasar valores en Visual Basic es por referencia.
Si especifica el tipo de dato de un argumento que se pasa por referencia, debe pasar un valor
de ese tipo para el argumento. Puede eludirlo si pasa una expresión en vez de un tipo de dato
como argumento. Visual Basic evalúa la expresión y la pasa como el tipo requerido si puede.
La forma más sencilla de convertir una variable en una expresión es ponerla entre paréntesis.
Por ejemplo, para pasar una variable declarada como entero a un procedimiento que espera
una cadena como argumento, debería hacer lo siguiente:
Sub ProcedimientoQueLlama ()
Dim intX As Integer
intX = 12 * 3

Material de estudio Página: 37 de 249


Visual Basic 6.0 y SQLServer 7.0

Foo(intX)
End Sub

Sub Foo(Bar As String)


MsgBox Bar 'El valor de Bar es la cadena "36".
End Sub

Uso de argumentos opcionales


Puede especificar argumentos a un procedimiento como opcionales si coloca la palabra clave
Optional en la lista de argumentos. Si especifica un argumento opcional, todos los
argumentos subsiguientes de la lista de argumentos deben ser también opcionales y se
deben declarar con la palabra clave Optional. Los dos fragmentos de código de ejemplo que
se muestran a continuación suponen que hay un formulario con un botón de comando y un
cuadro de lista.
Por ejemplo, este código proporciona todos los argumentos como opcionales:
Dim strNombre As String
Dim varDirección As Variant

Sub ListText(Optional x As String, Optional y _


As Variant)
List1.AddItem x
List1.AddItem y
End Sub

Private Sub Command1_Click()


strNombre = "sunombre"
varDirección = 12345 ' Se proporcionan ambos argumentos.
Call ListText(strNombre, varDirección)
End Sub

Sin embargo, este código no proporciona todos los argumentos como opcionales:
Dim strNombre As String
Dim varDirección As Variant

Sub ListText(x As String, Optional y As Variant)


List1.AddItem x
If Not IsMissing(y) Then
List1.AddItem y
End If
End Sub

Private Sub Command1_Click()


strNombre = "sunombre" 'No se proporciona el segundo argumento.
Call ListText(strNombre)
End Sub

En caso de que no se proporcione un argumento opcional, se asigna el argumento como un


tipo Variant con el valor Empty. El ejemplo anterior muestra cómo probar si se han perdido
argumentos opcionales mediante la función IsMissing.

Material de estudio Página: 38 de 249


Visual Basic 6.0 y SQLServer 7.0

Proporcionar un valor predeterminado a un argumento opcional

También es posible especificar un valor predeterminado para un argumento opcional. El


siguiente ejemplo devuelve un valor predeterminado si no se pasa el argumento opcional al
procedimiento Function:
Sub ListText(x As String, Optional y As _
Variant = 12345)
List1.AddItem x
List1.AddItem y
End Sub

Private Sub Command1_Click()


strNombre = "sunombre" ' No se proporciona el segundo
' argumento.
Call ListText(strNombre) ' Agrega "sunombre" y "12345".
End Sub

Uso de un número indefinido de argumentos


Generalmente, el número de argumentos en la llamada a un procedimiento debe ser el mismo
que los especificados en el procedimiento. Utilizar la palabra clave ParamArray le permite
especificar que el procedimiento aceptará un número arbitrario de argumentos. Eso le permite
escribir funciones como Sum:
Dim x As Variant
Dim y As Integer
Dim intSum As Integer

Sub Sum(ParamArray intNums())


For Each x In intNums
y = y + x
Next x
intSum = y
End Sub

Private Sub Command1_Click()


Sum 1, 3, 5, 7, 8
List1.AddItem intSum
End Sub

Creación de instrucciones más sencillas mediante argumentos con


nombre
En muchas funciones, instrucciones y métodos incorporados, Visual Basic proporciona la
opción de utilizar argumentos con nombre como método abreviado para escribir valores de
argumentos. Con los argumentos con nombre puede proporcionar cualquiera o todos los
argumentos, en cualquier orden, asignando un valor al argumento con nombre. Para ello,
escriba el nombre del argumento y un signo de dos puntos seguido del signo igual y el valor
(MiArgumento:= "UnValor") y colocando esta asignación en cualquier secuencia delimitada
con comas. Observe que los argumentos del ejemplo siguiente están en orden inverso al de
los argumentos esperados:
Function ListText(strNombre As String, Optional varDirección As
Variant)

Material de estudio Página: 39 de 249


Visual Basic 6.0 y SQLServer 7.0

List1.AddItem strNombre
List2.AddItem varDirección
End Sub

Private Sub Command1_Click()


ListText varDirección:=12345, strNombre:="Su nombre"
End Sub

Esto resulta especialmente útil si sus procedimientos tienen varios argumentos opcionales
que no siempre necesita especificar.

Determinación del soporte de argumentos con nombre


Para determinar qué funciones, instrucciones y métodos aceptan argumentos con nombre,
utilice la característica Información rápida automática de la ventana Código, compruebe el
Examinador de objetos o consulte la Referencia del lenguaje en los Libros en pantalla. Tenga
en cuenta lo siguiente cuando trabaje con argumentos con nombre:
• Los métodos de objetos de la biblioteca de objetos de Visual Basic (VB) no aceptan
argumentos con nombre, ni tampoco lo hacen todas las palabras clave del lenguaje de la
biblioteca de objetos de Visual Basic para aplicaciones (VBA).
• En la sintaxis, los argumentos con nombre se muestran en negrita y cursiva. Todos los
demás argumentos se muestran sólo en cursiva.

Importante No puede utilizar argumentos con nombre para evitar especificar argumentos
requeridos. Sólo puede omitir los argumentos opcionales. En las bibliotecas de objetos de
Visual Basic (VB) y Visual Basic para aplicaciones(VBA), el Examinador de objetos pone los
argumentos opcionales entre corchetes [ ].

1.7 Arrays: estáticos y dinámicos.

Un arreglo permite referirse a una serie de variables del mismo nombre, además de usar un
número de identificación para cada elemento. Todos los elementos de un arreglo, tienen el
mismo tipo de dato.

A continuación, se exponen tres carninos para declarar el tamaño de un arreglo; dependiendo del
alcance que necesite tener el arreglo.

• Para crear un arreglo global, usar la declaración Global en la sección


Declarations de un módulo.
• Para crear un arreglo a nivel de módulo, usar la declaración Dim en la sección
Declarations de una Forma o módulo
• Para crear un arreglo local, usar la declaración Static en un procedimiento.

Ejemplos de arreglos:

Dim Conteo(20) As lnteger


Dim Sumas(40) As Double

Para crear un arreglo global:

Global Conteo(20) As Integer


Global Sumas(40) As Double

Material de estudio Página: 40 de 249


Visual Basic 6.0 y SQLServer 7.0

La misma declaración dentro de un procedimiento utilizando Static

Static Conteo(20) As lnteger


Static Sumas(40) As Double

En la siguiente declaración el número indice de Sumas corre de 120 a 140

Dim Sumas(120 a 140) As String

El siguiente ejemplo inicializa los elementos con un número 2

Static Sumas(1 a 20) As integer


Dim X As integer
For X=1 To 20
Sumas(X) = 2
Next

Arreglos Multidimensionales
En Visual Basic, se pueden declarar arreglos hasta de 60 dimensiones. Por ejemplo, la siguiente
declaración declara un arreglo de 2 dimensiones de 5x5 .

Static Matriz(4,4) As String


0
Static Matriz(1 To 5,1 To 5) As String

Dim Multi(4,1 To 5,1 To 10)

El ejemplo anterior crea un arreglo de 3 dimensiones de 5 x 5 x 10; es decir: 250 elementos.

Arreglos Dinámicos
En algunas ocasiones, no se conoce que tan largo puede ser un arreglo. Un arreglo dinámico es
muy eficiente, ya que permite cambiar el tamaño de un arreglo,

• Para crear un arreglo dinámico

1 Declarar el arreglo con la declaración Global o Dim, a nivel de módulo y con Dim o
Static en un procedimiento. Se puede declarar el arreglo con una dimensión vacía . Por ejemplo:

Dim Arreglo( )

2 Asignar el actual número de elementos con la declaración ReDim. Por ejemplo:

ReDim Arregio(Y + 1)

La declaración ReDim, puede aparecer sólo en un procedimiento. ReDim puede cambiar el


número de elementos de un arreglo, pero no el número de dimensiones.

Cada vez que se ejecuta un arreglo con la declaración ReDim, todos los valores almacenados en
un arreglo, se pierden. Para evitar esto, se puede usar la palabra Preserve. Por ejemplo:

ReDim Preserve Arreglo(Arreglo+10)

Material de estudio Página: 41 de 249


Visual Basic 6.0 y SQLServer 7.0

1.8 Funciones internas de VB

Funciones de Cadenas de caracteres y de Fecha

Aunque un juego de caracteres de doble byte consiste en un byte de cabecera y un byte de


cola y requiere dos bytes consecutivos de almacenamiento, debe tratarlo como una única
unidad en cualquier operación relacionada con caracteres o cadenas. Varias funciones de
manipulación de cadenas controlan de forma apropiada todas las cadenas, incluidos los
caracteres DBCS, con base en el caracter.
Estas funciones tienen una versión ANSI/DBCS y una versión binaria o versión Unicode,
como se muestra en la tabla siguiente. Utilice las funciones apropiadas dependiendo del
propósito de la manipulación de cadenas.
Las versiones "B" de las funciones de la tabla siguiente se diseñaron para utilizarlas con
cadenas de datos binarios. Las versiones "W" se diseñaron para utilizarlas con cadenas
Unicode.

Función Descripción
Asc Devuelve el código de carácter ANSI o DBCS del primer carácter de una
cadena.
AscB Devuelve el valor del primer byte de la cadena dada que contiene datos
binarios.
AscW Devuelve el código de carácter Unicode del primer carácter de una
cadena.
Chr Devuelve una cadena que contiene un código de carácter ANSI o DBCS
específico.
ChrB Devuelve una cadena binaria que contiene un byte específico.
ChrW Devuelve una cadena que contiene un código de carácter Unicode
específico.
Input Devuelve desde un archivo un número de caracteres ANSI o DBCS
especificados.
InputB Devuelve desde un archivo un número de bytes especificados.
InStr Devuelve la primera ocurrencia de una cadena dentro de otra.
InStrB Devuelve la primera ocurrencia de un byte en una cadena binaria.
Left, Devuelve un número de caracteres especificado desde la parte izquierda
Right o derecha de una cadena.
LeftB, Devuelve un número de bytes especificado desde la parte izquierda o
RightB derecha de una cadena binaria.
Len Devuelve la longitud de la cadena en número de caracteres.
LenB Devuelve la longitud de la cadena en número de bytes.
Mid Devuelve un número especificado de caracteres de una cadena.
MidB Devuelve un número especificado de bytes de una cadena binaria.

Las funciones sin una "B" o "W" de esta tabla controlan correctamente los caracteres DBCS y
ANSI. Además de las funciones anteriores, la función String controla los caracteres DBCS.
Esto significa que todas estas funciones consideran un carácter DBCS como un único
carácter, incluso si se compone de 2 bytes.
El comportamiento de estas funciones es diferente cuando controlan caracteres SBCS y
DBCS. Por ejemplo, la función Mid se utiliza en Visual Basic para devolver un número
especificado de caracteres de una cadena. En las configuraciones regionales que utilizan
DBCS, el número de caracteres y el número de bytes no son necesariamente el mismo. En
estos casos Mid sólo devolvería el número de caracteres, no el de bytes.

Material de estudio Página: 42 de 249


Visual Basic 6.0 y SQLServer 7.0

En la mayoría de los casos, utilice las funciones basadas en caracteres cuando quiera
controlar los datos de cadenas, ya que estas funciones pueden tratar correctamente las
cadenas ANSI, las cadenas DBCS y las cadenas Unicode.
Las funciones de manipulación de cadenas basadas en bytes, como LenB y LeftB, se
proporcionan para controlar los datos de las cadenas como datos binarios. Cuando almacena
caracteres en una variable String u obtiene los caracteres de una variable String, Visual
Basic convierte automáticamente los caracteres Unicode a ANSI. Cuando quiera controlar los
datos binarios, utilice matrices Byte en lugar de variables String y las funciones de
manipulación de cadenas basadas en bytes.
Para obtener más información Busque la función apropiada en la Referencia del lenguaje
de los Libros en pantalla.

Si quiere controlar cadenas de datos binarios, puede asignar los caracteres de una cadena
con una matriz Byte si utiliza el código siguiente:
Dim MiCadenaDeBytes() As Byte
' Asigna la cadena con una matriz Byte.
MiCadenaDeBytes = "ABC"
' Presenta los datos binarios.
For i = LBound(MiCadenaDeBytes) to UBound(MiCadenaDeBytes)
Print Right(" " + Hex(MiCadenaDeBytes(i)),2) + " ,";
Next
Print

Conversión de cadenas DBCS


Visual Basic proporciona varias funciones de conversión cadenas que son útiles para los
caracteres DBCS: StrConv, UCase y LCase.

Función StrConv
Las opciones globales de la función StrConv son convertir mayúsculas en minúsculas y
viceversa. Además de estas opciones, la función tiene varias opciones específicas para
DBCS. Por ejemplo, puede convertir letras estrechas en letras anchas si especifica vbWide
en el segundo argumento de esta función. Puede convertir un tipo de carácter en otro, como
hiragana en katakana en japonés.
También puede utilizar la función StrConv para convertir caracteres Unicode en caracteres
ANSI/DBCS y viceversa. Normalmente, una cadena de Visual Basic está compuesta por
caracteres Unicode. Cuando necesite tratar cadenas ANSI/DBCS (por ejemplo, para calcular
el número de bytes de una cadena antes de escribir la cadena en un archivo), puede utilizar
esta capacidad de la función StrConv.

Conversión de mayúsculas y minúsculas en letras anchas


Puede convertir mayúsculas a minúsculas y viceversa si utiliza la función StrConv con
vbUpperCase o vbLowerCase o mediante las funciones UCase o LCase. Cuando utiliza
estas funciones, las letras anchas en inglés de DBCS también se convierten como caracteres
ANSI.

Material de estudio Página: 43 de 249


Visual Basic 6.0 y SQLServer 7.0

NOTA:

Visual Basic utiliza Unicode para almacenar y manipular cadenas. Unicode es un juego de
caracteres en el que se emplean 2 bytes para representar cada carácter. Algunos otros
programas, como la API de Windows 95 y 98, utilizan ANSI (American National Standards
Institute) o DBCS para almacenar y manipular cadenas. Cuando mueva cadenas fuera de
Visual Basic, puede que encuentre diferencias entre Unicode y ANSI/DBCS. En la tabla
siguiente se muestran los juegos de caracteres ANSI, DBCS y Unicode en diferentes
entornos.

Entorno Juego o juegos de caracteres utilizado


Visual Basic Unicode
Bibliotecas de objetos de 32 bits Unicode
Bibliotecas de objetos de 16 bits ANSI y DBCS
API de Windows NT Unicode
Automatización en Windows NT Unicode
API de Windows 95 ANSI y DBCS
Automatización en Windows 95 Unicode

ANSI
ANSI es el juego de caracteres estándar más utilizado por los equipos personales. Como el
estándar ANSI sólo utiliza un byte para representar un carácter, está limitado a un máximo de
256 caracteres y signos de puntuación. Aunque es adecuado para el inglés, no acepta
totalmente muchos otros idiomas.

DBCS
DBCS se utiliza en los sistemas Microsoft Windows que se distribuyen en la mayor parte de
Asia. Proporciona soporte para muchos alfabetos de Asia Oriental, como el chino, el japonés
y el coreano. DBCS utiliza los números de 0 a 128 para representar el juego de caracteres
ASCII. Algunos números mayores de 128 funcionan como caracteres de cabecera, que no
son realmente caracteres sino simples indicadores de que el valor siguiente es un carácter de
un juego de caracteres no occidental. En DBCS, los caracteres ASCII tienen una longitud de 1
byte, mientras que los caracteres japoneses, coreanos y de otros países de Asia Oriental
tienen una longitud de 2 bytes.

Unicode
Unicode es un esquema de codificación de caracteres que utiliza 2 bytes por cada carácter.
ISO (International Standards Organization) define un número dentro del intervalo 0 a 65.535
16
(2 – 1) por cada carácter y símbolo de cada idioma (más algunos espacios vacíos para
futuras ampliaciones). En todas las versiones de 32 bits de Windows, el Modelo de objetos
componentes (COM), que es la base de las tecnologías OLE y ActiveX, utiliza Unicode.
Unicode es totalmente compatible con Windows NT. Aunque Unicode y DBCS tienen
caracteres de doble byte, los esquemas de codificación son completamente diferentes.

Material de estudio Página: 44 de 249


Visual Basic 6.0 y SQLServer 7.0

La tabla siguiente identifica los caracteres que puede utilizar para crear formatos de
fecha/hora definidos por el usuario:
Carácter Descripción
(:) Separador de hora. En algunas configuraciones regionales, se pueden utilizar
otros caracteres para representar el separador de hora. El separador de hora
separa las horas, los minutos y los segundos cuando se da formato a los valores
de hora. El carácter real que se utiliza como separador de hora en la salida con
formato viene determinado por las configuraciones del sistema.
(/) Separador de fecha. En algunas configuraciones regionales se pueden utilizar
otros caracteres para representar el separador de fecha. El separador de fecha
separa el día, el mes y el año cuando se da formato a los valores de fecha. El
carácter real que se utiliza como separador de fecha en la salida con formato
viene determinado por las configuraciones del sistema.
c Muestra la fecha como ddddd y la hora como ttttt, en este orden. Sólo se
muestra información de fecha si no hay parte fraccionaria en el número de serie
de la fecha; sólo se muestra información de hora si no hay una parte entera.
d Muestra el día como un número sin un cero a la izquierda (1 – 31).
dd Muestra el día como un número con un cero a la izquierda (01 – 31).
ddd Muestra el día como abreviatura (Dom – Sáb).
dddd Muestra el día como nombre completo (Domingo – Sábado).
ddddd Muestra la fecha como fecha completa (incluyendo el día, el mes y el año), con el
formato de acuerdo a la configuración de formato de fecha corta del sistema. En
Microsoft Windows, el formato predeterminado de fecha corta para Inglés – U.S.
es m/d/aa, aunque cambia según la configuración regional.
dddddd Muestra un número de serie de fecha como fecha completa (incluyendo el día, el
mes y el año), con el formato de acuerdo a la configuración de formato de fecha
larga reconocido por el sistema. En Microsoft Windows, el formato
predeterminado de fecha larga para Inglés-US es mmmm dd, aaaa, aunque
cambia según la configuración regional.
w Muestra el día de la semana como un número (1 para Domingo hasta 7 para
Sábado).
ww Muestra la semana del año como un número (1 – 54).
m Muestra el mes como un número sin un cero a la izquierda (1 – 12). Si m
sigue inmediatamente a h o hh, se muestra el minuto en lugar del mes.
mm Muestra el mes como un número con un cero a la izquierda (01 –
12). Si m sigue inmediatamente a h o hh, se muestra el minuto en lugar
del mes.
mmm Muestra el mes como una abreviatura (Ene – Dic).
mmmm Muestra el mes como nombre de mes completo (Enero –Diciembre).
q Muestra el trimestre del año como un número (1 – 4).
y Muestra el día del año como un número (1 – 366).
yy Muestra el año como un número de dos dígitos (00 – 99).
yyyy Muestra el año como un número de cuatro dígitos (100 – 9999).
h Muestra la hora como un número sin ceros a la izquierda (0 – 23).
hh Muestra la hora como un número con ceros a la izquierda (00 – 23).
n Muestra el minuto como un número sin ceros a la izquierda (0 – 59).

Carácter Descripción
nn Muestra el minuto como un número con ceros a la izquierda (00 –

Material de estudio Página: 45 de 249


Visual Basic 6.0 y SQLServer 7.0

59).
s Muestra el segundo como un número sin ceros a la izquierda (0 –
59).
ss Muestra el segundo como un número con ceros a la izquierda (00 –
59).
ttttt Muestra una hora con formato completo (incluyendo hora, minutos y segundos),
utilizando el separador de hora definido por el formato de hora reconocido por el
sistema. Se muestra un cero a la izquierda si está seleccionada la opción de cero
a la izquierda y la hora es antes de 10:00 AM o PM En Microsoft Windows, el
formato predeterminado de hora es h:mm:ss.
AM/PM Utilice el reloj de 12 horas para mostrar AM en mayúsculas con cualquier hora
antes del mediodía; y mostrar PM en mayúsculas con cualquier hora entre el
mediodía y 11:59 P.M.

Material de estudio Página: 46 de 249


Visual Basic 6.0 y SQLServer 7.0

am/pm Utilice el reloj de 12 horas para mostrar am en minúsculas con cualquier hora
antes del mediodía; y mostrar pm en minúsculas con cualquier hora entre el
mediodía y 11:59 P.M.
A/P Utilice el reloj de 12 horas para mostrar A en mayúsculas con cualquier hora
antes del mediodía; y mostrar P en mayúsculas con cualquier hora entre el
mediodía y 11:59 P.M.
a/p Se utiliza el reloj de 12 horas y muestra A en minúsculas con cualquier hora antes
del mediodía; muestra P en minúsculas con cualquier hora entre el mediodía y
11:59 P.M.
AMPM Utilice el reloj de 12 horas para mostrar el literal de cadena AM como lo defina el
sistema con cualquier hora antes del mediodía; y mostrar el literal de cadena PM
como lo defina el sistema con cualquier hora entre el mediodía y 11:59 P.M.
AMPM puede estar en mayúsculas o en minúsculas, pero las mayúsculas o
minúsculas en la cadena que resulta se corresponden con la cadena definida por
las configuraciones del sistema. En Microsoft Windows, el formato
predeterminado es AM/PM.

Los siguientes son ejemplos de formatos de fecha y hora definidos por el usuario para el 6 de
diciembre de 1999:
Formato Muestra
m/d/aa 12/7/99
d-mmm 7-Dic
d-mmmm-aa 7-Diciembre-99
d mmmm 7 Diciembre
mmmm aa Diciembre 99
hh:mm AM/PM 08:50 PM
h:mm:ss a/p 8:50:35 p
h:mm 20:50
h:mm:ss 20:50:35
m/d/aa h:mm 12/7/99 20:50

Material de estudio Página: 47 de 249


Visual Basic 6.0 y SQLServer 7.0

1.9 Eventos, propiedades y Controles

El primer paso para construir una aplicación en Visual Basic, es dibujar el objeto. Para esta
primera aplicación, usaremos tres controles del ToolBox.

Control Nombre

TextBox (caja de Textos)

Command Button (Botón de Comando)

• Para dibujar un control usando el Toolbox.

1. Hacer click en el control que se desea. Utilizar en este caso, el de Text Box
2. Mover el apuntador dentro de la Forma. Ver figura

3. Hacer click en la Forma con el botón izquierdo del mouse. Sin soltar el botón, arrastrar el
objeto.
4. Soltar el botón del mouse

De esta manera, el control aparece en la Forma.

Material de estudio Página: 48 de 249


Visual Basic 6.0 y SQLServer 7.0

Un simple camino para añadir un control dentro de la Forma, es hacer doble-click en el icono del
control del ToolBox: entonces se crea un control localizado en el centro de la Forma, con tamaño
normal.

• Para cambiar el tamaño de un control.

1. Seleccionar el control, el cual se desea cambiar de tamaño, haciendo click con el mouse.
2. Posicionar el apuntador en la esquina donde se desea cambiar el tamaño, tomarlo y
arrastrarlo con el mouse.
3. Soltar el mouse.

• Para mover un control.

1. Posicionar el apuntador del mouse en el control que se desea mover, y tomar el control
con el mouse.
2. Arrastrar el control a la nueva localización.
3. Soltar el mouse.

Colocación de Propiedades
La Ventana de Propiedades (Properties) provee un fácil camino, para la determinación de las
Propiedades de todos los objetos de la Forma. Para abrir la Ventana de Propiedades, se puede:
seleccionar desde el menú de Windows; hacer click en el botón de Propiedades en el Toolbar ó
bien, presionar la tecla F4.

Ventana
de Lista de
propiedad objetos
es

Propiedades 1.5 Ventana de

Descripció
Propiedades n breve de
(Properties Window) la
propiedad

Material de estudio Página: 49 de 249


Visual Basic 6.0 y SQLServer 7.0

La Ventana de Propiedades consiste de los siguientes elementos:

• Object Box.- Despliega el nombre del objeto al cual se determinan las propiedades. Al hacer
click en la flecha de la derecha de la caja, se puede seleccionar una Forma ó cualquier control
que se encuentre dentro de la Forma actual.
• Setting Box.- Permite editar la colocación, para la propiedad seleccionada en la lista de
propiedades. Alguna colocación puede ser cambiada, haciendo click en la flecha a la derecha
de la caja: esta despliega una lista de opciones, y puede seleccionarse alguna.
• Properties list.- La columna izquierda despliega la lista de propiedades que posee el objeto.
La columna derecha determina la colocación de cada propiedad.

Para completar el ejemplo anterior, donde se despliega el mensaje "Mi Primera Aplicación"; se
necesita cambiar a los objetos, las siguientes propiedades:

Objetos Propiedades Setting


Form Caption Mi primera Aplicación
Text Box Text (Vacío)
Text Box FontName Arial
Text Box FontSize 16
Command1 Button Caption OK

Para continuar con el ejemplo, añadir un segundo Command Button (Botón de comando) y
colocar la siguiente propiedad:

Command2 Button Caption Exit

Escribiendo Código
La Ventana de código, es donde se escribe el código de Visual Basic para la aplicación. El
código consiste del lenguaje de declaraciones y constantes. Usando la Ventana de código, se
puede escribir rápidamente el código en la aplicación.

• Para abrir la Ventana de código.


• Hacer doble-click en la Forma ó el control que está dentro de la Forma a la que se desea
escribir el código.
• También se puede dentro de la Ventana de Proyectos, seleccionando el nombre de la
Forma y seleccionando el botón View Code.

Material de estudio Página: 50 de 249


Visual Basic 6.0 y SQLServer 7.0

La Ventana de código incluye los siguientes elementos:

• Object Box.- Despliega el nombre del objeto seleccionado. Haciendo click en la flecha que
se encuentra al lado derecho de la caja, se despliega una lista de todos los objetos
asociados con esta Forma.

• Procedure List Box.- Lista los procedimientos para un objeto. La caja despliega el nombre
del procedimiento seleccionado; en este caso, Click. Seleccionando la flecha a la derecha
de la caja, se despliega la lista de todos los procedimientos para el objeto.

El código, en una aplicación de Visual Basic; es dividido en pequeños bloques llamados


procedimientos (procedures). Un event procedure, como el que se creó anteriormente; contiene
código que es ejecutado cuando ocurre un evento (como hacer click en el botón).

• Para crear un event procedure

1. En el Object Box, se selecciona el nombre de un objeto en la Forma que se encuentra


activada, para continuar con el ejemplo anterior y seleccionar el command button,
Command1.
2. En el Procedure List box, se selecciona el nombre de un evento para el objeto
seleccionado.

Aquí, el procedimiento Click ya fue seleccioando. Éste es el procedimiento default para


los command buttons.

3. Escribir el siguiente código entre la declaración Sub y End Sub:

Para el Command Button, Command1 escribir:

Form1.BackColor = QBColor(Rnd * 15)


Text1.Text = "Mi Primera Aplicación"
Text1.BackColor = QBColor(Rnd * 15)
Text1.FontSize = 16
Text1.FontName = "Arial"

El event procedure de Command1, se ve así:

Sub Command1_Click()
Form1.BackColor = QBColor(Rnd * 15)
Text1.Text = "Mi Primera Aplicación"
Text1.BackColor = QBColor(Rnd * 15)
Text1.FontSize = 16
Text1.FontName = "Arial"
End Sub

Para el Command Button, Command2 escribir: End

Sub Command2_Click()
End
End Sub

Material de estudio Página: 51 de 249


Visual Basic 6.0 y SQLServer 7.0

La sintaxis para este ejemplo, es tomada desde object.property = setting. Se puede usar esta
sintaxis para Formas y controles en la ocurrencia de eventos, mientras la aplicación está
corriendo.

Control ComboBox

Un control ComboBox combina las características de un control TextBox y un control


ListBox; los usuarios pueden introducir información en la parte del cuadro de texto o
seleccionar un elemento en la parte de cuadro de lista del control.

Comentarios
Para agregar o eliminar elementos en un control ComboBox, use el método AddItem o
RemoveItem. Establezca las propiedades List, ListCount y ListIndex para permitir a un
usuario tener acceso a los elementos de un control ComboBox. Como alternativa, puede
agregar elementos a la lista mediante la propiedad List en tiempo de diseño.
Nota Un evento Scroll ocurrirá en un control ComboBox sólo cuando se desplace el
contenido de la parte desplegable del ComboBox, no cada vez que cambie el contenido del
ComboBox. Por ejemplo, si la parte desplegable de un ComboBox contiene cinco elementos
y el elemento superior está resaltado, no ocurrirá un evento Scroll hasta que presione seis
veces la flecha hacia abajo (o una vez la tecla AV PÁG). Después de eso, ocurrirá un evento
Scroll por cada pulsación de la tecla de flecha hacia abajo. Sin embargo, si después presiona
la tecla de flecha hacia arriba, no ocurrirá un evento Scroll hasta que presione seis veces la
tecla de flecha hacia arriba (o una vez la tecla RE PÁG). Después de eso, cada vez que
presione la tecla de flecha hacia arriba se producirá un evento Scroll.

Eventos
Evento Change Evento LostFocus
Evento Click Evento OLECompleteDrag
Evento DblClick Evento OLEDragDrop
Evento DragDrop Evento OLEDragOver
Evento DragOver Evento OLEGiveFeedback
Evento DropDown OLESetData Event
Evento GotFocus Evento OLEStartDrag
Eventos KeyDown y KeyUp Evento Scroll
Evento KeyPress

Métodos
Método AddItem Método Refresh
Método Clear (Clipboard, ComboBox, Método RemoveItem
ListBox)
Método Drag Método SetFocus
Método Move Método ShowWhatsThis
Método OLEDrag Método ZOrder

Propiedades
Propiedad Appearance Propiedad ListIndex
Propiedades BackColor y ForeColor Propiedad Locked
Propiedad Container Propiedad MouseIcon

Material de estudio Página: 52 de 249


Visual Basic 6.0 y SQLServer 7.0

Propiedad DataChanged Propiedad MousePointer


Propiedad DataField Propiedad Name
Propiedad DragIcon Propiedad NewIndex
Propiedad DragMode Propiedad OLEDragMode
Propiedad Enabled Propiedad OLEDropMode
Propiedad Font Propiedad Parent
Propiedades FontBold, FontItalic, Propiedades SelLength, SelStart y SelText
FontStrikethru y FontUnderline
Propiedad FontName Propiedades SelLength, SelStart y SelText
(Controles ActiveX)
Propiedad FontSize Propiedad Sorted
Propiedades Height y Width Propiedad Style
Propiedad HelpContextID Propiedad TabIndex
Propiedad hWnd Propiedad TabStop
Propiedad Index (Control Array) Propiedad Tag
Propiedad IntegralHeight Propiedad Text
Propiedad ItemData Propiedad ToolTipText
Propiedades Left y Top Propiedad TopIndex
Propiedad List Propiedad Visible
Propiedad ListCount Propiedad WhatsThisHelpID

Material de estudio Página: 53 de 249


Visual Basic 6.0 y SQLServer 7.0

Cuándo debe utilizar un cuadro combinado(ComboBox) en lugar de un


cuadro de lista (ListBox)
Generalmente, el ComboBox es el apropiado cuando hay una lista de opciones sugeridas y
el cuadro de lista es el apropiado cuando desea limitar la entrada a las opciones de la lista.
Un ComboBox contiene un campo de edición, de forma que en este campo se pueden
introducir opciones que no figuran en la lista.
Además, los cuadros combinados ahorran espacio en los formularios. Como la lista completa
no se presenta hasta que el usuario hace clic en la flecha abajo (excepto en el Estilo 1, donde
siempre se presenta), un ComboBox puede ocupar un espacio reducido, en el que no cabría
un cuadro de lista.

Características de enlace a datos


Visual Basic incluye versiones estándar y enlazadas a datos del control ComboBox. Si bien
las dos versiones permiten presentar, modificar y actualizar la información en la mayoría de
los tipos de bases de datos estándar, el ComboBox enlazado a datos proporciona
características más avanzadas de acceso a datos. El control DBCombo acepta además un
conjunto de propiedades y métodos diferente al del control ComboBox estándar.
Para obtener más información Para obtener más información, vea "Uso del cuadro de lista
y el ComboBox enlazados a datos", en "Tener acceso a datos".

Estilos de cuadros combinados


Hay tres estilos de cuadros combinados. Cada estilo puede establecerse en tiempo de diseño
o en tiempo de ejecución y, para establecer el estilo del ComboBox, se utilizan valores o
constantes equivalentes de Visual Basic.

Estilo Valor Constante


ComboBox desplegable 0 vbComboDropDown
ComboBox simple 1 vbComboSimple
ComboBox desplegable 2 vbComboDropDownList

ComboBox desplegable
Con el valor predeterminado (Style = 0 – ComboDropDown), un ComboBox es un
ComboBox desplegable. El usuario puede escribir texto directamente (como en un cuadro de
texto) o hacer clic en la flecha de la parte derecha del ComboBox para abrir una lista de
opciones. Si selecciona una de las opciones, se inserta en el cuadro de texto de la parte
superior del ComboBox. El usuario también puede abrir la lista mediante la combinación de
teclas ALT+ FLECHA ABAJO, cuando el control tiene el enfoque.

ComboBox simple
Si establece la propiedad Style de un ComboBox a 1 – ComboSimple, especifica un
ComboBox simple en el que la lista se presenta siempre. Para presentar todas las entradas
de la lista, debe dimensionar el cuadro de lista de forma que quepan. Cuando hay más
entradas de las que se pueden presentar se agrega automáticamente una barra de
desplazamiento. El usuario también puede escribir texto directamente o seleccionar una

Material de estudio Página: 54 de 249


Visual Basic 6.0 y SQLServer 7.0

opción de la lista. Al igual que el ComboBox desplegable, el ComboBox simple permite que
los usuarios escriban opciones que no figuran en la lista.

ComboBox de lista desplegable


Un cuadro de lista desplegable (Style = 2 – ComboDropDownList) es como un cuadro de
lista normal: presenta una lista de elementos entre los que el usuario tiene que elegir. Sin
embargo, a diferencia de los cuadros de lista, la lista no se presenta hasta que se hace clic en
la flecha de la derecha del cuadro. La principal diferencia entre este estilo y el ComboBox
desplegable es que el usuario no puede escribir en el cuadro, sólo puede seleccionar un
elemento de la lista. Utilice este tipo de cuadro de lista cuando no disponga de mucho
espacio.

Agregar elementos
Para agregar elementos a un ComboBox, utilice el método AddItem, que tiene la sintaxis
siguiente:
Objeto.AddItem elemento[, índice]

Argumento Descripción
Objeto Nombre del ComboBox la lista o del cuadro.
elemento Expresión de cadena que va a agregar a la lista. Si elemento es una constante
literal, tiene que ir entre comillas.
índice Especifica dónde va a insertar el nuevo elemento dentro de la lista. Un índice de 0
representa la primera posición. Si se omite el argumento índice, el elemento se
inserta al final (o en el orden establecido).

Aunque los elementos de la lista se suelen agregar en los procedimientos de evento


Form_Load, puede utilizar el método AddItem en cualquier momento. Esto le ofrece la
posibilidad de agregar elementos a la lista de forma dinámica (como respuesta a acciones del
usuario).
El siguiente código inserta "Chardonnay”, "Fumé Blanc”, "Gewürztraminer” y "Zinfandel" en un
ComboBox llamado Combo1 con la propiedad Style establecida a 0 (vbComboDropDown):
Private Sub Form_Load ()
Combo1.AddItem "Chardonnay"
Combo1.AddItem "Fumé Blanc"
Combo1.AddItem "Gewürztraminer"
Combo1.AddItem "Zinfandel"
End Sub

Cuando se carga el formulario en tiempo de ejecución y el usuario hace clic en la flecha hacia
abajo, aparece la lista, como se muestra en la figura 7.8.
Figura 7.8 El ComboBox "Lista de vinos"

Agregar elementos en tiempo de diseño


También puede insertar elementos en la lista en tiempo de diseño si establece la propiedad
List en la ventana Propiedades del control ComboBox. Cuando selecciona la propiedad List
y después hace clic en la flecha hacia abajo, puede escribir un elemento de la lista y después
presionar la combinación de teclas CTRL+ENTRAR para empezar otra línea.

Material de estudio Página: 55 de 249


Visual Basic 6.0 y SQLServer 7.0

Sólo puede agregar elementos al final de la lista. De esta forma, si desea ordenar la lista
alfabéticamente, tiene que establecer la propiedad Sorted a True. Para obtener más
información, consulte "Ordenación de una lista", más adelante en este mismo tema.

Agregar un elemento en una posición especificada


Para agregar un elemento a una lista en una posición determinada, especifique un valor de
índice detrás del nuevo elemento. Por ejemplo, la siguiente línea de código inserta "Pinot
Noir" en la primera posición y desplaza los demás elementos hacia abajo:
Combo1.AddItem "Pinot Noir", 0

Observe que el valor que especifica el primer elemento de una lista es 0 y no 1.

Ordenación de una lista


Puede establecer que los elementos se agreguen a la lista en orden alfabético si establece la
propiedad Sorted a True y omite el índice. El orden no distingue entre mayúsculas y
minúsculas; por tanto, las palabras "chardonnay" y "Chardonnay" reciben el mismo
tratamiento.
Cuando la propiedad Sorted está establecida a True, el uso del método AddItem con un
argumento índice puede producir resultados impredecibles y desordenados.

Quitar elementos
Para quitar elementos de un ComboBox puede utilizar el método RemoveItem, que tiene un
argumento, índice, que especifica el elemento que va a quitar:
Objeto.RemoveItem índice

Los argumentos Objeto e índice son iguales que para AddItem.


Por ejemplo, para quitar la primera entrada de una lista utilizaría la siguiente línea de código:
Combo1.RemoveItem 0

Para quitar todas las entradas de un ComboBox, utilice el método Clear:


Combo1.Clear

Obtención del contenido de la lista con la propiedad Text


Normalmente, la manera más sencilla de obtener el valor del elemento seleccionado
actualmente es utilizar la propiedad Text. Esta propiedad se corresponde con el contenido de
la parte de cuadro de texto del control en tiempo de ejecución. Puede ser un elemento de la
lista o una cadena de texto escrita por el usuario en el cuadro de texto.
Por ejemplo, el código siguiente presenta información acerca de Chardonnay si un usuario
selecciona "Chardonnay" en el cuadro de lista:
Private Sub Combo1_Click ()
If Combo1.Text = "Chardonnay" Then
Text1.Text = "Chardonnay es un vino blanco _
ligeramente embocado."
End If
End Sub

Material de estudio Página: 56 de 249


Visual Basic 6.0 y SQLServer 7.0

La propiedad Text contiene el elemento seleccionado actualmente en el cuadro de lista


Combo1. El código comprueba si se ha seleccionado "Chardonnay" y, si es así, presenta la
información en el cuadro de texto.

Acceso a los elementos de la lista con la propiedad List


La propiedad List proporciona acceso a todos los elementos de la lista. Esta propiedad
contiene una matriz en la que cada elemento de la lista es un elemento de la matriz. Cada
elemento está representado en forma de cadena de texto. Para hacer referencia a un
elemento de la lista, utilice esta sintaxis:
cuadro.List(índice)

El argumento cuadro es una referencia a un ComboBox e índice es la posición del elemento.


El primer elemento tiene un índice 0, el siguiente tiene un índice 1 y así sucesivamente. Por
ejemplo, la instrucción siguiente presenta el tercer elemento (índice = 2) de una lista en un
cuadro de texto:
Text1.Text = Combo1.List(2)

Determinación de la posición con la propiedad ListIndex


Si desea saber la posición del elemento seleccionado en la lista de un ComboBox, utilice la
propiedad ListIndex. Esta propiedad establece o devuelve el índice del elemento
seleccionado actualmente en el control y sólo está disponible en tiempo de ejecución. Al
establecer la propiedad ListIndex en un control ComboBox, también se genera un evento
Click en dicho control.
El valor de esta propiedad es 0 si está seleccionado el primer elemento, 1 si es el siguiente y
así sucesivamente. ListIndex es – 1 si no hay ningún elemento seleccionado o si el usuario
escribe una opción en el ComboBox (Style 0 ó 1) en vez de seleccionar un elemento de la
lista.
Nota La propiedad NewIndex permite conocer el índice del último elemento agregado a la
lista. Puede ser útil cuando se inserta un nuevo elemento en una lista ordenada.

Obtención del número de elementos con la propiedad ListCount


Para obtener el número de elementos de un ComboBox, utilice la propiedad ListCount. Por
ejemplo, la instrucción siguiente utiliza esta propiedad para determinar el número de entradas
de un ComboBox:
Text1.Text = "Hay " & Combo1.ListCount & " _
entradas en la lista"

Material de estudio Página: 57 de 249


Visual Basic 6.0 y SQLServer 7.0

Propiedad: ItemData
Devuelve o establece un número específico para cada elemento de un control ComboBox o
ListBox.

Sintaxis
Objeto.ItemData(índex) [= número]

La sintaxis de la propiedad ItemData consta de las siguientes partes:


Parte Descripción
Objeto Una expresión de objeto que da como resultado un objeto de la lista Aplicable a.
Índice El número de un elemento concreto del objeto.
Número El número que se asocia con el elemento especificado.

Comentarios
La propiedad ItemData es una matriz de valores enteros largos cuyo número de elementos es
el valor de la propiedad List de un control. Puede utilizar los números asociados con cada
elemento para identificar los elementos. Por ejemplo, puede usar un número de identificación
de empleado para identificar cada nombre de empleado de un control ComboBox o ListBox.
Cuando llena el Objeto, también se llenan los elementos correspondientes de la matriz
ItemData con los números de empleado.
La propiedad ItemData se usa a menudo como índice de una matriz de estructuras de datos
asociadas con los elementos de un control.
Nota Cuando inserta un elemento en una lista con el método AddItem, el elemento también
se inserta automáticamente en la matriz ItemData. Sin embargo, el valor no se reinicia a cero;
conserva el valor que había en esa posición antes agregar el elemento a la lista. Cuando use
la propiedad ItemData, asegúrese de establecer su valor al agregar nuevos elementos a la
lista.

El siguiente ejemplo adiciona elementos (empleados y número de identificación)

Private Sub Form_Load ()


' Llena el Combo1 y la matriz ItemData con los
' Elementos correspondientes ordenados.
Combo1.AddItem "José Vargas"
Combo1.ItemData(Combo1.NewIndex) = 1000
Combo1.AddItem "Rosa Reyes"
Combo1.ItemData(Combo1.NewIndex) = 2000
Combo1.AddItem "Mauro Sorrento"
Combo1.ItemData(Combo1.NewIndex) = 3000
Combo1.AddItem "Alvaro Dominguez"
Combo1.ItemData(Combo1.NewIndex) = 4000
End Sub
Private Sub Combo1_Click ()
' Agrega el número y el nombre del empleado.
Dim Msg As String
Msg = "El empleado:" & Combo1.List(Combo1.ListIndex)
Msg = Msg & " tiene el número: " & _
Combo1.ItemData(Combo1.ListIndex)
MsgBox Msg, vbInformation + vbOKOnly, "Aviso"
End Sub

Material de estudio Página: 58 de 249


Visual Basic 6.0 y SQLServer 7.0

1.10 Control de Errores


Un controlador de errores es una rutina para interceptar y responder a los errores de la
aplicación. Querrá agregar controladores de error a cualquier procedimiento en el que prevea
la posibilidad de un error (debería asumir que todas las instrucciones de Basic pueden
producir un error a menos que sepa explícitamente que no va a ser así). El proceso de diseño
de un controlador de errores implica tres pasos:
1. Establecer o activar, la interceptación de errores indicando a la aplicación hacia dónde se
debe bifurcar (qué rutina de tratamiento de errores debe ejecutar) cuando se produce un
error.
La instrucción On Error activa la interceptación y dirige la aplicación a la etiqueta que
marca el principio de una rutina de tratamiento de errores.

2. Escribir una rutina de tratamiento de errores que responda a cualquier error que pueda
prever. Si el control se bifurca realmente en la interceptación en algún punto, se dice que la
interceptación está activa.

3. Salir de la rutina de tratamiento de errores.


En el caso del error "El disco no está listo", la instrucción Resume crea la bifurcación del
código en la instrucción en la que se produjo el error. Entonces, Visual Basic intenta volver
a ejecutar esa instrucción. Si la situación no ha cambiado, se produce otro error y la
ejecución vuelve a la rutina de tratamiento de errores.

Establecimiento de la interceptación de errores


La interceptación de errores está activada cuando Visual Basic ejecuta la instrucción On
Error, que especifica un controlador de errores. La interceptación de errores permanece
activada mientras el procedimiento que lo contiene esté activo; es decir, hasta que se ejecute
una instrucción Exit Sub, Exit Function, Exit Property, End Sub, End Function o End
Property para ese procedimiento. Aunque sólo puede haber una interceptación de errores
activada a la vez en cualquier procedimiento dado, puede crear varias interceptaciones de
error alternativas y activar distintas interceptaciones en momentos diferentes. También puede
desactivar una interceptación de errores usando un caso especial de la instrucción On Error
con On Error GoTo 0.
Para establecer una interceptación de errores que salte a una rutina de tratamiento de
errores, use una instrucción On Error GoTo línea, donde línea es la etiqueta que identifica el
código de tratamiento de errores. En la función de ejemplo FileExists, la etiqueta es
CheckError. (A pesar de que el signo de dos puntos forma parte de la etiqueta, no se utiliza
en la instrucción On Error GoTo línea).

Escritura de una rutina de tratamiento de errores


El primer paso para escribir una rutina de tratamiento de errores es agregar una etiqueta de
línea para marcar el principio de una rutina de tratamiento de errores. La etiqueta de línea
debe tener un nombre descriptivo y debe ir seguida por un signo de dos puntos. Una
convención común es colocar el código de tratamiento de errores al final del procedimiento
con una instrucción Exit Sub, Exit Function o Exit Property inmediatamente delante de la
etiqueta de línea. Esto permite que el procedimiento evite la ejecución de código de
tratamiento de errores si no se produce ningún error.

Material de estudio Página: 59 de 249


Visual Basic 6.0 y SQLServer 7.0

El cuerpo de la rutina de tratamiento de errores contiene el código que realmente trata el


error, normalmente en forma de una instrucción Case o If…Then…Else. Necesita determinar
qué errores es probable que se produzcan y proporcionar una acción para cada uno; por
ejemplo, pedir al usuario que inserte un disco en caso de que se produzca un error "El disco
no está listo". Se debe proporcionar siempre una opción para tratar cualquier error
inesperado, mediante la cláusula Else o Case Else.
La propiedad Number del objeto Err contiene un código numérico que representa el error de
tiempo de ejecución más reciente. Si usa el objeto Err junto con la instrucción Select Case o
If...Then...Else, puede llevar a cabo una acción específica para cualquier error que se
produzca.
Nota La cadena contenida en la propiedad Description del objeto Err explica el error
asociado al número de error actual. El texto exacto de la descripción puede variar de una
versión de Microsoft Visual Basic a otra. Por tanto, use Err.Number en vez de
Err.Description para identificar el error específico que se ha producido.

Salida de una rutina de tratamiento de errores


Hay varias formas de salir de una rutina de tratamiento de errores. Dependiendo de las
circunstancias, puede hacerlo mediante una de las instrucciones que se muestran en la
siguiente tabla.
Instrucción Descripción

Resume [0] La ejecución del programa se reanuda con la instrucción que causó el error o la
última llamada que haya realizado el procedimiento que contenga la rutina de
tratamiento de errores. Úsela para repetir una operación después de corregir la
condición que causó el error.

Resume Next Reanuda la ejecución del programa en la instrucción que sigue


inmediatamente a la que causó el error. Si el error se produjo fuera del procedimiento que
contiene el controlador de errores, la ejecución se reanuda en la instrucción que sigue
inmediatamente a la llamada al procedimiento donde se produjo el error, si el
procedimiento llamado no tiene activado un controlador de errores.

Resume línea Reanuda la ejecución del programa en la etiqueta especificada por línea,
donde línea es una etiqueta de línea (o un número de línea diferente de cero) que debe
estar en el mismo procedimiento que el controlador de errores.

Err.Raise Number: = número Desencadena un error en tiempo de ejecución. Cuando se ejecuta


esta instrucción dentro de la rutina de tratamiento de errores, Visual Basic busca
en la lista de llamadas otra rutina de tratamiento de errores. (La lista de llamadas
es la cadena de procedimientos que se han invocado para llegar al punto actual
de ejecución. Consulte la sección "La jerarquía del tratamiento de errores", más
adelante en este mismo tema.)

Material de estudio Página: 60 de 249


Visual Basic 6.0 y SQLServer 7.0

La diferencia entre las instrucciones Resume y Resume Next

En la siguiente figura se muestra la diferencia entre las instrucciones Resume y Resume


Next.

Por lo general, Resume se usa siempre que el controlador de errores pueda corregir el error y
Resume Next cuando el controlador de errores no pueda hacerlo. Puede escribir un
controlador de errores de manera que la existencia de un error en tiempo de ejecución no se
revele nunca al usuario o para presentar mensajes de error y permitir al usuario que realice
correcciones.

Por ejemplo, el procedimiento Function en el siguiente código de ejemplo usa el tratamiento


de errores para llevar a cabo una división "segura" de sus argumentos sin revelar los errores
que se puedan producir. Los errores que se pueden producir al efectuar una división son:

Error Causa
"División por cero" El numerador es distinto de cero, pero el
denominador es cero.
"Desbordamiento" El numerador y el denominador son cero
(durante una división de punto flotante).
"Llamada no válida a un procedimiento" El numerador o el denominador no es un valor
numérico (o no se puede considerar como un
valor numérico).

Material de estudio Página: 61 de 249


Visual Basic 6.0 y SQLServer 7.0

En los tres casos, el siguiente procedimiento Function intercepta estos errores y devuelve
Null:
Function Divide (numer, denom) as Variant
Dim Msg as String
Const mnErrDivByZero = 11, mnErrOverFlow = 6,
Const mnErrBadCall = 5
On Error GoTo MathHandler
Divide = numer / denom
Exit Function
MathHandler:
If Err.Number = MnErrDivByZero Or _
Err.Number = ErrOverFlow _
Or Err = ErrBadCall Then
Divide = Null ' Si el error era División por
cero,
' Desbordamiento o
Llamada no válida
' a un procedimiento,
devuelve Null.
Else
' Presenta mensaje de error no previsto.
Msg "Error inesperado " & Err.Number
Msg = Msg & ": " & Err.Description
MsgBox Msg, vbExclamation
End If ' En todos los casos, Resume Next
continúa
Resume Next ' la ejecución en la instrucción Exit
' Function.
End Function

Reanudar la ejecución en una línea especificada


Resume Next también se puede utilizar cuando se produce un error dentro de un bucle y
necesita reiniciar la operación. O bien, puede utilizar Resume línea, que devuelve el control a
una etiqueta de línea especificada.
El siguiente ejemplo ilustra el uso de la instrucción Resume línea. Esta función, permite al
usuario escribir una especificación de archivo que la función devuelve si existe el archivo.
Function VerifyFile As String
Const mnErrBadFileName = 52, _
mnErrDriveDoorOpen = 71
Const mnErrDeviceUnavailable = 68, _
mnErrInvalidFileName = 64
Dim strPrompt As String, strMsg As String, _
strFileSpec As String
strPrompt = "Especificación de archivo que desea comprobar:"
StartHere:
strFileSpec = "*.*" ' Empieza con una especificación
' predeterminada.
strMsg = strMsg & vbCRLF & strPrompt
' Dejar al usuario modificar el valor predeterminado
strFileSpec = InputBox(strMsg, "Buscar archivo", _
strFileSpec, 100, 100)

Material de estudio Página: 62 de 249


Visual Basic 6.0 y SQLServer 7.0

' Sale si el usuario elimina el valor predeterminado


If strFileSpec = "" Then Exit Function
On Error GoTo Handler
VerifyFile = Dir(strFileSpec)
Exit Function
Handler:
Select Case Err.Number ' Analiza el código de error y carga
' el mensaje.
Case ErrInvalidFileName, ErrBadFileName
strMsg = "Su especificación de archivo no es "
strMsg = strMsg & "válida; pruebe con otra."
Case MnErrDriveDoorOpen
strMsg = "Cierre la puerta de la unidad de _"
strMsg = strMsg & "disco e inténtelo de nuevo."
Case MnErrDeviceUnavailable
strMsg = "No se encuentra la unidad especificada."
StrMsg = strMsg & " Inténtelo de nuevo."
Case Else
Dim intErrNum As Integer
intErrNum = Err.Number
Err.Clear ' Borra el objeto Err.
Err.Raise Number:= intErrNum ' Vuelve a generar el
error.
End Select
Resume StartHere ' Vuelve a la etiqueta StartHere para
' que el usuario pruebe con
' otro nombre
' de archivo.
End Function

Si se encuentra una especificación de archivo coincidente, la función devuelve el nombre del


archivo. Si no se encuentra ningún archivo coincidente, la función devuelve una cadena de
longitud cero. Si se produce uno de los errores previstos, se asigna un mensaje a la variable
strMsg y la ejecución vuelve a la etiqueta StartHere. Esto ofrece al usuario otra
oportunidad de escribir una ruta de acceso y una especificación de archivo válida.

Si el error no estaba previsto, el segmento Case Else vuelve a generar el error para que el
siguiente controlador de errores de la lista de llamadas pueda interceptar el error. Esto es
necesario porque, si no se volviera a generar el error, el código continuaría la ejecución a
partir de la línea Resume StartHere. Al volver a generar el error, está haciendo que se
vuelva a producir el error y el nuevo error se interceptará en el siguiente nivel de la pila de
llamadas.

Nota A pesar de que el uso de Resume línea es una forma legítima de escribir código, una
proliferación de saltos a etiquetas de línea puede hacer que el código sea difícil de entender y
depurar.

Material de estudio Página: 63 de 249


Visual Basic 6.0 y SQLServer 7.0

1.11 Modelo de Objetos de Sistemas de Archivos (FSO)

Visual Basic permite procesar archivos, folders y unidades(drives) de dos maneras, una por
metodos de objetos independientes y la otra a través del Modelo de Objetos de Sistemas de
Archivos.

El modelo FSO usa la convención de Objetos: método, propiedad y eventos para procesar drives,
folders y archivos, permitiendo crear, alterar, mover, borrar, buscar y obtener información de
objetos relacionados a éste.

El modelo FSO hace fácil estas tareas. Cuando procesa archivos su principal objetivo es
almacenar datos eficientemente para poder accesarlos de la misma manera, con el fin de no
sobrecargar con procesos a las bases de datos que ocupe, ya que el proceso de guardar datos
grandes (BLOB) en la base de datos requiere de mayor tiempo de dedicación del RDBMS
(Manejador de Base de Datos Relacional).

NOTA: Para utilizar el objeto FSO debe activar la referencia a “Microsoft Scripting Runtime” que
hace refernecia al archivo Scrrun.Dll

El modelo FSO cuenta con los siguientes objetos:


Object Description
Es el objeto principal del grupo, le permite accesar todos los eventos,
FileSystemObject
metodos y

Permite obtener información acerca del drive especificado como: espacio


disponible, nombre lógico con que se comparte, nombre de la unidad.
Drive Nota: También puyede hacer referencia a una unidad de CD-ROM, disco en
RAM, etc. EL drive no requiere que sea una unidad conectada al
equipo, también puede ser una unidad lógica accesada por la RED.

Permite crear, borrar o mover folders, así como consultar nombres, paths,
Folder
etc.

Permite crear, borrar o mover archivos, así como consultar nombres, paths,
Files
etc.

TextStream Permite leer y escribir archivos de texto.

Al trabajar con el módelo FSO se involucran tres tareas:


 El uso del método de CreateObject o declarar la variable como FileSystemObject
 El uso de los métodos apropiados del objeto creado
 El uso de las propiedades del objeto creado

Dichas tareas se explicarán a continuación.

Material de estudio Página: 64 de 249


Visual Basic 6.0 y SQLServer 7.0

Crear un objeto FileSystemObject

El primer paso es crear un objeto FileSystemObject para poder trabajar con él. Se puede realizar
ésto de dos formas:

• Declara una valriable del tipo de objeto FileSystemObject:


Dim fso As New FileSystemObject
• Usar el método CreateObject:
Set fso = CreateObject("Scripting.FileSystemObject")

Note que la esencia es crear un objeto dwl tipo FileSystemObject.

Nota El primer método trabaja bajo VB, mientras que el segundo trabaja en VB y VBScript.

Usar el método apropiado

El siguiente paso es usar el método apropiado del objeto FileSystemObject. Por ejemplo, si desea
crear un nuevo objeto, puede usar los métodos CreateFolder o CreateTextFile. (El modelo FSO
no soporta la creación o borrado de unidades “drives”).

Si desea borrar un objeto, puede usar los métodos DeleteFile y DeleteFolder del objeto
FileSystemObject, o el método de Delete de los objetos File y Folder. Puede copiar y mover
archivos y folders.

Accesando existentes Drives, Files, y Folders

Para accesar un existente drive, file, or folder, use el apropriado método "get" del objeto
FileSystemObject:

• GetDrive
• GetFolder
• GetFile

Por ejemplo:

Dim fso As New FileSystemObject, fil As File


Set fil = fso.GetFile("c:\test.txt")

Material de estudio Página: 65 de 249


Visual Basic 6.0 y SQLServer 7.0

Observe que no es necesario usar el método “get” para obtener información cuando ya ha creado
un objeto, una vez creado el objeto podrá manejar los métodos asociados a éste. Por ejemplo, si
usted crea un nuevo objeto folder usando el método CreateFolder, no necesitará usar el método
GetFolder para usar sus propiedades como son: Name, Path, Size, etc. Sólo necesita establecer
la variable al objeto CreateFolder y este nuevo objeto accesará las propiedades, métodos y
eventos asociados, como lo muestra el siguiente ejemplo:

Private Sub Create_Folder()


Dim fso As New FileSystemObject, fldr As Folder
Set fldr = fso.CreateFolder("C:\MyTest")
MsgBox "nombre del folder creado:" & fldr.Name
End Sub

Accesando las propiedades de Objeto

Una vez que tiene el manejador del objeto, podrá accesar sus propiedades. Por ejemplo, decirle
que quiere obtener el nombre de un folder particular. Primero cree una instancia del objeto,
entonces podrá manejar los métodos apropiados de éste ( en este caso el método GetFolder, si
es que ya existe este folder):
Set fldr = fso.GetFolder("c:\")

Ahora usted podrá manejar el objeto folder como checar la propiedad Name:
Debug.Print "Folder name is: "; fldr.Name

Si desea saber cual fue la última vez que el archivo fue modificado, use el siguiente método:
Dim fso As New FileSystemObject, fil As File
Set fil = fso.GetFile("c:\detlog.txt") ' Get a File object to query.
Debug.Print "El File fue modificado: "; fil.DateLastModified '

Trabajando con Drives y Folders

Con el modelo FSO usted puede trabajar con drivers y folders al igual que lo hace con Windows,
podrá copiar, mover y obtener información acerca de los drivers y folders.

Obteniéndo información acerca de Drives


El objeto Drive, le permitirá obtener información de los drives que se encuentran en el sistema
(PC) tanto físicos como mapeados. Estas propiedades le permitirán obtener información sobre:

• El tamaño total del drive en bytes (TotalSize).


• El espacio disponible existente en el drive en bytes (AvailableSpace or FreeSpace).
• Que letra está asignada al drive (DriveLetter property).
• El tipo de drive: removible, fijo, mapeado, CD-ROM, o RAM disk (DriveType).
• El número serial del drive (SerialNumber).
• El tipo de file system del drive, como FAT, FAT32, NTFS, etcétera (FileSystem).
• Que drive esta disponible para usar (IsReady).
• El nombre compartido y/o etiqueta del drive (ShareName and VolumeName).
• El path o RootFolder del drive (Path and RootFolder).

Material de estudio Página: 66 de 249


Visual Basic 6.0 y SQLServer 7.0

El ejemplo siguiente muestra como usar el objeto Drive, para obtener información acerca de éste.
Recuerde que no necesita hacer una referencia al objeto Drive, en lugar de eso use el método
GetDriver para obtener información acerca del objeto Drive.

Private Sub Command3_Click()


Dim fso As New FileSystemObject, drv As Drive, s As String
Set drv = fso.GetDrive(fso.GetDriveName("c:"))
s = "Drive " & UCase("c:") & " - "
s = s & drv.VolumeName & vbCrLf
s = s & "Espacio Total: " & FormatNumber(drv.TotalSize / 1024, 0)
s = s & " Kb" & vbCrLf
s = s & "Espacio Libre: " & FormatNumber(drv.FreeSpace / 1024, 0)
s = s & " Kb" & vbCrLf
MsgBox s
End Sub

Usando CurDir, ChDrive, ChDir o App.Path

Si usa la función Cur Dir, las instrucciones ChDrive y ChDir o la propiedad de Path (App.Path),
ponga atención, ya que éste puede retornar un path UNC (como \\Server\Nombre_compartido…)
en vez del path del drive (como E:\Folder), ésto dependera de cómo ejecute su programa o
proyecto.

App.Path retorna un UNC path de acuerdo a:

• Cuando se ejecuta un proyecto después de cargarlo de un recurso compartido, siempre


que el recurso esté mapeado a nuestra PC con una letra.
• Cuando se corre un archivo ejecutable desde un recurso compartido, siempre que éste
sea ejecutado usando UNC path.

ChDrive no puede manejar un UNC path, éste provocará un error cuando el App.Path retorna
uno. Podrá manejar este error adicionando la instrucción On Error Resume Next después de la
instrucción ChDrive o probando los primeros dos caracteres de App.Path para verificar si son
diagonales invertidas (\\):

On Error Resume Next


ChDrive App.Path
ChDir App.Path

Material de estudio Página: 67 de 249


Visual Basic 6.0 y SQLServer 7.0

Trabajando con Folders

La siguiente tabla muestra las tareas y métodos del objeto Folder:


Tarea Método
Crear un folder FileSystemObject.CreateFolder
Borrar un folder Folder.Delete o FileSystemObject.DeleteFolder
Mover un folder Folder.Move o FileSystemObject.MoveFolder
Copiar un folder Folder.Copy o FileSystemObject.CopyFolder
Obtener el nombre de un folder Folder.Name
Verificar si existe un folder FileSystemObject.FolderExists
Establecer una instancia de un folder
FileSystemObject.GetFolder
existente
Obtener el nombre del padre del folder FileSystemObject.GetParentFolderName
Obtener el path del folder FileSystemObject.GetSpecialFolder

Ejemplo

El siguiente ejemplo ilustra el uso de los objetos Folder y FileSystemObject:

Private Sub Command10_Click()


' Establecer una instancia del FileSystemObject.
Dim fso As New FileSystemObject, fldr As Folder, s As String
' Establecer el objeto Drive.
Set fldr = fso.GetFolder("c:")
' Desplegar el nombre del folder padre.
Debug.Print " nombre del folder padre: " & fldr
' Desplegar el nombre del drive.
Debug.Print "Contenido del drive " & fldr.Drive
' Desplegar la ruta.
If fldr.IsRootFolder = True Then
Debug.Print "Este folder es la raíz."
Else
Debug.Print " Este folder no es la raíz."
End If
' Crear un folder con el objeto FileSystemObject.
fso.CreateFolder ("c:\Nuevo")
Debug.Print "Se creo el folder C:\Nuevo"
' Desplegar el nombre base del folder.
Debug.Print "Nombre base= " & fso.GetBaseName("c:\Nuevo")
' Borrar el folder creado.
fso.DeleteFolder ("c:\Nuevo")
Debug.Print "Folder borrado C:\Nuevo"
End Sub

Material de estudio Página: 68 de 249


Visual Basic 6.0 y SQLServer 7.0

Trabajando con Archivos


Con el objeto FSO puedes copiar, borrar y abrir archivos. Existen dos categorias para el manejo
de estas opciones:

• Crear, adicionar, remover datos y lectura.


• Mover, copiar y borrar.

Crear, adicionar, remover datos y lectura

Existen tres maneras para crear archivos de texto secuenciales, algunas veces nos referimos a
éstos como "text stream”. Una de estas es usar el método CreateTextFile:

Dim fso As New FileSystemObject, fil As File


Set fil = fso.CreateTextFile("c:\prueba.txt", True)

Nota. El modelo de objetos FSO no soporta la creación de archivos Random o Binarios, para
crear estos tipos de archivos use el comando Open con la bandera establecida como Random o
Binary.

Otra forma para utilizar el método OpenTextFile del objeto FileSystemObject con la bandera
establecida como ForWriting (para escritura):

Dim fso As New FileSystemObject, ts As New TextStream


Set ts = fso.OpenTextFile("c:\test.txt", ForWriting)
Or you can use the OpenAsTextStream method with the ForWriting flag set:
Dim fso As New FileSystemObject, fil As File, ts As TextStream
Set fso = CreateObject("Scripting.FileSystemObject")
fso.CreateTextFile ("test1.txt")
Set fil = fso.GetFile("test1.txt")
Set ts = fil.OpenAsTextStream(ForWriting)

Adicionando datos al Archivo

Una vez que el archivo de texto ha sido creado, usted podrá adicionar datos de acuerdo con lo
siguiente:

1. Abrir el archivo de texto para escritura de datos.


2. Escribir los datos.
3. Cerrar el archivo.

Para abrir el archivo, puede usar los siguientes métodos: el método OpenAsTextStream del objeto
File o el método OpenTextFile del objeto FileSystemObject.

Para escribir datos en el archivo abierto de datos, use los métodos Write o WriteLine del
objetoTextStream. La diferencia entre éstos es que WriteLine adiciona un salto de línea al final de
la cadena.

Material de estudio Página: 69 de 249


Visual Basic 6.0 y SQLServer 7.0

Si desea adicionar una línea en blanco en el archivo de texto use el método WriteBlankLines.

Para cerrrar un archivo abierto, use el método Close del objeto TextStream.

El siguiente ejemplo ilustra lo anterior.

Sub Create_File()
Dim fso, txtfile
Set fso = CreateObject("Scripting.FileSystemObject")
Set txtfile = fso.CreateTextFile("c:\prueba.txt", True)
txtfile.Write ("This is a test. ") ' Write a line.
' Write a line with a newline character.
txtfile.WriteLine("Testing 1, 2, 3.")
' Write three newline characters to the file.
txtfile.WriteBlankLines(3)
txtfile.Close
End Sub

Lectura de Archivos con FSO

Para leer datos de un archivo de texto, use los siguientes métodos del objeto TextStream:
Tarea Método
Leer un número especificado de caracteres de un archivo Read
Leer una línea entera (no incluye el carácter nueva línea). ReadLine
Leer el contenido total de un archivo de texto ReadAll

Si desea saltar n caracteres o líneas, puede utilizar los métodos Skip o SkipLine.

El texto resultante de una lectura es almacenado en un string.

Nota La constante vbNewLine avanza el cursor hasta el comienzo de la siguiente línea.

Ejemplo

Sub Read_Files()
Dim fso As New FileSystemObject, txtfile, _
fil1 As File, ts As TextStream
Set txtfile = fso.CreateTextFile("c:\prueba.txt", True)
MsgBox "Escribiendo en el archivo"
' Escribiendo una línea.
Set fil1 = fso.GetFile("c:\prueba.txt")
Set ts = fil1.OpenAsTextStream(ForWriting)
ts.Write "Curso de Visual Basic"
ts.Close
' Leyendo contenido.
Set ts = fil1.OpenAsTextStream(ForReading)
s = ts.ReadLine
MsgBox s
ts.Close
End Sub

Material de estudio Página: 70 de 249


Visual Basic 6.0 y SQLServer 7.0

Moviendo, Copiando y Borrando Archivos

Tarea Método
Mover un archivo File.Move o FileSystemObject.MoveFile
Copiar un archivo File.Copy o FileSystemObject.CopyFile
Borrar una archivo File.Delete o FileSystemObject.DeleteFile

Ejemplo

Este ejemplo crea un archivo de texto en la raíz del drive c. Escribe en éste, lo mueve al directorio
\tmp, hace una copia de éste llamado \temp y borra los archivos copiados en ambos directorios.

Para ejecutar este ejemplo asegúrese que tiene los directorios \tmp y \temp en la raíz del drive C.

Sub Manip_Files()
Dim fso as New FileSystemObject, txtfile, fil1, fil2
Set txtfile = fso.CreateTextFile("c:\prueba.txt", True)
MsgBox "Escribiendo en archivo"
' Escribiendo una línea.
txtfile.Write ("Curso de Visual Basic.")
' Cerrando el archivo.
txtfile.Close
MsgBox "Moviendo el archivo a c:\tmp"
' Obteniendo una instancia del archivo.
Set fil1 = fso.GetFile("c:\prueba.txt")
' Moviendo el archivo a \tmp directory.
fil1.Move ("c:\tmp\prueba.txt")
MsgBox "Copiando archivo a c:\temp"
' Copiando archivo a \temp.
fil1.Copy ("c:\temp\prueba.txt")
MsgBox "Borrando archivos"
' Obteniendo una instancia de los archivos creados.
Set fil1 = fso.GetFile("c:\tmp\prueba.txt")
Set fil2 = fso.GetFile("c:\temp\prueba.txt")
' Borrando archivos.
fil1.Delete
fil2.Delete
MsgBox "Fin de proceso"
End Sub

Material de estudio Página: 71 de 249


Visual Basic 6.0 y SQLServer 7.0

1.12 Objetos del sistema de archivos: Drive, Folder y Files

Tipos de acceso a archivos


Por sí mismo, un archivo no es más que una serie de bytes relacionados ubicados en un
disco. Cuando su aplicación tiene acceso a un archivo, debe asumir qué se supone que
representan los bytes (caracteres, registros de datos, enteros, cadenas, etc.)
Dependiendo del tipo de datos que contiene el archivo, se usa el tipo de acceso apropiado.
En Visual Basic hay tres tipos de acceso a archivos:
• Secuencial: para leer y escribir archivos de texto en bloques continuos.
• Aleatorio: para leer y escribir archivos binarios de texto o estructurados como registros de
longitud fija.
• Binario: para leer y escribir archivos estructurados de forma arbitraria.

El acceso secuencial está diseñado para usarlo con archivos de texto normales. Se supone
que cada carácter del archivo representa un carácter de texto o una secuencia de formato de
texto, como un carácter de nueva línea (NL). Los datos se almacenan como caracteres ANSI.
Se supone que un archivo abierto para acceso aleatorio se compone de un conjunto de
registros de longitud idéntica. Puede usar tipos definidos por el usuario para crear registros
compuestos de varios campos, en los que cada uno puede tener tipos de datos diferentes.
Los datos se almacenan como información binaria.
El acceso binario le permite usar archivos para almacenar datos de la manera que desee. Es
similar al acceso aleatorio, excepto porque no se hacen suposiciones sobre los tipos de datos
o la longitud del registro. No obstante, debe saber de manera precisa cómo se escribieron los
datos en el archivo para poder recuperarlo correctamente.
Para obtener más información Para obtener más información acerca de los tipos de
acceso a datos, consulte "Uso del acceso secuencial a archivos", "Uso del acceso aleatorio a
archivos" y "Uso del acceso binario a archivos". Para obtener información acerca de
cuestiones de Unicode y ANSI, consulte "ANSI, DBCS y Unicode: Definiciones" y
"Procesamiento de archivos con caracteres de doble byte" en "Aspectos internacionales".

Instrucciones y funciones de acceso a datos


Las siguientes funciones se usan con los tres tipos de acceso a datos:
Dir FileLen LOF
EOF FreeFile Seek
FileCopy GetAttr SetAttr
FileDateTime Loc

Material de estudio Página: 72 de 249


Visual Basic 6.0 y SQLServer 7.0

La siguiente tabla muestra todas las instrucciones de acceso a archivos y las funciones
disponibles para cada uno de los tipos de acceso directo a archivos.
Instrucciones y funciones

Secuencial Aleatorio Binario


Close X X X
Get X X
Input( ) X X
Input # X
Line Input # X
Open X X X
Print # X
Put X X
Write # X

Un control DirListBox muestra directorios y rutas de acceso en tiempo de ejecución. Utilice


este control para mostrar una lista jerárquica de directorios. Puede crear cuadros de diálogo
que, por ejemplo, permitan a un usuario abrir un archivo desde una lista de archivos de todos
los directorios disponibles.

Sintaxis
DirListBox
Comentarios
Establezca las propiedades List, ListCount y ListIndex para permitir al usuario tener acceso
a los elementos de una lista. Si también muestra los controles DriveListBox y FileListBox,
puede escribir código para sincronizarlos con el control DirListBox y entre sí.
Eventos
Evento Change Evento MouseMove
Evento Click Evento OLECompleteDrag
Evento DragDrop Evento OLEDragDrop
Evento DragOver Evento OLEDragOver
Evento GotFocus Evento OLEGiveFeedback
Eventos KeyDown y KeyUp Evento OLESetData
Evento KeyPress Evento OLEStartDrag
Evento LostFocus Evento Scroll
Eventos MouseDown y MouseUp

Métodos
Método Drag Método SetFocus
Método Move Método ShowWhatsThis
Método OLEDrag Método ZOrder
Método Refresh

Material de estudio Página: 73 de 249


Visual Basic 6.0 y SQLServer 7.0

Propiedades
Propiedad Appearance Propiedad ListCount
BackColor y ForeColor Propiedad ListIndex
Propiedad Container Propiedad MouseIcon
Propiedad DragIcon Propiedad MousePointer
Propiedad DragMode Propiedad Name
Propiedad Enabled Propiedad OLEDragMode
Propiedad Font Propiedad OLEDropMode
Propiedad FontBold, FontItalic, Propiedad Parent
FontStrikethru y FontUnderline
Propiedad FontName Propiedad Path
Propiedad FontSize Propiedad TabIndex
Propiedad Height y Width Propiedad TabStop
Propiedad HelpContextID Propiedad Tag
Propiedad hWnd Propiedad ToolTipText
Propiedad Index (Control Array) Propiedad TopIndex
Propiedad Left y Top Propiedad Visible
Propiedad List Propiedad WhatsThisHelpID

Un control DriveListBox permite al usuario seleccionar una unidad de disco válida en tiempo
de ejecución. Utilice este control para mostrar una lista de todas las unidades válidas del
sistema de un usuario. Puede crear cuadros de diálogo que permitan al usuario abrir un
archivo de una lista de un disco en cualquier unidad disponible.

Sintaxis
DriveListBox
Comentarios
Establezca las propiedades List, ListCount y ListIndex para permitir al usuario tener acceso
a los elementos de la lista. Si además muestra los controles DirListBox y FileListBox, podrá
escribir código para sincronizarlos con el control DriveListBox y entre sí.
Eventos
Evento Change Evento OLECompleteDrag
Evento DragDrop Evento OLEDragDrop
Evento DragOver Evento OLEDragOver
Evento GotFocus Evento OLEGiveFeedback
Evento KeyDown y KeyUp Evento OLESetData
Evento KeyPress Evento OLEStartDrag
Evento LostFocus Evento Scroll

Métodos
Métodos Drag Métodos SetFocus
Métodos Move Métodos ShowWhatsThis
Métodos OLEDrag Métodos ZOrder
Métodos Refresh

Material de estudio Página: 74 de 249


Visual Basic 6.0 y SQLServer 7.0

Propiedades
Propiedad Appearance Propiedad List
Propiedades BackColor y ForeColor Propiedad ListCount
Propiedad Container Propiedad ListIndex
Propiedad DragIcon Propiedad MouseIcon
Propiedad DragMode Propiedad MousePointer
Propiedad Drive Propiedad Name
Propiedad Enabled Propiedad OLEDropMode
Propiedad Font Propiedad Parent
Propiedades FontBold, FontItalic, Propiedad TabIndex
FontStrikethru y FontUnderline
Propiedad FontName Propiedad TabStop
Propiedad FontSize Propiedad Tag
Propiedades Height y Width Propiedad ToolTipText
Propiedad HelpContextID Propiedad TopIndex
Propiedad hWnd Propiedad Visible
Propiedad Index (Control Array) Propiedad WhatsThisHelpID
Propiedades Left y Top

El control FileListBox encuentra y muestra los archivos del directorio especificado por la
propiedad Path en tiempo de ejecución. Utilice este control para mostrar una lista de los
archivos seleccionados por tipo. Puede crear cuadros de diálogo en la aplicación que, por
ejemplo, permitan al usuario seleccionar un archivo o un grupo de archivos.

Sintaxis
FileListBox
Comentarios
Establezca las propiedades List, ListCount y ListIndex para permitir al usuario tener acceso
a los elementos de la lista. Si además muestra los controles DirListBox y DriveListBox,
podrá escribir código para sincronizarlos con el control FileListBox y entre sí.
Eventos
Evento Click Evento OLECompleteDrag
Evento DblClick Evento OLEDragDrop
Evento DragDrop Evento OLEDragOver
Evento DragOver Evento OLEGiveFeedback
Evento GotFocus Evento OLESetData
Eventos KeyDown y KeyUp Evento OLEStartDrag
Evento KeyPress Evento PathChange
Evento LostFocus Evento PatternChange
Evento MouseDown y MouseUp Evento Scroll
Evento MouseMove

Métodos
Método Drag Método SetFocus
Método Move Método ShowWhatsThis
Método OLEDrag Método ZOrder
Método Refresh

Propiedades

Material de estudio Página: 75 de 249


Visual Basic 6.0 y SQLServer 7.0

Propiedad Appearance Propiedad Locked


Propiedades Archive, Hidden, Normal y Propiedad MouseIcon
System
Propiedades BackColor y ForeColor Propiedad MousePointer
Propiedad Container Propiedad MultiSelect
Propiedad DragIcon Propiedad Name
Propiedad DragMode Propiedad OLEDragMode
Propiedad Enabled Propiedad OLEDropMode
Propiedad FileName Propiedad Parent
Propiedad Font Propiedad Path
Propiedades FontBold, FontItalic, Propiedad Pattern
FontStrikethru y FontUnderline
Propiedad FontName Propiedad ReadOnly
Propiedad FontSize Propiedad Selected
Propiedades Height y Width Propiedad TabIndex
Propiedad HelpContextID Propiedad TabStop
Propiedad hWnd Propiedad Tag
Propiedad Index (Control Array) Propiedad ToolTipText
Propiedad Left y Top Propiedad TopIndex
Propiedad List Propiedad Visible
Propiedad ListCount Propiedad WhatsThisHelpID
Propiedad ListIndex

NOTAS IMPORTANTES SOBRE EL MANEJO DE OBJETOS: Drive, Folder y


Files

 Drive

La propiedad Drive del control lista de unidades de disco permite saber cual es la unidad actual.
Cuando queremos modificar la unidad actual, solo el primer carácter de la cadena de caracteres
correspondiente es significativa. Un cambio de unidad de disco genera el susceso Change.
Esta propiedad sólo esta disponible en tiempo de ejecución. Por ejemplo:
Drv_Drive.Drive =”d:”

Cuamndo se elige una unidad de disco de la lista, la unidad de trabajo actual no cambia
automáticamente. Si desea hacerlo, tiene que ejecutar la sentencia:

ChDrive drv_Drive.Drive

 Folder

El directorio actual en el control lista de directorios aparece sombreado. La propiedad Path


devuelve la ruta completa del directorio actual, incluyendo el nombre de la unidad. Modificando el
valor de esta propiedad podemos cambiar el directorio actual. Si sólo modificamos la unidad (por
ejemplo, d: ), por defecto se selecciona el directorio actual en dicha unidad. Un cambio de
directorio actual genera el suceso Change. La propiedad Path sólo esta disponible en tiempo de
ejecución y pertenece también al control Lista de Ficheros, con la diferencia de que aquí un
cambio del camino actual genera el susceso PathChange. Por ejemplo:

Dir_Dir.Path = “d:\temp”

Material de estudio Página: 76 de 249


Visual Basic 6.0 y SQLServer 7.0

Cuando se elige un directorio de la Lista ele directorio de trabajo actual no cambia


automáticamente. Si desea hacerlo tiene que ejecutar la sentencia:

ChDir Dir_Dir.Path

El directorio especificado por la propiedad Path siempre tiene como índice –1 (Propiedad
ListIndex). El directorio que esta inmediatamente encima de él tiene como índice-2, y así
sucesivamente hasta el directorio raíz. El primer subdirectorio que esta inmediatamente a
continuación tiene como índice 0. Si hay varios directorios en el priemer nivel de subdirectorios, el
siguiente tiene índice 1, y así sucesivamente. Dese cuenta que una lista sólo esta compuesta por
el directorio especificado por la propiedad Path, más los directorios hasta llegar desde éste hasta
el directorio Raíz, más los directorios correspondientes a su primer nivel de subdirectorios.
El número de directorios correspondientes al primer nivel de subdirectorios del directorio
especificado por la propiedad Path viene dado por la propiedad ListCount de la Lista.

Para calcular el índice correspondiente al directorio Raíz, escriba el siguiente código:

Dim InDirRaíz As Integer


InDirRaíz = dir_Dir.ListIndex
Do Until dir_Dir.List(InDirRaíz) = “”
InDirRaíz= InDirRaíz-1
Loop
InDirRaíz= InDirRaíz+1

 Files
La propiedad FileName permite especificar el fichero que se quiere utilizar o devuelve el nombre
del fichero seleccionadoen una lista; esta propiedad sólo está disponible en tiempo de ejecución
por ejemplo:

Lstr_NomArchivo = File1.FilenName

La propiedad Pattern del control Lista de Ficheros permite que se visualicen solamente los
ficheros que cumplan el patrón especificadoo ésta. Por ejemplo:

*.txt ‘hace que se visualicen sólo los archivos con extensión .txt

Los atributostambién estan disponibles a través de las propiedades Archive, Normal, System,
Hidden y ReadOnly. Por ejemplo:

Si no quiere visualizar los archivos ocultos, asigene a ala propiedad Hidden el valor False.
Cuando la propiedad Normal tiene asignado el valor True, se visualizan todos los ficheros,
menos los ocultos y los de sistema. Las proepiedades System y Hidden tienen por defecto valor
False; las demás tienen valor True. Para poner atributos a un archivo utilece la sentencia SetAttr
y para obtenerlos GetAttr.

Material de estudio Página: 77 de 249


Visual Basic 6.0 y SQLServer 7.0

1.13 Manejo de API's

Un programa en ambiente Windows, además de accesar toda la funcionalidad establecida en su


entorno, también accesa el entorno de programación de interfaz de aplicaciones para Windows
conocido como API (Windows Aplication Programming Interface), cuya característica principal son
los mensajes y las funciones.

Existen cientos de funciones que ejecutan una amplia variedad de tareas. Los mensajes son
utilizados por Windows para permitir que las aplicaciones se comuniquen entre sí y con el propio
sistema. Se dice entonces que las aplicaciones Windows son conducidas por mensajes o
sucesos.

Una Biblioteca Dinámica (Dynamic Link Libraries, DLL) permite que las aplicaciones windows
compartan código y recursos. Una DLL es un archivo ejecutable que contiene funciones que
puede ser utilizada por todas las aplicaciones.

Ventajas.
 Permiten realizar acciones especiales que no se pueden realizar directamente en
VB.
 Se actualizan sin tener que modificar los programas que la utilizan.
 No existe duplicidad de código cuando varias aplicaciones las utilizan.

Desventajas
Χ Tiempo en que Windows emplea para leer las funciones.
Χ El archivo físico debe estar presente cuando se ejecuta el programa.

Las funciones de la API de Windows están disponibles en las bibliotecas Kernel, GDI y User,
locaclizadas en la carpeta System de Windows. Para acceder a estas funciones, VB utiliza la
sentencia DECLARE: El archivo win32API.txt, contiene las sentencias DECLARE de casi todas
las funciones del API de windows (exceptuando las que trabajan con punteros).

Como los procedimientos de una DLL son externos a su aplicación, deberá proporcionar cierta
información que permita localizar y por lo tanto ejecutar el procedimiento deseado. Esta
información se declara en un módulo. Por ejemplo:

Declare Function GetModuleHandle Lif “Kernel32” (ByVal LPModuleName As String) As Integer

Puede utilizar la clausula Alias en cualquier otra situación en la que le sea conveniente. Por
ejemplo,
En un modulo inserte la siguiente instrucción
Declare Function DirWin Lib "Kernel32" Alias _
"GetWindowsDirectoryA" (ByVal lpBuffer As String, _
ByVal nSize As Integer) As Integer

Ahora podrá llamar a la función con el nombre más corto.

Dim RutaWin As String


RutaWin = String (145, chr(0))
RutaWin = Left (RutaWin, DirWin(RutaWin, len(RutaWin)))

Material de estudio Página: 78 de 249


Visual Basic 6.0 y SQLServer 7.0

1.14 Interactuar con Word y Excel

¿Necesita algunas veces proporcionar la misma capacidad de análisis y cálculo que Microsoft Excel en
sus aplicaciones de Visual Basic? O bien, quizá le gustaría dar formato a un documento con las
herramientas de formato de Microsoft Word o almacenar y administrar datos con el motor de base de
datos Microsoft Jet. Mejor aún, ¿no le gustaría poder crear o comprar componentes estándar para
utilizarlos después en múltiples aplicaciones sin necesidad de modificarlos?

Puede conseguir todo esto y más si genera sus aplicaciones con componentes ActiveX. Un
componente ActiveX es un fragmento reutilizable de código de programación y datos
compuesto por uno o más objetos creados mediante la tecnología ActiveX. Las aplicaciones
pueden utilizar componentes existentes, como los incluidos en las aplicaciones de Microsoft
Office, componentes de código, documentos ActiveX o controles ActiveX (antes llamados
controles OLE) que venden diversos proveedores. O bien, si dispone de la Edición profesional
o de la Edición empresarial de Visual Basic, puede crear sus propios controles ActiveX.
En el caso de los componentes compatibles con la vinculación e incrustación de objetos,
puede insertar objetos en su aplicación sin necesidad de escribir código, utilizando la interfaz
visual del componente. Puede insertar en la aplicación un objeto activado para ActiveX
utilizando el control contenedor OLE o agregando la clase del objeto al cuadro de
herramientas.
La palabra “documento” del término “documento ActiveX” puede llevar a confusión. Aunque la
génesis de los documentos ActiveX indica que un documento ActiveX de Microsoft Visual
Basic es análogo a un documento de Word, al crear el primero la distinción entre un
“documento” y una aplicación se difumina por completo. Aunque los documentos tradicionales
(como los de Word) son estáticos, los documentos ActiveX no tienen por qué serlo. Con
Visual Basic puede crear una aplicación completa con la semántica de un documento
tradicional. Es decir, dispone de la funcionalidad de la aplicación, pero con la flexibilidad del
comportamiento de un documento. Cuando un usuario abre un documento ActiveX, no sólo
tendrá la funcionalidad completa de una aplicación, sino también la capacidad de conservar y
distribuir “copias” de los datos intrínsecos a la aplicación. De este modo, el “documento” es
realmente activo.

Una analogía: documento de Word = documento ActiveX


Los documentos ActiveX no son un concepto completamente nuevo. Probablemente ya esté
familiarizado con los documentos de Word. Como sabe, un documento de Word no es lo
mismo que la aplicación Word: el documento (con la extensión .doc) almacena el contenido
real, mientras que la aplicación Word (Winword.exe) se utiliza para crear el documento.
Después de declarar una variable de objeto, debe asignar una referencia de objeto a la
variable antes de poder utilizar las propiedades, métodos y eventos del objeto. Hay varias
formas de asignar una nueva referencia de objeto:
• Si ha declarado la variable utilizando la palabra clave New, Visual Basic asignará
automáticamente una nueva referencia de objeto la primera vez que utilice la variable.
• Puede asignar una referencia a un objeto nuevo en una instrucción Set utilizando la
palabra clave New o la función CreateObject.
• Puede asignar una referencia a un objeto nuevo o existente en una instrucción Set
utilizando la función GetObject.

Asignación de una referencia de objeto mediante la palabra clave New

Material de estudio Página: 79 de 249


Visual Basic 6.0 y SQLServer 7.0

Si el componente ActiveX proporciona una biblioteca de tipos, puede utilizar la palabra clave
New en una declaración de variable o una instrucción Set para crear un nuevo objeto y
asignar una referencia de objeto a una variable de objeto.
Si declara una variable de objeto con la palabra clave New, Visual Basic creará
automáticamente un nuevo objeto la primera vez que utilice la variable. Para obtener más
información al respecto, consulte "Declaración de una variable de objeto".
También puede utilizar la palabra clave New en una instrucción Set para asignar una
referencia a un nuevo objeto de la clase especificada. Por ejemplo, las instrucciones
siguientes asignan una referencia a un nuevo objeto de tabla DAO a la variable tdfOrders,
estableciendo la propiedad Name de la tabla a "Pedidos":
Dim tdfOrders As DAO.TableDef
Set tdfOrders = New DAO.TableDef
tdfOrders.Name = "Pedidos"

Asignación de una referencia de objeto mediante CreateObject


Independientemente de que un componente ActiveX proporcione o no una biblioteca de tipos,
puede utilizar la función CreateObject en una instrucción Set para crear un nuevo objeto y
asignar una referencia de objeto a una variable de objeto. Debe especificar el identificador de
programación del objeto como argumento para la función, y el objeto al que desea tener
acceso debe ser de creación externa.
Para asignar una referencia de objeto utilizando CreateObject
• Utilice la sintaxis siguiente para CreateObject.
Set variable_objeto = CreateObject("Idprog")

El argumento Idprog suele ser el nombre de clase calificado del objeto que se está creando;
por ejemplo, Word.Document. Sin embargo, Idprog puede ser diferente del nombre de clase.
Por ejemplo, Idprog para un objeto de Microsoft Excel es "Sheet" en lugar de "Worksheet".
El ejemplo de código siguiente inicia Microsoft Excel (si Microsoft Excel no está ya en
ejecución) y establece la variable xlApp para hacer referencia a un objeto de la clase
Application. El argumento "Excel.Application" califica correctamente Application como
una clase definida por Microsoft Excel:
Dim xlApp As Excel.Application
Set xlApp = CreateObject("Excel.Application")

Asignación de una referencia de objeto mediante GetObject


La función GetObject se utiliza normalmente para asignar una referencia a un objeto
existente, aunque también puede utilizarla para asignar una referencia a un nuevo objeto.
Para asignar una referencia a un objeto existente, utilice la sintaxis siguiente:
Set variable_objeto = GetObject([nombre_ruta] [, Idprog])

El argumento nombre_ruta puede ser la ruta de acceso a un archivo existente, una cadena o
se puede omitir. Si se omite, se requiere Idprog. Especificar la ruta de acceso a un archivo
existente hace que GetObject cree un objeto utilizando la información almacenada en el
archivo. Utilizar una cadena vacía para el primer argumento hace que GetObject actúe como
CreateObject: creará un nuevo objeto de la clase cuyo identificador de programación sea
Idprog. En la tabla siguiente se describen los resultados de utilizar GetObject.

Material de estudio Página: 80 de 249


Visual Basic 6.0 y SQLServer 7.0

Al igual que ocurre con CreateObject, el argumento "Word.Application" es el


identificador de programación para la clase Application definida por Microsoft Word. Si están
en ejecución múltiples instancias de Microsoft Word, no puede saber a que instancia hará
referencia wdApp.
Importante También puede utilizar GetObject para asignar una referencia a un objeto en un
archivo de documento compuesto. Un archivo de documento compuesto contiene referencias
a múltiples tipos de objetos. Por ejemplo, un archivo de documento compuesto puede
contener una hoja de cálculo, texto y mapas de bits.

El ejemplo siguiente inicia la aplicación de hoja de cálculo, si no está ya en ejecución, y abre


el archivo Ingresos.xls:
Dim xlBook As Excel.Workbook
Set xlBook = GetObject("C:\Cuentas\Ingresos.xls")

Cuando haya terminado de utilizar un objeto, borre las variables que hagan referencia al
objeto de forma que se pueda liberar el objeto de la memoria. Para borrar una variable de
objeto, establézcala a Nothing. Por ejemplo:
Dim acApp As Access.Application
Set acApp = New Access.Application
MsgBox acApp.SysCmd(acSysCmdAccessVer)
Set acApp = Nothing

Todas las variables de objeto se borran automáticamente cuando se salen del alcance. Si
desea que la variable conserve su valor en todos los procedimientos, utilice una variable
pública o de nivel formulario, o cree procedimientos que devuelvan el objeto. El código
siguiente muestra como se utilizaría una variable pública:
Public wdApp Aas Word.Application
.
.
.
' Crea un objeto Word e inicia Microsoft Word.
Set wdApp = New Word.Application
.
.
.
' Microsoft Word no se cerrará hasta que la
' aplicación termine o la referencia se establezca a
' Nothing:
Set wdApp = Nothing

Tenga cuidado también de establecer todas las referencias de objetos a Nothing cuando
termine, incluso las de objetos dependientes. Por ejemplo:
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Set xlApp = New Excel.Application
Set xlBook = xlApp.Workbooks.Add
Set xlApp = Nothing ' ¡Cuidado! xlBook puede contener
' aún una referencia de objeto.
Set xlBook = Nothing ' Ahora se han borrado todas
' las referencias.

Material de estudio Página: 81 de 249


Visual Basic 6.0 y SQLServer 7.0

En este ejemplo se ilustran los distintos usos de la instrucción AppActivate para activar una
ventana de una aplicación. Las instrucciones Shell suponen que las aplicaciones están en las
rutas especificadas. En Macintosh, se puede utilizar la función MacID para especificar la
identidad de la aplicación, en lugar del nombre de ésta. La instrucción AppActivate está
disponible para el sistema operativo de Macintosh System 7.0 o posterior.
Dim MyAppID, ReturnValue
' En Microsoft Windows:
AppActivate "Microsoft Word" ' Se activa Microsoft
' Word.

' AppActivate puede también utilizar el valor devuelto ' por la


función Shell.
MyAppID = Shell("C:\WORD\WINWORD.EXE", 1)' Se ejecuta Microsoft Word.
AppActivate MyAppID ' Se activa Microsoft
' Word.

' También se puede utilizar el valor devuelto por la función Shell.


ReturnValue = Shell("c:\EXCEL\EXCEL.EXE",1)' Se ejecuta Microsoft
Excel.
AppActivate ReturnValue ' Se activa Microsoft
' Excel.

Material de estudio Página: 82 de 249


Visual Basic 6.0 y SQLServer 7.0

1.15 Activar Animación en los procesos

El control Animation reproduce secuencias de vídeo AVI sin sonido. Una secuencia AVI está
formada por una serie de marcos de mapas de bits, como una película.
Un ejemplo es la hoja de papel que “vuela” de una carpeta a otra al copiar archivos en el
sistema Windows 95:

Aunque las secuencias AVI pueden tener sonido, cuando lo tienen no pueden utilizarse con el
control Animation y se producirá un error si intenta cargar un archivo de ese tipo. Sólo puede
utilizar secuencias AVI sin sonido. Para reproducir archivos .avi con sonido, utilice el control
Multimedia (MCI).
Nota Encontrará diversos archivos .avi sin sonido en el directorio \Graphics\AVI del CD-
ROM de Visual Basic.

En tiempo de ejecución, el control Animation no tiene un marco visible.


El control Animation mantiene un subproceso de ejecución independiente mientras se
reproduce la secuencia. Por tanto, la aplicación no se bloquea y puede continuar la ejecución
dentro de su proceso.

Aplicaciones posibles
• Crear cuadros de diálogo que informen al usuario de la duración y naturaleza de una
operación.
• Reproducir sin sonido secuencias de vídeo informativas sobre la aplicación.
• Permitir a los usuarios reproducir los archivos colocados en el control.

Funcionamiento básico: métodos Open, Play, Stop y Close


Al utilizar el control, el archivo .avi se abre con el método Open, se reproduce con el método
Play y se detiene con el método Stop. Una vez terminada la reproducción de un vídeo, puede
utilizar el método Close para cerrar el archivo. No es necesario cerrar un archivo para poder
abrir otro.
En el código siguiente se utilizan dos controles CommandButton, cmdPlay y cmdStop, y un
control CommonDialog llamado dlgOpen. Como título de cmdPlay, establezca “Abrir y
reproducir”. El título del control CommandButton cmdStop es "Detener".
Private Sub cmdPlay_Click()
' Configura un control CommonDialog para permitir
' al usuario buscar archivos .avi y reproducirlos.
' El control CommonDialog se llama "dlgOpen". El
' control Animation se llama "anmAVI".
dlgOpen.Filter = "archivos avi (*.avi)|*.avi"
dlgOpen.ShowOpen
anmAvi.Open dlgOpen.FileName
anmAVI.Play
End Sub

Este código detiene la reproducción del vídeo:


Private Sub cmdStop_Click()
anmAVI.Stop

Material de estudio Página: 83 de 249


Visual Basic 6.0 y SQLServer 7.0

End Sub

Argumentos del método Play: repeat, start y stop


El método Play tiene tres argumentos, repeat, start y stop, que determinan el número de
veces que se reproduce un archivo, en qué marco comienza la reproducción y dónde se
detiene el archivo.
Si no se especifica el argumento repeat, el archivo se reproducirá continuamente. Por
ejemplo, el código siguiente reproducirá un archivo continuamente hasta que el usuario haga
clic en el botón cmdStop:
Private Sub cmdPlay_Click()
dlgOpen.Filter = "archivos avi (*.avi)|*.avi"
dlgOpen.ShowOpen
anmAVI.Open dlgOpen.FileName
' Reproduce el archivo indefinidamente.
anmAVI.Play
End Sub

Private Sub cmdStop_Click()


anmAVI.Stop
End Sub

El código siguiente reproduce el archivo diez veces, desde el marco sexto al decimosexto (el
primer marco es el 0):
anmAVI.Play 10, 5, 15

Reproducción automática de archivos con la propiedad AutoPlay


Si la propiedad AutoPlay se establece a True, el control comenzará a reproducir un archivo
en cuanto se haya cargado. Por el contrario, para que no se reproduzca el archivo, establezca
la propiedad AutoPlay a False, como se muestra en el código siguiente:
Private Sub cmdPlay_Click()
' Si establece a True la propiedad AutoPlay, se
' reproduce el archivo al cargarlo. Por eso no es
' necesario el método Play.
dlgOpen.Filter = "archivos avi (*.avi)|*.avi"
dlgOpen.ShowOpen
anmAvi.AutoPlay = True
anmAVI.File = dlgOpen.FileName
End Sub

Private Sub cmdStop_Click()


' Establece AutoPlay a False para detener la
' reproducción.
anmAVI.AutoPlay = False
End Sub

Centrado del área de reproducción con la propiedad Center


Puede especificar si desea o no centrar el vídeo en el control mediante la propiedad Center.
Cuando el valor de esta propiedad es False, el control cambia automáticamente de tamaño
en tiempo de ejecución para ajustarse al tamaño del vídeo. En tiempo de diseño, los bordes
izquierdo y superior del control definen el área donde se mostrará el vídeo, de esta forma:

Material de estudio Página: 84 de 249


Visual Basic 6.0 y SQLServer 7.0

Cuando el valor de la propiedad Center es True, el control no cambia de tamaño, sino que el
vídeo se muestra en el centro del área definida por el control, de esta forma:
Nota Si el área definida por el control en tiempo de diseño es menor que el vídeo, se
recortarán los bordes de éste.

Material de estudio Página: 85 de 249


Visual Basic 6.0 y SQLServer 7.0

2 Desarrollo de aplicaciones bajo el modelo C/S

2.1 Modelo cliente / Servidor.

Podemos decir que en la arquitectura cliente/servidor existe en procesos


separados que residen en plataformas diferentes, e interactúan por medio de
una red.

UNA PLATAFORMA ES UN CONJUNTO FORMADO


POR :
• Hardware
• Software (Sistema Operativo)
• Software de Subsistema (Manejador de Base de
Datos)
• Software de Aplicación
EXISTEN DIFERENTES TIPOS DE PLATAFORMAS

• Mainframe o Minis enlazadas:


Funciona como servidor gigante de archivos o servidor de base
de datos, manejan aplicaciones tanto batch como interactivas y
la interface con el usuario es tipo carácter, además que son
equipos propietarios.
• Minis o Workstation de alto desempeño :
Dan servicio a nivel departamental, pero a
diferencia de las workstations, las
microcomputadoras son equipos propietarios y
también manejan aplicaciones tanto batch como
interactivas

• Microcomputadoras:
Existe una gran base instalada en ellas

La Arquitectura cliente/servidor pertenece a un Modelo Distribuido.

MODELO DISTRIBUIDO

Este esquema puede ser definido formalmente como aquel en el cual múltiples
procesadores autónomos, posiblemente de diferentes tipos, están
interconectados por una red de comunicación para interactuar entre sí, con la
finalidad de llevar a cabo tareas de procesamiento común. Para alcanzar está
meta los sistemas son integrados lógicamente en varios grados por sistemas
operativos para procesamiento distribuido y aplicaciones distribuidas, tales
como bases de datos distribuidas. Sin embargo, el esquema no sólo incluye
procesadores y sistemas operativos, en un concepto más general el modelo
distribuido es capaz de integrar los más diversos equipos periféricos,
aplicaciones, tecnologías de diseño de redes y herramientas de
administración.

Material de estudio Página: 86 de 249


Visual Basic 6.0 y SQLServer 7.0

Entre las características más relevantes de este modelo se encuentran:

• Soporte para un número arbitrario de sistemas y aplicaciones.


• Diseño modular de la arquitectura física.
• Uso de sistemas operativos y aplicaciones para procesamiento distribuido.
• Soporte de terceros tanto en hardware como en software.

Mientras que algunos de los beneficios que se derivan de adoptar el modelo,


son:

• Incremento de desempeño.
• Incremento de la confiabilidad y disponibilidad.
• Modularidad y control local.
• Costos reducidos y un alto grado de confiabilidad.

INFRAESTRUCTURA

Basado primordialmente en redes de computadoras, el modelo de


cómputo distribuido, utiliza todos los recursos y capacidades de éstas
como la herramienta principal de su infraestructura, para comunicar a los
diferentes recursos que se verán involucrados en el esquema.

Dada la rápida evolución de tecnologías en el campo de la computación,


así como en el de las comunicaciones, la red de computadoras que se
utilizará para implantar el esquema, como ya se había mencionado,
requiere de ser lo suficientemente robusta, eficiente y adaptable a nuevas
tecnologías, con la finalidad de garantizar la continuidad del modelo.

El esquema distribuido no sólo permite la integración de las más variadas


tecnologías de diseño y construcción de procesadores y periféricos, sino
también de las diferentes tecnologías de diseños de redes. Permitiendo de
ésta forma, integrar redes de comunicaciones ya existentes dentro de una
organización al modelo, que representa una ventaja sobre el esquema
centralizado, sin embargo, resulta conveniente que la red a utilizarse sea
realmente eficiente, dado que los resultados del modelo dependerán en
gran medida de ésta.

Dadas las facilidades de integración de tecnologías de redes y equipos, la


infraestructura del modelo distribuido puede ilustrarse, como se muestra
en la siguiente figura.

Material de estudio Página: 87 de 249


Visual Basic 6.0 y SQLServer 7.0

CD. SONORA
CARM EN

W O R K S T A T IO N

C H IH U A H U A

W O R K S T A T IO N W O R K S T A T IO N W O R K S T A T IO N W O R K S T A T IO N

T E R M IN A L

W O R K S T A T IO N

C D . D E M E X IC O
T E R M IN A L

Material de estudio Página: 88 de 249


Visual Basic 6.0 y SQLServer 7.0

MANEJO DE INFORMACION

Al igual que se distribuyen equipos de cómputo y periféricos, la


información se halla distribuida a lo largo de toda la organización,
encontrándose en aquellos lugares donde comúnmente es utilizada, donde
sin embargo, no importando su localización, cualquier persona puede tener
acceso a ella.

A diferencia del modelo centralizado, la información bajo este esquema


conserva las características de oportunidad y rapidez, ya que las consultas
se harán normalmente a bases de datos locales. Sin embargo dado que la
información generalmente es procesada en forma distribuida y pese a que
las herramientas para su manejo empleen complejos algoritmos de
validación de datos, ésta es susceptible de perder características como
consistencia y confiabilidad.

Con este esquema, el usuario final tiene también la posibilidad de acceder


a diversos bancos de información, que existen alrededor del mundo, y la
consulta a estos se efectúa a través de aplicaciones y herramientas
capaces de manipular la información contenida en ellos, sin importar su
localización geográfica. Entre las fuentes externas a las cuales se puede
acceder para obtener información actualizada y oportuna, se encuentran
diversas redes de computación públicas y privadas que existen alrededor
del mundo, destacando entre ellas Internet que es la red más grande e
importante, que cuenta entre sus miembros a universidades, instituciones
de investigación, agencias gubernamentales e instituciones privadas.
Herramientas para consultar estas fuentes, comúnmente permiten una
fácil interacción con el usuario, al contar con interfaces amigables que
harán del proceso de adquisición de información una tarea sencilla para
cualquier persona.

PROCESAMIENTO

Nuevos conceptos que han sido integrados a sistemas operativos, así


como complejos mecanismos de comunicación entre computadoras a
través de una red, permitiendo llevar a cabo el procesamiento de grandes
cantidades de datos y complejos algoritmos utilizando para ello múltiples
procesadores, que pueden ser de diferentes tipos y encontrarse
distribuidos a lo largo de la organización, esta forma de procesar datos,
conocida como procesamiento distribuido, es totalmente transparente el
usuario final ya que serán los sistemas operativos y aplicaciones los que
llevarán a cabo la distribución y control de todas las tareas que esto
implique, entre aquellos sistemas que se dispongan para ese efecto dando
la apariencia de que todas las operaciones necesarias las está llevando a
cabo un solo procesador.

Dado que el procesamiento distribuido sería llevado a cabo por diversos


procesadores utilizando como medio de comunicación la red de cómputo,
está deberá ser lo suficientemente confiable para que el procesamiento
puede efectuarse, pues se requerirá de llamadas y peticiones de control
entre todos aquellos procesadores que estén participando en el
procesamiento.

Material de estudio Página: 89 de 249


Visual Basic 6.0 y SQLServer 7.0

SERVICIOS

Sustentar el modelo distribuido en redes de computadoras, permite ofrecer


al usuario final una amplia gama de servicios basados en la utilización de
aplicaciones que operan bajo la red de cómputo instalada, entre ésta
variedad de facilidades se encuentran algunas que para el usuario final
revisten vital importancia, como lo es el caso del correo electrónico, ya
que éste adquiere gran relevancia cuando la organización pasa a formar
parte de algunas de las redes existentes alrededor del mundo. Bajo estas
circunstancias, el correo electrónico proporciona mayores beneficios en
relación con otros medios de comunicación tradicionales tales como
mensajería, fax, telefonía, ya que el usuario no sólo tendrá la posibilidad
de entablar comunicación con personas de su organización, sino que
también le será posible hacerlo con otras personas e instituciones de
forma segura y eficiente, no importando en que lugar del mundo se
encuentren.

Otro servicio que reviste igual importancia es la transferencia de


información, el modelo cuenta con herramientas eficientes y confiables
para transferir información entre sitios remotos sin importar que tipo de
información deba transferirse, abarcando desde artículos periodísticos,
reportes de clima, imágenes sobre condiciones atmosféricas hasta
archivos de aplicaciones guardados bajo formatos especiales.

Compartir equipos periféricos, tales como impresoras y graficadores de


alta calidad y desempeño es una tarea que se facilita tanto para los
administradores como para los usuarios finales, haciendo uso de la red de
cómputo éstos podrán ser utilizados por todo aquel personal que así lo
requiera, sin considerar donde se localicen los recursos. La integración y
distribución de recursos en el modelo se efectúa mediante sistemas
operativos y aplicaciones, las cuales una vez configuradas permitirán al
usuario hacer uso de aquellos recursos que le sean más convenientes o
adecuados al momento de requerirlo en forma transparente.

Dada la veracidad del modelo distribuido, integrar recursos y servicios no


previstos, no implicará rediseñar o modificar totalmente la estructura del
modelo, sólo se requerirá variar configuraciones en sistemas operativos y
aplicaciones. Integrar nuevos equipos periféricos no implicará contar con
un distribuidor o fabricante único, periféricos de terceros pueden ser
empleados sin ocasionar problemas de compatibilidad y sin recurrir a
gastos excesivos.

ADMINISTRACION

Una de las tareas más importantes para alcanzar las metas previstas
cuando se utiliza cómputo distribuido, lo constituye la administración de su
infraestructura. En este esquema donde el uso exhaustivo de una red de
computadoras es común, la administración de este recurso ocupa un lugar
primordial, contar con las herramientas adecuadas, así como con el
personal capacitado, garantizará el correcto desempeño y funcionamiento
de cada una de las partes que forman la red de cómputo. Herramientas
comunes son aplicaciones que utilizan protocolos especialmente diseñados
para monitorear el estado actual de la red y dar al administrador una idea
precisa de cual es el problema y en que parte éste está ocurriendo, para
así poder tomar decisiones sobre una solución rápida y adecuada, además

Material de estudio Página: 90 de 249


Visual Basic 6.0 y SQLServer 7.0

de contar con un equipo de personal especializado, permitirá dar pronta


solución a problemas técnicos en la infraestructura de la Red.

MODELO COOPERATIVO

Es una variante de los sistemas distribuidos, el modelo cooperativo que


consiste cuando el procesamiento de la aplicación se ejecuta en la plataforma
óptima de hardware.

El termino Proceso Cooperativo, es una definición literal, implica los


componentes individuales, en lo que aplicaciones se refieren, es cuando
diferentes aplicaciones de las mismas se llevan a cabo en varias
computadoras de la red y estas son transparentes para el usuario.

Parte de
Proceso de
Proceso la Aplicación

Estación A

Parte de
Proceso
Resultados

Estación B

Proceso Cooperativo.

Existen tres tipos de procesos para el Modelo Cooperativo, que son : Peer-to-
peer, RPC y Cliente/Servidor.

CLIENTE/SERVIDOR

En un sistema Cliente/Servidor, uno o más clientes y uno o más servidores,


juntos con el sistema operativo y los protocolos de comunicación, conforman
el ambiente que permite y facilita el computo distribuido.

En una aplicación basada en esta arquitectura existen dos procesos


independientes, en lugar de uno solo. De esta forma se puede repartir el
trabajo a través de varias computadoras en una red. Estos dos procesos, el
cliente y el servidor, se comunican mediante un protocolo bien definido. Esta
técnica modular permite la comunicación entre distintas computadoras
(Servidor de archivos, estaciones de trabajo con alta calidad de graficación,
etc ), para que cada uno de ellos se dedique a realizar el trabajo que realiza
mejor.

Material de estudio Página: 91 de 249


Visual Basic 6.0 y SQLServer 7.0

De manera introductoria, se puede decir que un servidor es un sistema o un


programa en un sistema que provee de algún servicio a otros sistemas a
través de una Red. Un ejemplo típico es un servidor de archivos, que permite
el acceso a información remota a cualquier usuario a través de la red. Un
cliente es un sistema o un programa que requiere y recibe alguna acción de
un servidor.

Existen varias interpretaciones acerca de la definición exacta de que es la


computación Cliente/Servidor y en vez de discutir una definición precisa mejor
discutiremos las características que debe cumplir.

Básicamente la arquitectura Cliente/Servidor es aprovechar la computación


que esta en procesos separados sobre separadas plataformas, interactuando
una con otra permitiendo el aprovechamiento de recursos, mientras toman la
mejor ventaja de los diferentes dispositivos.

Si bien no existe una definición precisa de Cliente/Servidor que sea aceptada


por el ámbito informático, si existen diez características que debe cumplir. Las
cinco primeras son aceptadas como obligatorias y las cinco restantes como
opcionales, precisando aún más como deseables, las cuales son:

1La arquitectura Cliente/Servidor, consiste en un proceso cliente y un proceso


servidor, distinguiéndose uno de otro, sin embargo pueden interactuar
conjuntamente.

2La parte del cliente y la del servidor, pueden operar en plataformas diferentes
y esto generalmente ocurre, pero no necesariamente.

3La plataforma del cliente o del servidor, puede ser actualizada sin que esto
implique actualizar ambas.

4El servidor dispone de servicios múltiples de concurrencia de clientes, en


algunos sistemas el cliente puede tener acceso a múltiples servicios.

5El sistema Cliente/Servidor incluye capacidad de administración de la red.

6Una parte significativa (en algunos casos, no todos) de aplicaciones lógicas,


residen en el cliente.

7Usualmente la acción es iniciada por el cliente final y no por el servidor final,


sin embargo, servidores de base de datos pueden tomar acciones basados en
disparadores, como una política de la organización o proceso almacenado.

8Una interfaz gráfica amigable GUI (Graphical User Interface), generalmente


reside en el cliente.

9La capacidad de un lenguaje estructurado de consulta (SQL), es característica


de la mayoría de los sistemas Cliente/Servidor.

10 El servidor de base de datos, debe proveer seguridad y protección de datos.

Material de estudio Página: 92 de 249


Visual Basic 6.0 y SQLServer 7.0

DESCRIPCION FUNCIONAL

De manera general, para iniciar la comunicación entre un cliente y un servidor


es necesario establecer una sesión. Por lo tanto, el servidor debe estar
esperando ó escuchando que algún cliente trate de establecer una sesión,
esto quiere decir que un cliente trate de “hablar” pero si no es “escuchado” la
comunicación fracasará. Es muy posible que por algún momento el servidor
también “hable” y que el cliente “escuche”, pero esto sólo ocurrirá cuando el
servidor así se lo indique al cliente.

Un servidor también se reserva el derecho de establecer comunicación con


uno o más clientes. Así, el servidor se encargara de atender a cada cliente y
establecer los mecanismos que seguirá para la distribución de sus servicios.
Un servidor define operaciones que son exportadas a los clientes, los clientes
invocan estas operaciones para que el servidor controle el manejo de datos.

Típicamente, una aplicación cliente comenzará una transacción, ejecutará una


o varias operaciones en el servidor y terminará la transacción. Lógicamente,
los servidores están estructurados como un ciclo infinito. El servidor
simplemente recibe los requerimientos de los clientes para invocar
operaciones en favor de esas transacciones. Para implantar las operaciones
que exporta, el servidor puede requerir de otro servidor o puede manipular
sus propios datos.

Bajo este esquema, se reparte el proceso de una aplicación entre un front-end


(Cliente) y un back-end (Servidor), cuyas funciones se distinguen como se
muestra a continuación:

FRONT-END BACK-END

PROGRAMA DE SERVIDOR DE BASE DE


APLICACIÓN
- Diseño de formas DATOS
- Almacenamiento
- Presentación - Seguridad
- Lógica de la aplicación - Administración de datos
- Manejo de datos - Selección de registros
- Consultas - Reorganización de la BD
- Menús - Indexación
- Utilerías - Ordenamientos
- Actualizaciones en lote

Comparación de funciones: Front-end vs Back-end.

SISTEMAS ABIERTOS “OPEN SYSTEM”

Muchas organizaciones han instalado una variedad de plataformas, y en cada


una de ellas manejan información necesaria para la vida de las organización.
El reto de los sistemas abiertos y con ellos los estándares, está en hacer que
estas diferentes plataformas trabajen de manera conjunta.

Material de estudio Página: 93 de 249


Visual Basic 6.0 y SQLServer 7.0

Los estándares permiten mejorar la compatibilidad, dejan mayor libertad al


usuario para elegir lo que más convenga a sus necesidades tanto de hardware
como de software, permite explotar nuevas tecnologías y generan un
ambiente de competencia tanto en precios, como en el desempeño en el
mercado.

Un sistema abierto es aquel basado en un ambiente independiente a


fabricantes, cuyas especificaciones son aceptadas, disponibles y
estandarizadas. En estos sistemas los usuarios pueden mezclar hardware y
software de diversos fabricantes en redes muy diversas. Los sistemas abiertos
son de crucial importancia en el ambientes de computo distribuidos ya que
estos son construidos con sistemas de diversos proveedores de computadoras,
redes, manejadores de base de datos y aplicaciones.

A pesar de que los estándares de programación y de comunicaciones han


evolucionado por décadas, UNIX de AT&T fue el primer sistema operativo que
funciono en diversas plataformas con éxito, permitiendo escalabilidad,
portabilidad e interoperabilidad, como ventajas características.

Interoperabilidad Significa que dos sistemas pueden trabajar


conjuntamente a través de interfaces bien definidas, por
ejemplo, una aplicación desarrollada en el sistema operativo
UNIX puede interactuar con aplicaciones para los sistemas
operativos OS/2 y MVS. Estas aplicaciones deben tener
interfaces que permiten intercambiar información.

Portabilidad Significa que las aplicaciones deben ser independientes de


las plataformas, de tal manera que cambios que sufran las
plataformas existentes no signifiquen modificaciones a las
aplicaciones. Las aplicaciones desarrolladas en una
plataforma deben ser transportadas y utilizables en otras
plataformas.

Integración Se refiere a la facilidad con la cual un sistema puede ser


usado. Un sistema integrado básicamente minimiza el
esfuerzo necesario para utilizarlo.

Los estándares son necesarios para hacer a los sistemas abiertos una
realidad. Un gran número de estándares han sido desarrollados para cumplir
con interoperabilidad, portabilidad e integración. Estos estándares son
desarrollados por la ISO (International Standard Organization). Los estándares
TCP/IP y XWindows son claros ejemplos de sistemas abiertos.

INFRAESTRUCTURA DE SOFTWARE CLIENTE/SERVIDOR

El término Cliente/Servidor, en primera instancia es un termino complejo y


abstracto, de la misma forma tanto las empresas de computo, como los

Material de estudio Página: 94 de 249


Visual Basic 6.0 y SQLServer 7.0

especialistas en sistemas hacen referencia a él, como un modelo o como una


arquitectura.

En un sentido estricto, de acuerdo a la definición del diccionario:

MODELO. “Es un objeto que se reproduce o se imita. Representación de


alguna cosa en pequeña escala. Técnicamente es la construcción de una o
varias piezas para hacer el molde en el cual se vaciarán los objetos”.

En tanto que:

ARQUITECTURA. “Arte de proyectar, construir y adornar. Forma, estructura”


Por lo tanto Cliente/Servidor, es la conjunción de varias piezas que
primeramente se diseñarán a escala para posteriormente reproducirse como
un esquema digno de imitarse, Pero, ¿dónde esta la interconexión de
componentes?. Desde luego, que aquí entra la infraestructura de
comunicación entre los elementos o piezas adicionales a su ubicación para
construir el sistema.

Podemos decir que la Infraestructura Cliente/Servidor es la integración


distribuida y abierta de un sistema en red, con los recursos, medios y
aplicaciones, que definidos modularmente en los servidores, administran,
ejecutan y atienden peticiones de los clientes, todos interrelacionados física y
lógicamente, compartiendo datos, procesos e información, estableciendo así
un enlace de comunicación transparente entre los elementos que conforman la
estructura.

Los elementos que conforman la estructura Cliente/Servidor son : El Cliente,


El Servidor y Software De Comunicación.

Software de
CLIENTE SERVIDOR
Comunicación

Estructura básica de la arquitectura Cliente / Servidor.

Una idea simple de la computación Cliente/Servidor es, que el servidor acepta


requerimientos de datos de un cliente y retorna los resultados a éste. El
cliente manipula los datos y presenta los resultados al usuario.

La computación cliente/servidor no se basa solo en los componentes del


hardware, sin menospreciar sus cualidades, lo que hace posible esta
tecnología es el software. Al dividirse las tareas entre el cliente y el servidor,
pueden ser procesadas en diferentes: plataformas, Sistemas Operativos y
Protocolos de Comunicación, teniendo como resultado un desarrollo más
rápido de la aplicación donde están envueltas. Entonces el usuario podrá
accesar los datos con una interfaz gráfica agradable, que despertará su
interés e invitación y sin la necesidad de capacitaciones exhaustivas.

Material de estudio Página: 95 de 249


Visual Basic 6.0 y SQLServer 7.0

EL CLIENTE: Es un consumidor de servicios provistos por uno o más


servidores (acceso a la base de datos, servicio de impresión,
correo electrónico). desarrolla parte y en ocasiones toda la lógica
de aplicación, brinda servicios de presentación al usuario a través
de una interfaz gráfica.

EL SERVIDOR: Es diseñado con el objetivo de dar servicio, sus capacidades


de hardware son mayores a las del cliente, generalmente, a
través del DBMS que radica en él, puede recuperar, actualizar y
almacenar los datos. Administra los recursos de la red,
dispositivos y demás servicios con los que cuente.

SOFTWARE DE COMUNICACIÓN: Por medio de él se realiza la comunicación


entre el cliente y el servidor, administra el flujo de datos a través
de la red, permite la comunicación hacia otros sistemas (por
medio de ruteadores, puentes y gateways). Es responsable de
detectar problemas y recuperación de datos por coaliciones.

Una aplicación envuelve varias tareas las cuales pueden ser llevadas a cabo
en el modulo cliente o el del servidor, con el fin de entender mejor como se
realiza una aplicación la dividiremos en seis tareas, las cuales son :

1. INTERFACE PARA EL USUARIO. Cuenta con un dispositivo que


acepta entradas del usuario y las despliega en la lógica de
presentación. Este dispositivo puede simplemente desplegar
caracteres recibidos de un teclado o un dispositivo que reciba señales
de un mouse.

2. LÓGICA DE PRESENTACIÓN. Controla la interacción entre el usuario


y la computadora. Esta es la especificación que el usuario realiza
cuando selecciona un menú de opciones, un botón de selección o
escoge un elemento de una lista.

3. LÓGICA DE APLICACIÓN. Es una colección de decisiones, cálculos y


operaciones que la aplicación puede llevar a cabo. Esta puede incluir
los cálculos del pago a empleados, la decisión de aceptar una orden de
compra, la evaluación de cargar una aplicación o el procedimiento de
realizar una transacción la cual ha sido transferida.

4. LÓGICA DE DATOS. Es la expresión de las operaciones desarrolladas


en la base de datos que son necesarias para realizar la lógica del
negocio. Como la mayoría de los manejadores de bases de datos se
basan sobre el modelo relacional, las expresiones son instrucciones en
SQL como el Select, Insert y Update.
5. SERVICIO DE DATOS. Son las acciones que el DBMS toma para
realizar la lógica de datos, incluyendo la manipulación, la definición y
la transacción de los mismos. Para manipular datos el DBMS
típicamente compila las instrucciones en SQL.

Material de estudio Página: 96 de 249


Visual Basic 6.0 y SQLServer 7.0

6. SERVICIO DE ARCHIVOS. Accesa el disco y trae los bits que se


convierten en datos cuando son vistos a través del DBMS. Los
servicios de archivos son usualmente realizados por funciones del
sistema operativo.

En el ambiente Cliente/Servidor, una aplicación se puede almacenar, dentro de


los clientes, en los servidores o parcialmente en ambos dependiendo de las
características y capacidad del equipo, así como de las necesidades
particulares en cuanto al acceso a datos e información; de esta manera, es
responsabilidad del área de Sistemas así como de los diseñadores de la red,
definir "desde la etapa de Planeación", cómo serán estructuradas las
aplicaciones y componentes dentro del sistema en red.

A continuación se muestra una clasificación de alternativas, para organizar las


aplicaciones sobre la base del acceso a la información como se muestra a
continuación.

Presentación Distribuida: Se separan los datos, procesos y presentación en


el servidor y solo una parte de la presentación se ejecuta en el
cliente. Donde varios usuarios pueden accesar los mismos datos
desde los diferentes servidores y cada uno visualiza
exclusivamente la información que solicita. Por ejemplo. la
consulta e impresión de las listas de proveedores que maneja el
Departamento de Compras de la empresa, adicionándole los
datos personales del usuario. Este tipo de estructura hace uso
del poder gráfico de los clientes y permite compartir las
aplicaciones existentes.

Presentación Remota: Se concentran los datos y procesos en el servidor y la


presentación se ejecuta en el cliente. Aquí se aprovechan las
capacidades particulares de cada cliente, de tal manera que el
usuario por su parte, puede accesar los datos que requiera,
manipularlos con sus propias herramientas creando y/o
modificando libremente la presentación y salida de la
información. Por ejemplo, un vendedor de seguros realiza una
consulta a la base de datos (servidor) de las diferentes primas
que se tienen registradas para los automóviles modelo 94, al
visualizar la información, utiliza su procesador de textos para una
mejor presentación y así obtiene los reportes requeridos.

Función Distribuida: Se tienen los datos y procesos en el servidor, pero


parte de los procesos conjuntamente con la presentación, se
ejecutan con los recursos propios del cliente. Aquí el principal
aspecto es el uso y manejo de ciertas subrutinas y/o programas
dentro de lo servidores, mismas que pueden ser utilizadas tantas
veces como sean requeridas, sin tener que reescribirlas o
particularizarlas para cada cliente. Por ejemplo, se puede
solicitar la consulta de las cifras de ventas por los últimos dos
trimestres, a las diferentes subsidiarias (bases de datos), dónde
internamente se efectúa un proceso de selección de datos, el
concentrado de información se recibe en el servidor local y a su
vez el cliente ejecuta el proceso correspondiente para obtener los

Material de estudio Página: 97 de 249


Visual Basic 6.0 y SQLServer 7.0

datos de su empresa, así mediante ciertas instrucciones


predefinidas conjunta la información y obtiene el informe
requerido.

Acceso Remoto de Datos: Los datos se almacenan en el servidor, de esta


forma los procesos y la presentación se ejecutan desde el cliente.
Básicamente es el modo de acceso utilizado en el software de
correo electrónico, dónde se solicitan consultas de información a
bases de datos remotas, de la misma forma que se recibe y se
envía información de otros clientes. Por ejemplo, consultas a las
bibliotecas de las diferentes universidades nacionales y del
extranjero.

Base de Datos Distribuida: Todos los datos se concentran en los servidores,


pero cierta porción de información así como los procesos y
presentación se accesan con los recursos del cliente. Este tipo
de estructura permite la comparación de datos a cualquier nivel
dentro de la empresa, dónde cada usuario puede manipular la
información de su área o departamento y compartirla con la de
otros en forma simultánea. Por ejemplo, una empresa puede
tener una base de datos única dónde concentre la información
relacionada a las existencias en almacén de sus productos, de tal
forma que las altas, bajas y cambios se efectúan en línea y al ser
consultadas por cualquier persona dichas modificaciones se
visualizan por todos los demás usuarios.

Acceso Dase de
Presentación Presentación Función Remoto de Datos
Distribuida Remota Distribuida Datos Distribuida

Manejo de Manejo de Manejo de Manejo de Manejo de


Datos Datos Datos Datos Datos
RED

S
E Logica de Logica de Logica de Manejo de
R Aplicación Aplicación Aplicación Datos
C
V
L
I
I
D
E
O
Lógica de Logica de Logica de Lógica N
R Presentación Aplicación Aplicación Presentación T
E

RED
Lógica de Lógica de Lógica de Lógica de Lógica de
Presentación Presentación Presentación Presentación Presentación

División de un procesos del Cliente y del Servidor .

Material de estudio Página: 98 de 249


Visual Basic 6.0 y SQLServer 7.0

EL CLIENTE

Características del Cliente:

• Es el medio de enlace y/o comunicación entre el usuario y el computadora.


• Es la entidad que requiere o solicita el servicio.
• Requiere el uso de los recursos del computadora para realizar cualquier
actividad.
• Es el medio por el cual se envía la solicitud y se reciben los resultados o
notificaciones del servidor.
• Contiene la interface gráfica (GUI).
• Puede interactuar con uno o varios servidores.
• Es el responsable de mantener el diálogo con el usuario.
• Su costo comparado con un servidor es considerablemente más bajo.

Funciones principales del Cliente :

• Inicia y termina la solicitud.


• Permite el manejo de la pantalla y ventanas.
• Presenta la información y/o datos.
• Interpreta los comandos.
• Maneja procesos de ayuda.
• Recibe las entradas provenientes del mouse , teclado y touch-screen.
• Permite controlar las cajas de diálogo.
• Habilita el manejo de multimedia (si es el caso).

EL SERVIDOR

Es la entidad física que provee un servicio, se encuentra la ejecución de


procesamiento de datos, aplicaciones, manejo de la información y recursos. En
el reside el BACK-END, que es la parte destinada a recibir las solicitudes del
cliente y donde se ejecutan los procesos.

Un servidor es considerado, por muchos, como la conjunción de Hardware y


Software que ejecuta tareas específicas.

Sus principales características son:

• Responde a las peticiones de los clientes.


• Tiene gran capacidad de almacenamiento y rapidez.
• Provee el uso de los recursos y servicios a los clientes.
• Es el administrador de los recursos de la red
• Tiene capacidad de procesamiento transaccional.
• Puede actuar como cliente de otros servidores.
• Contiene los datos, programas, aplicaciones, software e información.
• Realiza procesos como accesar, organizar, almacenar, actualizar y manejar
datos o recursos compartidos.

SOFTWARE DE COMUNICACIÓN

Material de estudio Página: 99 de 249


Visual Basic 6.0 y SQLServer 7.0

Algunos profesionales del ámbito informático, utilizan el termino


“Middleware”, el cual crea más confusión que contribución, ya que es usado
indistintamente. Utilizaremos el término software de comunicación, para
describir las capacidades de comunicación entre el cliente y el servidor.

Material de estudio Página: 100 de 249


Visual Basic 6.0 y SQLServer 7.0

LA RED

La arquitectura de la red define los protocolos, formato de los mensajes y


estándares que se usarán. Una arquitectura de red robusta usa una estructura
de capas, cada capa consiste en entidades compuestas por hardware y
procesos de software, las normas y formatos para comunicación entre capas
adyacentes son colectivamente llamadas una interface. Los protocolos son las
normas y formatos para comunicación dentro de la misma capa, a través de
diferentes dispositivos, incluyen formatos y el orden de los datos para su
intercambio y cualquier acción para la transmisión y recepción de datos

El sistema operativo es el corazón y alma de la red. El hardware del sistema


proporciona las trayectorias de datos y las plataformas en la red, pero el
sistema operativo es el encargado de controlar todo lo demás. La
funcionalidad, la facilidad de uso, el rendimiento, la administración. la
seguridad de los datos y la seguridad de acceso, dependen del sistema
operativo.

Actualmente existen en el mercado varios sistemas operativos de red, cada


uno tiene su forma de operar, proporcionando mayor seguridad unos que
otros, por lo cual, cada uno tiene una participación diferente en el mercado;
no obstante, una de las direcciones más claras para el desarrollo de sistemas
futuros es hacia estrategias similares de diseño.

BONDADES Y DESVENTAJAS

De lo expuesto se resume que, el ambiente Cliente/Servidor ofrece las


siguientes ventajas:

• Permite la integración de los recursos y elementos del sistema en red.


• Incrementa aún mas la productividad y el desempeño de la red.
• Permite el uso y comparación de los sistemas y recursos
interconectados.
• Incrementa la velocidad de respuesta al usuario.
• Evita el sustituir totalmente los equipos instalados.
• Permite el ensamble de las aplicaciones heredadas (legancy systems)
ya existentes con las aplicaciones y software que se están
desarrollando.
• Permite la integración abierta en plataformas multivendor.
• Reduce los costos de mantenimiento de software.
• Agiliza el tráfico en la red y tiempos de respuesta.
• Mejora la administración y el control de los procesos y recursos en red.
• Propicia un ambiente para la implantación de nuevas tecnologías.
• Incrementa el nivel de calidad y obtención de información.
• Reduce tangiblemente los costos del sistema una vez implantado la
arquitectura Cliente/Servidor.

Material de estudio Página: 101 de 249


Visual Basic 6.0 y SQLServer 7.0

Dentro de un ambiente idóneo y "perfecto" como el que se vislumbra bajo ésta


arquitectura, también es importante mencionar su lado gris, las principales
desventajas son:

• La migración e implantación es costosa ya que se requiere de


servidores poderosos, equipos y recursos.
• Requiere necesariamente de una infraestructura de comunicación en
red.
• Se requiere de software y aplicaciones adicionales a las ya existentes
como parte del software de comunicación para conformar el nuevo
sistema.
• Las aplicaciones para Cliente/Servidor son en ocasiones más complejas
que las convencionalmente utilizadas.
• Aún no existen estándares específicos y reconocidos universalmente
que reglamenten esta arquitectura.

Sin embargo, conforme la arquitectura vaya madurando seguramente estos


puntos dejarán de ser desventajas, puesto que los expertos ya trabajan sobre
ello para desarrollar los productos que cubran dichas deficiencias.

Material de estudio Página: 102 de 249


Visual Basic 6.0 y SQLServer 7.0

2.2 Que es ODBC

Lo que dice Microsoft:


ODBC (Conectividad abierta a bases de datos)
La tecnología proporciona una interface común para acceder bases de datos heterogéneas
basadas en SQL. ODBC esta basado en el lenguaje Estructurado de consultas (SQL) como una
norma para acceder a los datos. Esta interface proporciona interoperabilidad al máximo: no solo
la aplicación puede acceder bases de datos de diferentes Sistemas basados en SQL, a través de
un juego común de código. Esto le permite a un diseñador construir y distribuir una aplicación
cliente/servidor sin tener un DBMS específico. Se agregan drivers para unir la aplicación, a la
base de datos destino, con el fin de que el usuario elija el DBMS deseado.

La flexibilidad de ODBC se caracteriza por:

 ODBC esta diseñado con la interface de nivel de llamadas estándar de la ISO


 No se atan aplicaciones a un propietario API.
 Las declaraciones SQL pueden ser incluidas explícitamente en código fuente o construidas
en tiempo de ejecución de la aplicación.

 Una aplicación puede ignorar los datos subyacentes de los protocolos de comunicaciones.
 Pueden enviarse y recibirse datos en un formato conveniente a la aplicación.
 Existen más de 55 drivers para accesar a las bases de datos más populares.

Material de estudio Página: 103 de 249


Visual Basic 6.0 y SQLServer 7.0

Lo que pienso:
ODBC es un intermediario entre bases de datos y aplicaciones, cuya tarea es sostener una
conversación de preguntas y respuestas entre dos "sujetos" que no hablan el mismo idioma y que
gestionan sus recursos de forma diferente, esto es una abstracción de un concepto muy
tecnificado. Concretando, puedes tener un CAD, una hoja de calculo, un editor de texto, etc.,
cuyas finalidades son las que quieras, menos gestionar datos en la forma que lo hace un sistema
de base de datos; estas aplicaciones no saben como se obtienen y se guardan datos en, por
ejemplo, un archivo MDB de Microsoft Access, o en un DBF, o en SQL Server, o en algún otro.
Por otra parte, pero en lo mismo, que tal si un usuario de Paradox quiere extraer información de
SQL Pato, un nuevo sistema de lo más avanzado que nadie conoce pero que alguien uso para
guardar información que resulta necesaria (no sabes cuántas veces sucede), ambos son sistemas
de bases de datos, Paradox conoce la forma de leer los archivos de los sistemas conocidos, pero
no los de SQL Pato.

En el ambiente Windows, Microsoft creó la tecnología ODBC pensando en este problema. No es


una solución de la comunidad informática del orbe, es de Microsoft, y por eso se basa en los
impulsos estomacales del corazón de Microsoft; esto quiere decir que no se esta recomendando
esta tecnología, sino que mientras sea en Windows, hay que usarla cuando no hay algo mejor,
punto. ODBC es una utilería que alberga controladores. La utilería sirve para gestionar los
controladores, y los controladores son los que saben "hablar" con las bases de datos. Entonces el
"acuerdo" entre Microsoft y los fabricantes de software para Windows fue: "Ustedes, que hacen
software no especifico para bases de datos, enseñen, si quieren, a sus aplicaciones a
comunicarse con el armatoste llamado ODBC; y ustedes, fabricantes de bases de datos, hagan
controladores de sus sistemas para ponerlos en la utilería, si quieren que otras aplicaciones
puedan accesar su información".

Así Excel puede leer una base de datos en Access o SQL Server, incluso SQL Pato (si es que
alguien fabricó un controlador de ODBC). Siendo sinceros, esas no son todas las razones ni los
intereses por los que ODBC fue implementado, hay cierta oscuridad por ahí.

En ODBC no se tiene que hacer gran cosa, es una simple tarea, se llama crear un origen de
datos, otros le denominan fuente en vez de origen.Un origen o fuente de datos consiste en el
nombre, el controlador y la base de datos. Por ejemplo, si un usuario quiere tener acceso a una
base de datos de Access, digamos que se llama Negocio.mdb, desde una hoja de cálculo de
Excel para consultar su volumen de ventas por país, este usuario crea un nuevo origen de datos
en ODBC llamado Volumen_Ventas (este es, pues, el nombre), después selecciona un
controlador para Microsoft Access e indica el archivo de base de datos está en
"c:\LaEmpresa\Administración\Negocio.mdb". Eso es básicamente de lo que se trata.

Las aplicaciones creadas específicamente para Windows 95, 98 y NT usan el ODBC de 32 bits;
pero algunos sistemas conservan un ODBC de 16 bits para las aplicaciones de legado que
corrían o corren en Windows 3.11.

Al iniciar ODBC de 32Bits la tres pestañas se refieren a: User DSN, System DSN y File DSN,
versión en inglés, traduciendo un poco:

User DSN: nombre del origen de datos para el usuario. A veces, una máquina es utilizada por
más de un usuario, los orígenes de datos declarados aquí son exclusivos del usuario.

Material de estudio Página: 104 de 249


Visual Basic 6.0 y SQLServer 7.0

System DSN: nombre del origen de datos para el sistema. Todos los usuarios de la máquina
tienen acceso a estos orígenes de datos.

File DSN: nombre del origen de datos en archivo. Se crea un archivo con la extensión DSN, que
sirve como origen de datos y puede ser distribuido a otros usuarios. Este origen es el que usa
Excel por omisión cuando hace consultas, cuidado con eso.

Otra petaña importante que es ODBC Drivers o Controladores ODBC. Aquí se ven todos los
controladores disponibles en la máquina. De está forma se puede consultar si se dispone del
controlador que se necesita y si es la versión conveniente. Regularmente los controladores de
bases de datos vienen con un programa de instalación que los instala y quedan dados de alta en
esta lista.

Las otras pestañas merecen explicarse aparte, ya que están fuera del alcance de este curso.

2.3 Conexiones Cliente – Servidor.

La comprensión del paradigma cliente - servidor contribuye a la correcta implementación de


servidores de motores de bases de datos remotos. Los programadores que no tengan
experiencia en el desarrollo cliente - servidor pueden cometer fácilmente errores que hagan
que sus aplicaciones fallen o tengan un rendimiento bajo. Dichos fallos pueden conducirles a
malinterpretar el concepto cliente - servidor o los componentes de desarrollo utilizados para
desplegar el sistema.
Por ejemplo, el diseño de tablas con demasiadas columnas o que no estén correctamente
normalizadas puede privar de muchas de las ventajas del modelo de base de datos relacional.
Los diseños que extraen tablas enteras o que crean cursores que contienen demasiadas filas
también pueden conducir a un rendimiento no deseado, independientemente del modelo de
programación.
La programación de aplicaciones para sistemas de servidores centrales, especialmente para
sistemas que tienen acceso a grandes cantidades de datos o tienen cientos de usuarios, es
muy diferente de la programación de sistemas de bases de datos basados en ISAM planos.
Cuando desarrolle una aplicación que tenga acceso a una base de datos remota, debe
implementar un modelo relacional cuidadosamente diseñado. Aunque es algo que podría dejar
para una fecha posterior en un intento de mejorar el rendimiento, sería como intentar modificar
el sótano de su casa después de haber terminado el último piso.
Antes de tomar la decisión final sobre el modelo de programación que va a implementar, debe
tener en cuenta una serie de aspectos que afectan al diseño independientemente del modelo.

Para tener acceso a un servidor remoto, su aplicación tiene que establecer una conexión. Esta
conexión crea un vínculo de comunicaciones en la red entre el servidor y el cliente. A su
aplicación se le pasa un controlador de esta conexión. Una vez creada, la conexión
proporciona acceso a un servidor específico, a una de las bases de datos del servidor y a
cualquiera de los objetos temporales específicos de la conexión que su aplicación cree en el
servidor.

Material de estudio Página: 105 de 249


Visual Basic 6.0 y SQLServer 7.0

2.4 Establecimiento de conexiones cliente-servidor.


Dependiendo del modelo de programación cliente-servidor de acceso a datos que elija, puede
establecer una conexión con un servidor remoto desde el código con los siguientes métodos
descritos.

En Visual Basic, existen tres formas de acceso a datos: ActiveX Data Objects (ADO), Remote
Data Objects (RDO) y Data Access Objects (DAO). Una interface de acceso a datos es un modelo
de objetos que representan una forma de accesar datos desde una B.D. la última versión de
conexión es ADO es simple y más flexible, ya que contiene la facilidad de uso de DAO y la
robustes de RDO.

Todas estas técnicas crean una o varias conexiones que vinculan la instancia específica de
su aplicación con el servidor remoto. En algunos casos, está limitado a un número de
conexiones relativamente bajo; con Microsoft SQL Server Workstation Edition son 15 o
menos. En otros casos, dicho número puede ser relativamente alto (32.767), como con SQL
Server Enterprise Edition. No todas estas técnicas tienen el mismo nivel de rendimiento. Por
ejemplo, utilizar DAO para abrir directamente una base de datos remota puede ser muy
costoso en tiempo y en recursos de red.
Nota Compruebe con el administrador del servidor el número de conexiones disponibles.
Éstas pueden estar limitadas por restricciones de licencia o de recursos. Como una única
aplicación puede crear cualquier número de conexiones, el número de usuarios que su
servidor remoto acepta puede estar limitado por su capacidad de administrar suficientes
conexiones.

Puede que en su aplicación no sea necesario mantener una conexión permanente con el
servidor remoto, pero en algunos casos la pérdida de una conexión puede hacer que se
pierdan los objetos temporales específicos de la conexión. En un sistema multiusuario, la
administración de las conexiones se hace mucho más importante porque el número total de
usuarios conectados a una base de datos puede estar limitado por el número de conexiones
que utilice cada aplicación. Dependiendo del servidor y del número de conexiones
disponibles, puede ser más eficiente dejar una o varias conexiones establecidas durante toda
la vida de la aplicación. En otros casos, puede que tenga que abrir y cerrar conexiones lo más
rápidamente para dar cabida a otros usuarios debido al número limitado de controladores de
conexión. Asegúrese de que la interfaz de programación que elija acepte una estrategia de
conexión adecuada.

La mayoría de los modelos de programación de acceso a datos utilizan esquemas de bloqueo


de páginas de 2 KB. Generalmente, esto significa que cuando una fila (registro) queda
bloqueada para su actualización, toda la página (y todas las demás filas de la página) también
permanecen bloqueadas durante la operación. Algunas veces, cuando la operación de
actualización o eliminación afecta a un gran número de filas, el DBMS puede pasar los
bloqueos de página a bloqueos de tabla para acelerar el proceso. Cuando se utiliza SQL
Server , puede controlar el número de bloqueos de página que provocan el bloqueo de la
tabla mediante el uso de opciones de escalado del bloqueo. También puede especificar el
bloqueo de fila en los sistemas SQL Server
Todas las filas de una página de datos pertenecen a la misma tabla. Por este motivo, puede
aliviar las situaciones de bloqueo si modifica la distribución de las columnas en su base de
datos. Este proceso de normalización distribuye la información de las columnas sobre tablas
relacionadas. Si su tabla tiene un tamaño de fila que se aproxima al límite de 2 KB,
probablemente necesite implementar cierto grado de normalización, lo que minimiza la

Material de estudio Página: 106 de 249


Visual Basic 6.0 y SQLServer 7.0

duplicación de información en una base de datos relacional mediante un diseño eficiente de


las tablas.
Nota Si el tamaño de una fila individual es mayor de 1 KB, en cada página de 2 KB sólo se
coloca un fila porque las filas no ocupan más de una página.

2.5 Estrategias de bloqueo.

Todos los modelos de programación de acceso a datos de Visual Basic proporcionan varios
métodos de bloqueo. A veces puede controlar el grado de bloqueo mediante:
• Operaciones de transacción (BEGIN TRANS/COMMIT TRANS).
• Un HOLDLOCK.
• Otros parámetros en las instrucciones SQL SELECT.

En general, las recomendaciones siguientes le ayudarán a definir una estrategia de bloqueo.


Asegúrese de elegir una interfaz de programación que proporcione la flexibilidad necesaria
para implementar las recomendaciones que considere importantes.
• Evite las situaciones en las que varios procesos intenten realizar actualizaciones o
inserciones en la misma página de datos. Por ejemplo, esto puede ocurrir en una tabla no
indexada, porque todas las inserciones se aplican a la última página de la cadena. Cree
tablas distintas de historial para cada grupo de usuarios para minimizar los retrasos
provocados por esta situación. Además, cree un índice agrupado para distribuir datos en
varias páginas.
• Evite las transacciones que incluyan interacción con el usuario. Como los bloqueos se
mantienen durante toda la transacción, un único usuario puede bloquear todo el sistema.
• Haga que las transacciones que modifiquen datos sean lo más breves posible. Cuanto más
larga sea la transacción, más tiempo duran los bloqueos, bloqueando así otras actividades
y provocando un aumento en el número de situaciones de punto muerto.
• Agrupe las transacciones en un único lote. Problemas inesperados de red pueden retrasar
la finalización de las transacciones y, por tanto, la liberación de los bloqueos.
• Los sistemas SQL Server utilizan lecturas repetibles, niveles de aislamiento serializables o
SELECT con HOLDLOCK sólo cuando es necesario. Las actualizaciones pueden
retrasarse esperando la liberación de los bloqueos.
• En sistemas SQL Server, reduzca el factor de ocupación (que determina el porcentaje de la
página que SQL Server llena cuando crea un nuevo índice sobre datos existentes) cuando
cree un índice para evitar la posibilidad de que actualizaciones aleatorias requieran la
misma página. Esto es especialmente útil en tablas pequeñas con acceso frecuente.

Material de estudio Página: 107 de 249


Visual Basic 6.0 y SQLServer 7.0

3 SQL Server 7.0

Introducción
El principal objetivo de una base de datos de Microsoft SQL Server es almacenar datos y,
posteriormente, poner esos datos a disposición de las aplicaciones y usuarios autorizados.
Mientras que los administradores de base de datos crean y mantienen las bases de datos, los
usuarios trabajan con el contenido de las mismas al:

• Tener acceso o recuperar los datos existentes.


• Cambiar o actualizar los datos existentes.
• Agregar o insertar nuevos datos.
• Eliminar los datos existentes.

El acceso y modificación de datos en Microsoft SQL Server se realiza mediante la utilización de


una aplicación o herramienta para enviar peticiones de recuperación y modificación de datos a
SQL Server. Por ejemplo, puede conectarse a SQL Server con el Administrador corporativo de
SQL Server, el Analizador de consultas de SQL Server o la herramienta osql, y empezar a
trabajar con los datos de SQL Server.

Las aplicaciones y herramientas usan dos componentes para tener acceso a SQL Server:

• Interfaces de programación de aplicación de base de datos (API) para enviar comandos a


SQL Server y recuperar el resultado de esos comandos. Estas API pueden ser API de
base de datos de propósito general, como ADO, OLE DB, ODBC o bibliotecas de bases
de datos. También pueden ser API diseñadas específicamente para usar las
características especiales de SQL Server, como SQL-DMO, SQL-DTS o los componentes
de duplicación de SQL Server.
• Los comandos enviados a SQL Server son instrucciones de Transact-SQL.
Las instrucciones de Transact-SQL se generan con el lenguaje SQL definido en la
Referencia de Transact-SQL. La mayor parte de estas operaciones se implementa
usando una de las siguientes cuatro instrucciones de Transact-SQL:
• La instrucción SELECT se usa para recuperar los datos existentes.
• La instrucción UPDATE se usa para cambiar los datos existentes.
• La instrucción INSERT se usa para agregar nuevas filas de datos.
• La instrucción DELETE se usa para quitar filas que ya no son necesarias.

Estas cuatro instrucciones forman el núcleo del lenguaje SQL. Cuando se comprenda cómo
funcionan estas cuatro instrucciones, se habrá entendido en gran medida cómo funciona SQL.

Las herramientas de consulta gráficas o basadas en formularios no requieren ningún


conocimiento de SQL. Presentan al usuario una representación gráfica de la tabla. El usuario
puede seleccionar gráficamente las columnas y especificar con facilidad cómo calificar las filas
que desea recuperar.

Algunas aplicaciones, como, por ejemplo, el Analizador de consultas de SQL Server y la


herramienta osql, son programas para ejecutar instrucciones de Transact-SQL. Las herramientas
ejecutan las instrucciones de Transact-SQL introducidas interactivamente o leídas de un archivo.

Para usar estas herramientas, debe ser capaz de construir instrucciones de Transact-SQL.

Las aplicaciones escritas para las API de base de datos de propósito general, como, por ejemplo,
ADO, OLE DB, ODBC o bibliotecas de bases de datos, también envían instrucciones de Transact-

Material de estudio Página: 108 de 249


Visual Basic 6.0 y SQLServer 7.0

SQL a SQL Server. Estas aplicaciones presentan al usuario una interfaz que refleja la función de
empresa que implementan. Cuando el usuario ha indicado qué función de empresa debe
realizarse, la aplicación usa una de las API de base de datos para pasar instrucciones SQL a SQL
Server. Para codificar estos tipos de aplicaciones, debe conocer las instrucciones de Transact-
SQL.

Otras aplicaciones, como el Administrador corporativo de SQL Server, usan un modelo de objetos
que aumenta la eficiencia de la utilización de SQL Server. El Administrador corporativo de SQL
Server usa un modelo de objetos que facilita la tarea de administrar los distintos servidores SQL
Server. Las API como SQL-DMO y SQL-DTS, y los componentes de duplicación usan también
modelos similares de objetos. Sin embargo, los propios objetos se comunican con SQL Server
mediante Transact-SQL. Entender el lenguaje Transact-SQL puede ayudarle a comprender estos
objetos.

Material de estudio Página: 109 de 249


Visual Basic 6.0 y SQLServer 7.0

Crear instrucciones de Transact-SQL


En los fundamentos del acceso y modificación de los datos se explican los elementos básicos
usados para crear instrucciones de Transact-SQL. También se proporciona información acerca de
las funciones que Transact-SQL puede realizar, así como de la funcionalidad similar que ofrecen
las API de bases de datos.

Una instrucción SELECT contiene los elementos comunes usados en las instrucciones de
Transact-SQL. Por ejemplo, para seleccionar los nombres, nombres de contacto y números de
teléfono de los clientes que viven en Estados Unidos de la tabla Customers de la base de datos
Northwind, se usan estos elementos:

• El nombre de la base de datos que contiene la tabla (Northwind)


• El nombre de la tabla que contiene los datos (Customers)
• Una lista de las columnas cuyos datos se van a devolver (CompanyName,
ContactName, Phone)
• Los criterios de selección (sólo para los clientes que viven en Estados Unidos)

A continuación se muestra la sintaxis de Transact-SQL utilizada para recuperar esta información:

SELECT CompanyName, ContactName, Phone


FROM Northwind.dbo.Customers
WHERE Country = 'USA'

Entre los elementos adicionales usados en instrucciones de Transact-SQL se encuentran:

• Funciones
Las funciones se usan en las consultas, informes y muchas instrucciones de Transact-
SQL de SQL Server para devolver información, de forma parecida a como se utilizan las
funciones de otros lenguajes de programación. Toman parámetros de entrada y
devuelven un valor que se puede usar en las expresiones. Por ejemplo, la función
DATEDIFF toma dos fechas y una parte de una fecha (semanas, días, meses, etc.) como
argumentos y devuelve el número de unidades de parte de fecha que hay entre dos
fechas.

• Identificadores
Los identificadores son los nombres dados a los objetos, como, por ejemplo, tablas,
vistas, bases de datos e índices. Un identificador se puede especificar sin delimitadores
(por ejemplo, TEST), con delimitadores entre comillas (por ejemplo, "TEST") o entre
corchetes (por ejemplo, [TEST]).

• Comentarios
Los comentarios son fragmentos de texto que no se ejecutan en el código del programa.

• Expresiones
Las expresiones incluyen valores de constantes o literales (por ejemplo, 5 es un literal
numérico), funciones, nombres de columna, aritmética, operaciones de bits, subconsultas
escalares, funciones CASE, funciones COALESCE y funciones NULLIF.

• Palabras clave reservadas


Las palabras que SQL Server reserva para su propio funcionamiento. Se recomienda
evitar la utilización como identificadores de estas palabras clave reservadas.

• Valores NULL

Material de estudio Página: 110 de 249


Visual Basic 6.0 y SQLServer 7.0

Los valores NULL son aquellos que son desconocidos. Puede usar valores NULL para
indicar que la información se proporcionará posteriormente. Por ejemplo, si la persona de
contacto de la empresa Comercio Leka cambia y no se conoce la nueva persona de
contacto, podría indicar que su nombre es desconocido con un valor NULL.

• Tipos de datos
Los tipos de datos definen el formato en el que se almacenan los datos. Por ejemplo,
puede usar cualquiera de los tipos de datos de carácter o Unicode (char, varchar, nchar
o nvarchar) para almacenar los datos de carácter como, por ejemplo, los nombres de los
clientes.

• Lotes
Los lotes son grupos de instrucciones transmitidas y ejecutadas como una unidad.
Algunas instrucciones de Transact-SQL no se pueden agrupar en un lote. Por ejemplo,
para crear cinco tablas nuevas en la base de datos pubs, cada instrucción CREATE
TABLE debe encontrarse en su propio lote o unidad. A continuación se muestra un
ejemplo de un lote de Transact-SQL:

USE Northwind
SELECT *
FROM Customers
WHERE Region = 'WA'
AND Country = 'USA'
ORDER BY PostalCode ASC, CustomerID ASC
UPDATE Employees
SET City = 'Missoula'
WHERE CustomerID = 'THECR'
GO

• Lenguaje de control de flujo


El lenguaje de control de flujo permite al código del programa emprender una acción en
función de que se cumpla o no alguna condición. Por ejemplo, IF (si) la cantidad de
productos pedida es igual o menor que la cantidad de productos almacenada
actualmente, THEN (entonces) necesitamos pedir más productos.

• Operadores
SQL Server incluye operadores que permiten la ejecución de ciertas acciones en los
datos. Por ejemplo, mediante la utilización de operadores aritméticos puede realizar
operaciones matemáticas como, por ejemplo, sumas y restas en los datos.

Para realizar procesos que no se pueden llevar a cabo con una sola instrucción de Transact-SQL,
Microsoft SQL Server permite agrupar instrucciones de Transact-SQL de varias formas:

• Usar lotes
Un lote es un grupo compuesto por una o varias instrucciones de Transact-SQL que se
envían desde una aplicación al servidor como una unidad. SQL Server ejecuta cada lote
como una unidad ejecutable individual.

• Utilizar procedimientos almacenados


Un procedimiento almacenado es un grupo de instrucciones de Transact-SQL que han
sido definidas y compiladas previamente en el servidor. El procedimiento almacenado
puede aceptar parámetros y devolver conjuntos de resultados, códigos de retorno y
parámetros de salida a la aplicación que realiza la llamada.

• Utilizar desencadenadores

Material de estudio Página: 111 de 249


Visual Basic 6.0 y SQLServer 7.0

Un desencadenador es un tipo especial de procedimiento almacenado. No es llamado


directamente por las aplicaciones. En su lugar, se ejecuta cuando un usuario realiza una
modificación determinada (INSERT, UPDATE o DELETE) en una tabla.

• Utilizar secuencias de comandos


Una secuencia de comandos es una serie de instrucciones de Transact-SQL
almacenadas en un archivo. El archivo se puede usar como entrada para la herramienta
osql o para el Analizador de consultas de SQL Server. Las herramientas ejecutarán
entonces las instrucciones de Transact-SQL almacenadas en el archivo.

Las siguientes características de SQL Server permiten controlar la utilización de varias


instrucciones de Transact-SQL a la vez:

• Instrucciones de control de flujo


Le permiten incluir lógica condicional. Por ejemplo, si el país es Canadá, se realiza una
serie de instrucciones de Transact-SQL. Si el país es Reino Unido, se realiza otra serie de
instrucciones de Transact-SQL.

• Variables
Le permiten almacenar datos para ser utilizados posteriormente como entrada de una
instrucción de Transact-SQL. Por ejemplo, puede que tenga que codificar una consulta
que necesite especificar distintos valores de datos en la cláusula WHERE cada vez que
se ejecuta la consulta. Puede escribir la consulta para que use variables en la cláusula
WHERE y codificar la lógica para que rellene las variables con los datos adecuados. Los
parámetros de los procedimientos almacenados son una clase especial de variables.

• Tratamiento de errores
Le permite personalizar la forma en la que SQL Server responde a los problemas. Pueden
especificar las acciones apropiadas que se llevarán a cabo cuando se produzcan errores,
o generar mensajes de error personalizados que sean más informativos para el usuario
que los errores genéricos de SQL Server.

Material de estudio Página: 112 de 249


Visual Basic 6.0 y SQLServer 7.0

3.1 Permisos
Cada objeto de una base de datos de Microsoft SQL Server tiene un propietario, normalmente el
identificador del usuario activo en la conexión en que se creó el objeto. Otros usuarios no pueden
tener acceso a ese objeto hasta que el propietario autorice a sus identificadores de usuario para
que tengan acceso al objeto.

Ciertas instrucciones de Transact-SQL también están limitadas a determinados identificadores de


usuario. Por ejemplo, la instrucción CREATE DATABASE está limitada a los miembros de las
funciones fijas de servidor sysadmin y dbcreator. Los usuarios no pueden tener acceso a un
objeto o ejecutar una instrucción a menos que hayan sido autorizados a hacerlo.

Todas las instrucciones de Transact-SQL que emite un usuario están sujetas a los permisos que
éste ha recibido. Los miembros de la función fija de servidor sysadmin, los miembros de la
función fija de base de datos dbowner y los propietarios de objetos de base de datos pueden
conceder, denegar o revocar permisos a una persona o función. Cuando use Transact-SQL,
utilice las instrucciones GRANT, DENY y REVOKE para especificar quién puede usar qué
instrucciones de modificación de datos:

• GRANT da permisos para trabajar con datos o ejecutar otras instrucciones de Transact-
SQL.
• DENY deniega un permiso e impide que el usuario, grupo o función especificada herede
el permiso a través de su pertenencia a un grupo o función.
• REVOKE quita los permisos concedidos o denegados previamente.

Los permisos que se pueden conceder a los objetos son:


• SELECT :Permite a un usuario emitir instrucciones SELECT en una tabla o vista.
• INSERT :Permite a un usuario emitir instrucciones INSERT en una tabla o vista.
• UPDATE:Permite a un usuario emitir instrucciones UPDATE en una tabla o vista.
• DELETE :Permite a un usuario emitir instrucciones DELETE en una tabla o vista.
• REFERENCES :Permite a un usuario insertar una fila en una tabla que tiene una clave
externa, que hace referencia a la tabla que se nombra en la instrucción GRANT, DENY y
REVOKE.
• EXECUTE :Permite a un usuario emitir instrucciones EXECUTE en un procedimiento
almacenado.

Los permisos se pueden conceder también para ejecutar instrucciones de Transact-SQL que
normalmente están limitadas a los miembros de una función determinada. Por ejemplo, un
miembro de la función fija de servidor sysadmin puede conceder permisos de CREATE
DATABASE a un usuario que normalmente no podría crear bases de datos.

Material de estudio Página: 113 de 249


Visual Basic 6.0 y SQLServer 7.0

3.2 Utilizar las opciones de SQL Server

Microsoft SQL Server proporciona opciones que afectan al resultado y rendimiento de las
instrucciones SQL. Transact-SQL permite establecer estas opciones de las siguientes maneras:

• Las opciones de configuración del servidor se establecen mediante el procedimiento


almacenado sp_configure.
• Las opciones de base de datos se establecen al ejecutar el procedimiento almacenado
sp_dboptions.
• El nivel de compatibilidad de la base de datos se establece mediante la ejecución del
procedimiento almacenado sp_dbcmptlevel.
• Las opciones de conexión (opciones SET) se especifican con instrucciones SET, como,
por ejemplo, SET ANSI_PADDING y SET ANSI_NULLS.
• Las opciones de instrucción (sugerencias de consultas, de tablas y de combinación) se
especifican en instrucciones individuales de Transact-SQL.

Las aplicaciones ODBC pueden especificar opciones de conexión que controlan algunas de las
opciones de ANSI SET. El controlador ODBC de SQL Server y Microsoft OLE DB Provider for
SQL Server establecen de forma predeterminada varias opciones SET. Las opciones se pueden
establecer también mediante el Administrador corporativo de SQL Server.

Jerarquía de opciones
Cuando una opción se admite en más de un nivel:
1. Una opción de base de datos anula una opción de servidor.
2. Una opción SET anula una opción de base de datos.
3. Un sugerencia anula una opción SET.

Nota sp_configure proporciona la opción user options, que permite cambiar los valores
predeterminados de varias opciones SET. Aunque user options parece una opción del servidor,
es una opción SET.

Material de estudio Página: 114 de 249


Visual Basic 6.0 y SQLServer 7.0

3.2.1 Opciones SET

En esta tabla se incluye una lista alfabética de opciones SET y las correspondientes opciones de
base de datos y de servidor que se admiten en Microsoft SQL Server.

Valor pre-
OPCIÓN SET OPCIÓN DE BASE DE DATOS OPCIÓN DE SERVIDOR
determinado
ANSI null default
ANSI_NULL_DFLT_ON user options asigna
(valor NULL ANSI OFF
ANSI_NULL_DFLT_OFF valor predeterminado
predeterminado)
Valores NULL ANSI user options asigna
ANSI_NULLS OFF
(ANSI nulls) valor predeterminado
user options asigna
ANSI_PADDING Ninguno ON
valor predeterminado
Advertencias ANSI user options asigna
ANSI_WARNINGS OFF
(ANSI warnings) valor predeterminado
El resultado de la
CONCAT_NULL_YIELDS_NULL concatenación con null
Ninguno OFF
es null
(concat null yields null)
CURSOR_CLOSE_ON Cierre de cursor al confirmar User options asigna
OFF
_COMMIT (cursor close on commit) valor predeterminado
User options asigna
IMPLICIT_TRANSACTIONS Ninguno OFF
valor predeterminado
Identificador entre comillas User options asigna
QUOTED_IDENTIFIER OFF
(quoted identifier) valor predeterminado
ANSI_DEFAULTS Ninguno Ninguno N/D
User options asigna
ARITHABORT Ninguno OFF
valor predeterminado
User options asigna
ARITHIGNORE Ninguno OFF
valor predeterminado
DATEFIRST Ninguno Ninguno 7
DATEFORMAT Ninguno Ninguno mdy
DEADLOCK_PRIORITY Ninguno Ninguno NORMAL
User options asigna
DISABLE_DEF_CNST_CHK Ninguno OFF
valor predeterminado
FIPS_FLAGGER Ninguno Ninguno OFF
FMTONLY Ninguno Ninguno OFF
FORCEPLAN Ninguno Ninguno OFF
IDENTITY_INSERT Ninguno OFF
LANGUAGE Ninguno Ninguno us_english
LOCK_TIMEOUT Ninguno Ninguno Sin límite
User options asigna
NOCOUNT Ninguno OFF
valor predeterminado
NOEXEC Ninguno Ninguno OFF
NUMERIC_ROUNDABORT Ninguno Ninguno OFF
OFFSETS Ninguno Ninguno OFF
PARSEONLY Ninguno Ninguno OFF
PROCID Ninguno Ninguno OFF
QUERY_GOVERNOR_COST_LIM Límite del administrador
Ninguno OFF
IT de consultas
REMOTE_PROC_TRANSACTION
Ninguno Ninguno OFF
S
ROWCOUNT Ninguno Ninguno OFF
SHOWPLAN_ALL Ninguno Ninguno OFF
SHOWPLAN_TEXT Ninguno Ninguno OFF
STATISTICS IO Ninguno Ninguno OFF
STATISTICS_PROFILE Ninguno Ninguno N/D

Material de estudio Página: 115 de 249


Visual Basic 6.0 y SQLServer 7.0

STATISTICS TIME Ninguno Ninguno OFF


TEXTSIZE Ninguno Ninguno OFF
TRANSACTION ISOLATION
Ninguno Ninguno N/D
LEVEL
XACT_ABORT Ninguno Ninguno OFF

Opciones SET de tiempo de análisis y tiempo de ejecución

El momento en el que las opciones SET surten efecto depende de si la opción es una opción de
tiempo de análisis o de tiempo de ejecución. Las opciones de tiempo de análisis surten efecto
durante el análisis, según se encuentran las opciones en el texto, sin tener en cuenta las
instrucciones de control de flujo. Las opciones de tiempo de ejecución surten efecto durante la
ejecución del código en el que se especifican. Si la ejecución falla antes de que se haya
ejecutado la instrucción SET, la opción no se establece. Si la ejecución falla una vez ejecutada la
instrucción SET, la opción se habrá establecido.

Las opciones QUOTED_IDENTIFIER, PARSEONLY, OFFSETS y FIPS_FLAGGER son de tiempo


de análisis. El resto de las opciones SET son de tiempo de ejecución.

Las instrucciones SET QUOTED_IDENTIFIER y SET ANSI_NULLS que se producen en un lote o


procedimiento almacenado no afectan al lote o al procedimiento almacenado. En su lugar, la
configuración que se utiliza para las instrucciones de un lote o procedimiento almacenado es la
que hay cuando se crea el lote o procedimiento almacenado.

Duración de las opciones SET

En esta sección se describe la duración de las opciones SET.


• Las opciones SET que establece un usuario en una secuencia de comandos se aplican
hasta que se restablezcan o hasta que se termine la sesión del usuario con el servidor.
• Las opciones SET que se establecen en un procedimiento almacenado o
desencadenador se aplican hasta que se restablezcan en el procedimiento almacenado o
desencadenador, o hasta que el control retorne al código que los llamó.
• A menos que se restablezcan de forma explícita, los valores de las opciones SET de
todos los códigos de mayor nivel se aplican en un procedimiento almacenado o
desencadenador.
• A menos que se restablezcan de forma implícita o explícita, las opciones SET que se han
establecido para una conexión se aplican después de conectarse a una base de datos
distinta.

Nota Una consideración adicional es que cuando un usuario se conecta a una base de
datos, algunas opciones se pueden establecer a ON (activada) automáticamente, en
función de los valores especificados por el uso anterior de la opción de servidor user
options o los valores que se aplican a todas las conexiones ODBC y OLE DB.

Opción SET con acceso directo

Transact-SQL proporciona la instrucción SET ANSI_DEFAULTS como acceso directo para


establecer estas opciones estándar de SQL-92:
• SET ANSI_NULLS
• SET CURSOR_CLOSE_ON_COMMIT

Material de estudio Página: 116 de 249


Visual Basic 6.0 y SQLServer 7.0

• SET ANSI_NULL_DFLT_ON
• SET IMPLICIT_TRANSACTIONS
• SET ANSI_PADDING
• SET QUOTED_IDENTIFIER
• SET ANSI_WARNINGS

El acceso directo restablece los valores de estas opciones. Cualquier opción individual
establecida una vez que se ha utilizado el acceso directo anula el valor correspondiente
establecido por el mismo.

Nota SET ANSI_DEFAULTS no establece todas las opciones necesarias para cumplir el estándar
SQL-92.

Material de estudio Página: 117 de 249


Visual Basic 6.0 y SQLServer 7.0

3.2.2 Opciones de base de datos

En esta tabla se enumeran en orden alfabético las opciones de base de datos y las
correspondientes opciones SET y de servidor que se admiten en Microsoft SQL Server.
Valor
Opción de servidor predeterminad
Opción de base de datos Opción SET
o
ANSI null default (valor
ANSI_NULL_DFLT_ON user options asigna valor
NULL ANSI OFF
ANSI_NULL_DFLT_OFF predeterminado
predeterminado)
ANSI nulls (Valores user options asigna valor
ANSI_NULLS OFF
NULL ANSI) predeterminado
ANSI warnings user options asigna valor
ANSI_WARNINGS OFF
(Advertencias ANSI) predeterminado
auto create statistics
(crear estadísticasNinguno Ninguno ON
automáticamente)
auto update statistics
(actualizar estadísticasNinguno Ninguno ON
automáticamente)
autoclose (cerrar
Ninguno Ninguno FALSE
automáticamente)
autoshrink (reducción
Ninguno Ninguno FALSE
automática)
concat null yields null (el
resultado de laCONCAT_NULL_YIELDS_NULL
Ninguno OFF
concatenación con null
es null)
cursor close on commit
CURSOR_CLOSE_ON user options asigna valor
(cierre de cursor al OFF
_COMMIT predeterminado
confirmar)
dbo use only (sólo para
Ninguno Ninguno FALSE
uso del dbo)
default to local cursor
(toma como
Ninguno Ninguno FALSE
predeterminado el cursor
local)
merge publish
Ninguno Ninguno FALSE
(publicación de mezcla)
offline (sin conexión) Ninguno Ninguno FALSE
published (publicado) Ninguno Ninguno FALSE
quoted identifier
user options asigna valor
(identificador entreQUOTED_IDENTIFIER OFF
predeterminado
comillas)
read only (de sólo
Ninguno Ninguno FALSE
lectura)
recursive triggers
(desencadenadores Ninguno Ninguno FALSE
recursivos)
select into/ bulkcopy
(select into o copiaNinguno Ninguno FALSE
masiva)
single user (un único
Ninguno Ninguno FALSE
usuario)

Material de estudio Página: 118 de 249


Visual Basic 6.0 y SQLServer 7.0

subscribed (suscrito) Ninguno Ninguno TRUE


torn page detection
(detección de página Ninguno TRUE
rasgada)
trunc. log on chkpt.
(truncar registro enNinguno Ninguno TRUE
punto de comprobación)

Las opciones predeterminadas de base de datos para una base de datos nueva son las que se
han definido en la base de datos model. En las instalaciones nuevas de SQL Server, la
configuración de las bases de datos model y master es la misma.
Un cambio en una opción de base de datos obliga a que se tenga que volver a compilar todo lo
que hay en la caché.

Opciones y contexto de base de datos

El contexto de base de datos de las secuencias de comandos y los lotes dentro de las mismas
viene determinado por la conexión más reciente. La conexión se puede establecer explícitamente
con la instrucción USE en Transact-SQL y con métodos implícitos y explícitos en otros entornos,
como OBDC y OLE DB.

Cuando se ejecuta un procedimiento almacenado desde un lote o desde otro procedimiento


almacenado, la ejecución se hace con las opciones establecidas en ese momento en la base de
datos que contiene el procedimiento almacenado. Por ejemplo, cuando el procedimiento
almacenado db1.dbo.sp1 llama al procedimiento almacenado db2.dbo.sp2, sp1 se ejecuta con
la opción de nivel de compatibilidad actual de la base de datos db1 y sp2 se ejecuta con la opción
de nivel de compatibilidad actual de la base de datos db2.

Cuando una instrucción de Transact-SQL se refiere a objetos que residen en varias bases de
datos, se le aplica el contexto de base de datos actual y de conexión actual (la base de datos
definida con la instrucción USE, si se trata de un lote, o la que contiene el procedimiento
almacenado en el caso de un procedimiento almacenado).

Material de estudio Página: 119 de 249


Visual Basic 6.0 y SQLServer 7.0

3.2.3 Opciones de servidor

En esta tabla se enumeran en orden alfabético las opciones de servidor y las opciones
correspondientes de base de datos y SET que se admiten en Microsoft SQL Server .

Opción de Valor
Opción de servidor Opción SET base de datos predeterminado
affinity mask (máscara de afinidad) Ninguno Ninguno 0
allow updates (permitir actualizaciones) Ninguno Ninguno OFF
cost threshold for parallelism (umbral de
Ninguno Ninguno 5
costo del paralelismo)
cursor threshold (umbral del cursor) Ninguno Ninguno -1
default language (idioma predeterminado) Ninguno Ninguno 0
default sortorderid (id. predeterminado de
Ninguno Ninguno 52
orden)
extended memory size (tamaño de memoria
Ninguno Ninguno 0
extendida)
fill factor (factor de relleno) Ninguno Ninguno 0
index create memory (memoria para creación
Ninguno Ninguno 2048
de índices)
language in cache (idioma en caché) Ninguno Ninguno 3
language neutral full-text (texto independiente
Ninguno Ninguno 0
del idioma)
lightweight pooling (agrupación compacta) -1
locks (bloqueos) Ninguno Ninguno 0
max async io (máx. de E/S asincrónica) Ninguno Ninguno 32
max degree of parallelism (máximo grado de
Ninguno Ninguno 0
paralelismo)
max server memory (memoria máxima del
Ninguno Ninguno 2147483647
servidor)
max text repl size (tamaño máximo de texto
Ninguno Ninguno 65536
reemplazado)
max worker threads (máx. de subprocesos
Ninguno Ninguno 255
secundarios)
media retention (conservación de medio) Ninguno Ninguno 0
min memory per query (mín. de memoria por
Ninguno Ninguno 1024
consulta)
min server memory (memoria mínima del
Ninguno Ninguno 0
servidor)
nested triggers (desencadenadores anidados) Ninguno Ninguno 1
network packet size (tamaño del paquete de
Ninguno Ninguno 4096
red)
open objects (objetos abiertos) Ninguno Ninguno 0
priority boost (aumento de prioridad) Ninguno Ninguno 0
query governor cost limit (límite del QUERY_GOVERNOR_COST_LIM
Ninguno 0
administrador de consultas) IT
query wait (espera de consulta) Ninguno Ninguno 600
recovery interval (intervalo de recuperación) Ninguno Ninguno 5
remote access (acceso remoto) Ninguno Ninguno 1
remote login timeout (tiempo de espera de
Ninguno Ninguno 30
inicio de sesión remoto)
remote proc trans (transacción de
Ninguno Ninguno 0
procedimiento remoto)
remote query timeout (tiempo de espera de
Ninguno Ninguno 0
consulta remota)
resource timeout (tiempo de espera de Ninguno Ninguno 10

Material de estudio Página: 120 de 249


Visual Basic 6.0 y SQLServer 7.0

recurso)
scan for startup procs (buscar procesos de
Ninguno Ninguno 0
inicio)
set working set size (establecer el tamaño del
Ninguno Ninguno 0
conjunto de trabajo)
show advanced options (mostrar opciones
Ninguno Ninguno 1
avanzadas)
spin counter (contador de giro) Ninguno Ninguno 0
time slice (división de tiempo) Ninguno Ninguno 100
Unicode comparison style (estilo de
Ninguno Ninguno 1
comparación en Unicode)
Unicode locale id (Id. local de Unicode) Ninguno Ninguno 1033
user connections (conexiones de usuario) Ninguno Ninguno 0
ANSI null
default (valor
ANSI_NULL_DFLT_ON
user options (opciones de usuario) ANSI_NULL_DFLT_OFF
NULL ANSI OFF
predeterminado
)
Valores NULL
ANSI_NULLS ANSI (ANSI OFF
nulls)
ANSI_PADDING Ninguno ON
Advertencias
ANSI_WARNINGS ANSI (ANSI OFF
warnings)
Cierre de cursor
CURSOR_CLOSE_ON al confirmar
OFF
_COMMIT (cursor close on
commit)
IMPLICIT_TRANSACTIONS Ninguno OFF
Identificador
entre comillas
QUOTED_IDENTIFIER OFF
(quoted
identifier)
ARITHABORT Ninguno OFF
ARITHIGNORE Ninguno OFF
DISABLE_DEF_CNST_CHK Ninguno OFF
NOCOUNT Ninguno OFF
extended memory size (tamaño de memoria
Ninguno Ninguno 0
extendida)

Material de estudio Página: 121 de 249


Visual Basic 6.0 y SQLServer 7.0

3.2.4 Sugerencias

En esta tabla se enumeran las opciones disponibles para las sugerencias de combinación, de
consulta y de tabla en Microsoft SQL Server .

Tipo
Opción Valor predeterminado
sugerencia Descripción
LOOP | HASH Especifica la estrategia que utilizar al
Combinación Elegido por SQL Server.
| MERGE | REMOTE combinar las filas de dos tablas.
Especifica si se utiliza hash u orden para
Consulta { HASH | ORDER } GROUP calcular los agregados GROUP BY yElegido por SQL Server.
COMUTE.
{ MERGE | HASH | Especifica la estrategia que utilizar para todas
Consulta Elegido por SQL Server.
CONCAT } UNION las operaciones UNION de la consulta.
Optimiza la consulta para la recuperación del
Consulta FAST entero No hay tal optimización.
número especificado de filas.
Realiza combinaciones en el orden en que las
Consulta FORCE ORDER Elegido por SQL Server.
tablas aparecen en la consulta
Crea un plan que tiene en cuenta el tamaño
Consulta ROBUST PLAN Elegido por SQL Server.
máximo posible de fila.
Tiene el mismo efecto que especificar la
Tabla FASTFIRSTROW No hay tal optimización.
sugerencia de consulta FAST 1.
Indica a SQL Server que utilice los índices
Tabla INDEX = Elegido por SQL Server.
especificados de una tabla.
HOLDLOCK
| SERIALIZABLE Hace que se establezcan (o no) ciertos
| REPEATABLEREAD bloqueos para una tabla y anula los bloqueosLos bloqueos necesarios para
Tabla
| READCOMMITTED que se utilizarían para exigir el nivel dela transacción actual.
| READUNCOMMITTED aislamiento de la transacción actual.
| NOLOCK
ROWLOCK
| PAGLOCK Especifica el tamaño de los bloqueos
Tabla Elegido por SQL Server.
| TABLOCK compartidos que se toman para esta tabla.
| TABLOCKX
Tabla READPAST Salta todas las filas bloqueadas de una vez. Espera filas bloqueadas.
Toma bloqueos actualizados en lugar de
Tabla UPDLOCK Toma bloqueos compartidos.
compartidos.

Material de estudio Página: 122 de 249


Visual Basic 6.0 y SQLServer 7.0

3.3.5 Opción del nivel de compatibilidad de la base de datos

Transact-SQL proporciona el procedimiento almacenado sp_dbcmptlevel que establece ciertos


comportamientos de base de datos para que sean compatibles con las versiones anteriores de
Microsoft SQL Server .

Una regla especial se aplica a la relación entre la opción del nivel de compatibilidad de la base de
datos, la opción de base de datos concat null yields null (la concatenación con null es null) y la
opción SET CONCAT_NULL-YIELDS_NULL. La configuración de concat null yields null y
CONCAT_NULL_YIELDS_NULL se pasan por alto cuando el valor del nivel de compatibilidad es
para una versión anterior a la 7.0.

El nivel de compatibilidad afecta a los comportamientos de la base de datos especificada, no a


todo el servidor. Para obtener más información, consulte sp_dbcmptlevel .

3.3.6 Comportamiento cuando ARITHABORT y ARITHIGNORE están activadas

Cuando utilice la versión 2.50.0121 o posterior del controlador ODBC de Microsoft SQL Server ,
ARITHABORT asumirá la prioridad si están activadas las opciones de proceso de consultas
ARITHABORT y ARITHIGNORE.

ARITHABORT y ARITHIGNORE son dos opciones distintas; el hecho de activar una no implica la
desactivación automática de la otra. Por ejemplo, si una aplicación contiene estas instrucciones,
ambas opciones están activadas:

SET ARITHABORT ON
SET ARITHIGNORE ON
GO

Los procedimientos almacenados que emitan una instrucción SET ARITHIGNORE ON seguirán
provocando que los clientes muestren el comportamiento propio de SET ARITHABORT ON si el
cliente había activado ARITHABORT antes de llamar al procedimiento almacenado.

Los procedimientos pueden hacer lo siguiente para garantizar que ARITHIGNORE esté siempre
activa, independientemente de la configuración del cliente para ARITHABORT:

CREATE PROCEDURE example AS


SET ARITHABORT OFF
SET ARITHIGNORE ON
-- Statements making up the stored procedure go here.
GO

Siempre que se ejecute una instrucción SET en un procedimiento almacenado, la nueva


configuración permanecerá activa el tiempo que dure el procedimiento. Cuando finalice el
procedimiento, la configuración de la conexión para esa opción volverá a su estado anterior a la
ejecución del procedimiento. Con el código mostrado anteriormente, la opción ARITHABORT se
desactiva durante la ejecución del procedimiento para que se active la opción ARITHIGNORE. A
continuación, restablece la configuración definida por la aplicación cliente cuando finaliza el
procedimiento.

Material de estudio Página: 123 de 249


Visual Basic 6.0 y SQLServer 7.0

3.3 Implementación y el mantenimiento de bases de datos.

Un sistema de base de datos de cliente-servidor consta de dos componentes: programas que


proporcionan una interfaz para que los usuarios del cliente puedan tener acceso a los datos y la
estructura de base de datos que administra y almacena los datos en el servidor. Por ejemplo, si
utiliza Microsoft SQL Server para crear una aplicación de cuentas corrientes, deberá configurar
una estructura de base de datos para administrar los datos de las transacciones de las cuentas y
una aplicación que actúe como la interfaz de usuario para la base de datos con que los usuarios
tendrán acceso a la información de las cuentas corrientes.

Para crear una base de datos deberá conocer cómo diseñar, crear y mantener cada uno de esos
componentes para asegurar un funcionamiento óptimo de la base de datos.

Una base de datos de Microsoft SQL Server consta de una colección de tablas con datos y otros
objetos como vistas, índices, procedimientos almacenados y desencadenadores, que se definen
para poder llevar a cabo distintas operaciones con datos. Los datos almacenados en una base de
datos suelen estar relacionados con un tema o un proceso determinados como, por ejemplo, la
información de inventario para el almacén de una fábrica.

SQL Server puede trabajar con un gran número de bases de datos y cada una de ellas puede
almacenar datos interrelacionados o datos no relacionados con los de las otras bases de datos.
Por ejemplo, un servidor podría tener una base de datos en la que se almacenen datos del
personal y otra en la que se almacenen datos relacionados con los productos. Por otra parte,
puede utilizarse una base de datos para almacenar datos acerca de pedidos actuales de los
clientes y otra base de datos relacionada puede almacenar pedidos anteriores de los clientes que
se utilicen para la elaboración de los informes anuales.

Antes de crear una base de datos, es importante entender las partes que la componen y cómo
diseñarlas para asegurar que la base de datos funcione correctamente una vez implementada.

Importante Se recomienda encarecidamente ( o sea que no la vallan a regar) no crear objetos de


usuario, como tablas, vistas, procedimientos almacenados o desencadenadores, en la base de
datos master. La base de datos master contiene las tablas del sistema con la información del
sistema que utiliza SQL Server, como los valores de las opciones de configuración.

3.3.1 Componentes de una base de datos

Una base de datos de Microsoft SQL Server consta de una colección de tablas en las que se
almacena un conjunto específico de datos estructurados. Una tabla contiene una colección de
filas (en ocasiones denominadas registros o tuplas) y de columnas (también denominadas
atributos). Cada columna de la tabla se ha diseñado para almacenar un determinado tipo de
información (por ejemplo, fechas, nombres, importes en moneda o números). Las tablas
contienen diversos tipos de controles (restricciones, reglas, desencadenadores, valores
predeterminados y tipos de datos personalizados por los usuarios), que aseguran la validez de los
datos. Las tablas pueden presentar índices, similares a los de los libros, que permiten localizar las
filas rápidamente. Se puede agregar restricciones de integridad referencial declarativa (DRI) a las
tablas con el fin de asegurar la coherencia de los datos interrelacionados que se encuentran en
tablas distintas. Asimismo, una base de datos puede almacenar procedimientos que utilicen
código de programación de Transact-SQL para realizar operaciones con los datos que contiene la
base de datos, por ejemplo, almacenar vistas que permiten el acceso personalizado a los datos
de las tablas.

Material de estudio Página: 124 de 249


Visual Basic 6.0 y SQLServer 7.0

3.3.2 Archivos y grupos de archivos

Microsoft SQL Server crea una base de datos mediante un conjunto de archivos del sistema
operativo. Todos los datos y objetos de la base de datos, como las tablas, los procedimientos
almacenados, los desencadenadores y las vistas, se almacenan exclusivamente en los siguientes
archivos del sistema operativo:

• Principal
Este archivo contiene la información de inicio para la base de datos y se utiliza para
almacenar datos. Cada base de datos tiene un archivo de datos principal.
• Secundario
Estos archivos contienen todos los datos que no caben en el archivo principal. Las bases
de datos no necesitan archivos de datos secundarios si el archivo principal puede
contener todos los datos de la base de datos. Algunas bases de datos pueden ser muy
grandes y necesitar varios archivos de datos secundarios, o bien utilizar archivos
secundarios en unidades de disco distintas para distribuir los datos en varios discos.
• Registro de transacciones
Estos archivos contienen la información de registro que se utiliza para recuperar la base
de datos. Cada base de datos debe tener al menos un archivo de registro.

Por ejemplo, puede crearse una base de datos sencilla, ventas, con un archivo principal que
contenga todos los datos y objetos, y un archivo de registro que contenga la información del
registro de transacciones. Por otra parte, puede crearse una base de datos más compleja,
pedidos, compuesta por un archivo principal y cinco archivos secundarios; los datos y objetos de
la base de datos se reparten entre los seis archivos, y cuatro archivos de registro adicionales
contienen la información del registro de transacciones.

Los grupos de archivos permiten agrupar archivos con fines administrativos y de asignación y
ubicación de datos. Por ejemplo, pueden crearse tres archivos (datos1.ndf, datos2.ndf y
datos3.ndf) en tres unidades de disco, respectivamente, para asignarlos posteriormente al grupo
de archivos grupoa1. A continuación, se puede crear específicamente una tabla en el grupo de
archivos grupoa1. Las consultas de datos de la tabla se distribuirán por los tres discos, con lo que
mejorará el rendimiento. Puede obtenerse el mismo incremento en el rendimiento con un archivo
único creado en un conjunto de bandas RAID (matriz redundante de discos económicos). No
obstante, los archivos y los grupos de archivos le permiten agregar nuevos archivos o discos con
gran facilidad. Además, si la base de datos supera el tamaño máximo establecido para un archivo
de Microsoft Windows NT®, puede utilizar archivos de datos secundarios para que la base de
datos pueda seguir creciendo.

Reglas para la definición de archivos o grupos de archivos

Éstas son, entre otras, las reglas para la definición de archivos y grupos de archivos:
• Un archivo o un grupo de archivos no puede ser utilizado por más de una base de datos.
Por ejemplo, los archivos ventas.mdf y ventas.ndf, que contienen datos y objetos de la
base de datos ventas, no pueden ser utilizados por otra base de datos.
• Un archivo puede pertenecer únicamente a un grupo de archivos.
• Los datos y la información del registro de transacciones no pueden pertenecer al mismo
archivo o grupo de archivos.
• Los archivos del registro de transacciones nunca pueden formar parte de un grupo de
archivos.

Material de estudio Página: 125 de 249


Visual Basic 6.0 y SQLServer 7.0

3.3.2.1 Grupos de archivos predeterminados

Una base de datos consta de un grupo de archivos principal y de uno o varios grupos de archivos
definidos por el usuario.

El grupo de archivos que contiene el archivo principal se denomina grupo de archivos principal.
Cuando se crea una base de datos, el grupo de archivos principal contiene el archivo de datos
principal y todos los archivos que no hayan sido asignados a otros grupos de archivos. Todas las
tablas del sistema se encuentran en el grupo de archivos principal. Si el grupo de archivos
principal se queda sin espacio, no se podrá agregar más información del catálogo a las tablas del
sistema. El grupo de archivos principal sólo se llenará si el crecimiento automático está
desactivado o si todos los discos que almacenan los archivos del grupo de archivos principal se
quedan sin espacio. Si es así, vuelva a activar el crecimiento automático o mueva los archivos a
otros discos para dejar espacio libre.

Los grupos de archivos definidos por el usuario son todos los creados específicamente por el
usuario durante la creación de la base de datos o durante una modificación posterior. Si se llena
un grupo de archivos definido por el usuario, sólo se verían afectadas las tablas de usuario
asignadas específicamente a dicho grupo de archivos.

En cualquier momento, se designa un grupo de archivos como el grupo de archivos


predeterminado (DEFAULT). Cuando se crean objetos en la base de datos sin especificar a qué
grupo de archivos pertenecen, se asignan al grupo de archivos predeterminado. El grupo de
archivos predeterminado debe ser lo suficientemente grande como para dar cabida a todos los
objetos no asignados a un grupo de archivos definido por el usuario. En principio, el grupo de
archivos principal será el grupo de archivos predeterminado.

El grupo de archivos predeterminado puede cambiarse mediante la instrucción ALTER


DATABASE. Si se cambia el grupo de archivos predeterminado, todos los objetos no asignados a
un grupo de archivos específico en el momento de su creación serán asignados a los archivos de
datos del nuevo grupo de archivos predeterminado. No obstante, los objetos y las tablas del
sistema no pasan a asignarse al nuevo grupo de archivos predeterminado, sino que siguen
estando asignados al grupo de archivos principal.

El cambio del grupo de archivos predeterminado impide que los objetos de usuario que no se
hayan creado específicamente en un grupo de archivos definido por un usuario compitan por el
espacio con los objetos y las tablas del sistema.

3.3.2.2 Usar archivos y grupos de archivos

Los grupos de archivos utilizan una estrategia de relleno proporcional entre todos los archivos de
cada grupo de archivos. A medida que se escriben datos en el grupo de archivos, Microsoft SQL
Server escribe una cantidad proporcional al espacio libre del archivo en cada archivo del grupo, en
lugar de escribir todos los datos en el primer archivo hasta que esté completo antes de pasar al
archivo siguiente. Por ejemplo, si el archivo a1 tiene 100 MB de espacio libre y el archivo a2 tiene
200 MB libres, por cada cantidad de datos que se asigne al archivo a1, se asignará el doble al
archivo a2 y así sucesivamente. De ese modo, los dos archivos se llenarán aproximadamente al
mismo tiempo y se conseguirá una crear banda simple.

Cuando se llenan todos los archivos de un grupo de archivos, SQL Server expande
automáticamente los archivos por turnos para que quepan más datos (siempre y cuando la base
de datos esté configurada para crecer automáticamente). Por ejemplo, un grupo de archivos
consta de tres archivos configurados para crecer automáticamente. Cuando se agota el espacio

Material de estudio Página: 126 de 249


Visual Basic 6.0 y SQLServer 7.0

de todos los archivos del grupo de archivos, sólo se expande el primer archivo. Cuando se llena el
primer archivo y no se pueden escribir más datos en el grupo de archivos, se expande el segundo
archivo. Cuando se llena el segundo archivo y no pueden escribirse más datos en el grupo de
archivos, se expande el tercer archivo. Si se llena el tercer archivo y no se pueden escribir más
datos en el grupo de archivos, se vuelve a expandir el primer archivo, y así sucesivamente.

El uso de archivos y grupos de archivos permite mejorar el rendimiento de la base de datos al


permitir crear la base de datos en varios discos, varios controladores de disco o sistemas RAID
(matriz redundante de discos independientes). Por ejemplo, si su equipo tiene cuatro discos,
puede crear una base de datos que contenga tres archivos de datos y un archivo de registro, y
mantener un archivo en cada disco. Cuando se produce un acceso a los datos, hay cuatro
cabezales de lectura y escritura que pueden tener acceso a los datos a la vez, con lo que se
aceleran las operaciones de la base de datos.

Además, los archivos y los grupos de archivos permiten la distribución de los datos, ya que puede
crearse una tabla en un grupo de archivos específico. De ese modo se aumenta el rendimiento,
dado que todas las E/S para una tabla específica pueden dirigirse a un disco determinado. Por
ejemplo, una tabla que se utilice muy a menudo puede colocarse en un archivo de un grupo
determinado de archivos y ubicarse en un disco. Otras tablas menos utilizadas de la base de
datos pueden colocarse en archivos distintos de otro grupo de archivos, en un segundo disco.

Éstas son algunas recomendaciones generales referentes a los archivos y a los grupos de
archivos:
• La mayor parte de las bases de datos funcionarán correctamente con un solo archivo de
datos y un solo archivo de registro de transacciones.
• Si utiliza varios archivos, cree un segundo grupo de archivos para el archivo adicional y
conviértalo en el grupo de archivos predeterminado. De ese modo, el archivo principal
sólo contendrá objetos y tablas del sistema.
• Para aumentar al máximo el rendimiento, cree archivos o grupos de archivos en tantos
discos físicos como estén disponibles y distribuya en grupos de archivos distintos los
objetos que compitan intensamente por el espacio.
• Utilice grupos de archivos para disponer los objetos en discos físicos determinados.
• Disponga en grupos de archivos distintos las diferentes tablas que se utilicen en las
mismas consultas de combinación. De ese modo mejorará el rendimiento, debido a la
búsqueda que las operaciones de E/S realizan en paralelo en los discos para localizar
datos combinados.
• Distribuya en grupos de archivos distintos las tablas de acceso frecuente y los índices no
agrupados que pertenezcan a esas tablas. De ese modo mejorará el rendimiento, dado
que las operaciones de E/S se realizan en paralelo si los archivos se encuentran en
discos físicos distintos.
• No coloque el archivo o archivos de registro en el mismo disco físico que los demás
archivos y grupos de archivos.

Material de estudio Página: 127 de 249


Visual Basic 6.0 y SQLServer 7.0

3.3.3.3 Usar archivos y grupos de archivos para administrar el crecimiento de las


bases de datos

Cuando cree una base de datos mediante archivos y grupos de archivos, deberá especificar un
tamaño inicial para el archivo. Microsoft SQL Server crea los archivos de datos y para ello se basa
en el tamaño que se especifique. A medida que se agregan datos a la base de datos, estos
archivos se van llenando. Sin embargo, debe tener presente si la base de datos va a crecer, y
cómo, por encima del espacio inicial asignado, si se agregan más datos a la base de datos de los
que caben en los archivos.

De forma predeterminada, SQL Server permite que los archivos de datos crezcan tanto como sea
necesario hasta que se agote el espacio de disco. Por lo tanto, si los archivos de la base de datos
no pudieran crecer más allá de los límites especificados cuando se creó la base de datos, deberá
especificarse en el momento de su creación mediante el Administrador corporativo de SQL Server
o la instrucción CREATE DATABASE.

Por otra parte, SQL Server le permite crear archivos de datos que pueden crecer
automáticamente cuando se llenan, pero sólo hasta un tamaño máximo definido previamente. Así
se puede evitar que las unidades de disco se queden sin espacio.

Recomendaciones

Cuando cree una base de datos, defina el mayor tamaño posible para los archivos de datos y
tenga en cuenta la cantidad de datos máxima prevista para la base. Permita que los archivos de
datos crezcan automáticamente, pero establezca un límite de crecimiento mediante la
especificación de un tamaño máximo de crecimiento de los archivos de datos que deje algo de
espacio disponible en el disco duro. De ese modo, la base de datos podrá crecer si se agregan
más datos de los previstos, pero sin llegar a agotar completamente el espacio disponible en la
unidad de disco. Si se supera el tamaño inicial del archivo de datos y el archivo empieza a crecer
automáticamente, vuelva a realizar una previsión del tamaño máximo de la base de datos,
agregue más espacio de disco (si es preciso) y cree más archivos o grupos de archivos y
agréguelos a la base de datos.
No obstante, si se establece que la base de datos no pueda crecer más allá de su tamaño inicial,
configure el tamaño de crecimiento máximo de la base de datos con el valor cero. Así, los
archivos de la base de datos no podrán crecer. Si los archivos de la base de datos se llenan, no
podrán agregarse más datos hasta que se agreguen más archivos de datos a la base de datos o
se expandan los archivos existentes.
Fragmentación de archivos
Al permitirse que los archivos crezcan automáticamente, se puede producir una fragmentación de
esos archivos si un gran número de archivos comparten el mismo disco. Por lo tanto, se
recomienda crear los archivos o los grupos de archivos en tantos discos físicos locales distintos
como haya disponibles. Distribuya en grupos de archivos distintos los objetos que compitan de
forma intensa por el espacio.

3.3.4 Grupos de archivos de sólo lectura.

Microsoft SQL Server permite marcar los grupos de archivos como de sólo lectura. Puede
marcarse como de sólo lectura cualquier grupo de archivos, incluso el grupo de archivos principal.
Un grupo de archivos marcado como de sólo lectura no puede ser modificado de ninguna forma.
Si el grupo de archivos principal se marca como de sólo lectura, no se crearán nuevos objetos en

Material de estudio Página: 128 de 249


Visual Basic 6.0 y SQLServer 7.0

la base de datos. Por ejemplo, la creación de un nuevo objeto, como una tabla, una vista, un
registro, un procedimiento almacenado o una recompilación automática de un procedimiento
almacenado, actualiza las tablas del sistema. Esta actualización no sería posible si el grupo de
archivos principal estuviera marcado como de sólo lectura.

Coloque las tablas que no deban modificarse (como las de datos históricos) en uno o varios
grupos de archivos y, a continuación, márquelos como de sólo lectura. De ese modo, se evitarán
actualizaciones accidentales. Puede hacer una copia de seguridad del grupo de archivos de sólo
lectura y restaurarla en otro servidor en el que se ejecute SQL Server, sin preocuparse por la
recuperación de los registros de transacciones.

Material de estudio Página: 129 de 249


Visual Basic 6.0 y SQLServer 7.0

3.3.4 Registros de transacciones

Una base de datos de Microsoft SQL Server tiene, como mínimo, un archivo de datos y un archivo
de registro de transacciones. Los datos y la información del registro de transacciones nunca se
mezclan en el mismo archivo, y cada archivo es utilizado por una sola base de datos.

SQL Server utiliza el registro de transacciones de cada base de datos para recuperar las
transacciones. El registro de transacciones consiste en una serie de registros de todas las
modificaciones de la base de datos y las transacciones que se han realizado en las
modificaciones. En el registro de transacciones figura el inicio de cada transacción. También se
registran los cambios de los datos y se facilita suficiente información para deshacer las
modificaciones (si fuera necesario posteriormente) realizadas durante la transacción. Para
algunas operaciones largas, como la de CREATE INDEX, el registro de transacciones sólo
registra que se llevó a cabo la transacción. El registro crece continuamente a medida que se
producen operaciones en la base de datos y éstas se registran. El registro de transacciones
registra la asignación y cancelación de asignación de páginas y la confirmación o anulación de
cada transacción. Esto permite a SQL Server aplicar (confirmar) o anular (deshacer) cada
transacción de las siguientes maneras:

• Una transacción se confirma cuando usted aplica un registro de transacciones. SQL


Server copia la imagen posterior de cada modificación en la base de datos o vuelve a
ejecutar instrucciones como CREATE INDEX. Estas acciones se aplican en la misma
secuencia que la de las acciones originales. Al finalizar este proceso, la base de datos se
encuentra en el mismo estado en que estaba en el momento en que se realizó la copia de
seguridad del registro de transacciones.

• Una transacción se deshace si invierte una transacción incompleta. SQL Server copia las
imágenes previas de todas las modificaciones de la base de datos desde BEGIN
TRANSACTION. Si encuentra registros de transacciones que indiquen que se ejecutó la
instrucción CREATE INDEX, realizará las operaciones necesarias para invertir
lógicamente la instrucción. Estas imágenes previas y las inversiones de CREATE INDEX
se aplican en orden inverso al de la secuencia original.

En un punto de comprobación, SQL Server se asegura de que todos los registros de


transacciones y todas las páginas de la base de datos que hayan sufrido modificaciones se
escriban en el disco. Durante el proceso de recuperación de cada base de datos que se produce
cuando se reinicia SQL Server, debe rehacerse una transacción únicamente cuando no se sabe si
todas las modificaciones de los datos de la transacción se escribieron realmente en el disco
desde la caché del búfer de SQL Server. Dado que un punto de comprobación fuerza a todas las
páginas modificadas a grabarse en el disco, representa el punto en el que la recuperación de
inicio debe empezar a rehacer transacciones. Debido a que se garantiza que todas las páginas
modificadas antes del punto de comprobación están en el disco, no es necesario rehacer ninguna
operación que se haya realizado antes del punto de comprobación.

3.3.4.1 Operaciones no registradas

Si la opción de la base de datos select into/bulkcopy (select into o copia masiva) está
configurada con el valor TRUE (verdadero), Microsoft SQL Server no registrará los detalles
completos de las operaciones siguientes en el registro de transacciones:

• Operaciones de carga masiva

Material de estudio Página: 130 de 249


Visual Basic 6.0 y SQLServer 7.0

• Instrucciones SELECT INTO


• Instrucciones WRITETEXT
• Instrucciones UPDATETEXT

Aunque estas operaciones no se registren, siempre se registran determinados cambios de las


operaciones. Todas estas operaciones asignan una o varias páginas nuevas para contener los
datos que agregan. Las asignaciones de páginas se registran, pero no así los detalles de los
datos agregados en las páginas. SQL Server puede deshacer estas operaciones no registradas al
invertir las asignaciones de páginas escritas en el registro. SQL Server no puede confirmar las
operaciones, ya que en el registro no constan los datos que se deberían agregar en las páginas
nuevas.

Como no es posible confirmar las operaciones no registradas, estas operaciones invalidan una
secuencia de copias de seguridad del registro de transacciones. Debe realizarse una copia de
seguridad completa o incremental de la base de datos después de una operación no registrada
para comenzar una nueva secuencia de copias de seguridad del registro. Por lo tanto, si se
produce una de estas operaciones, SQL Server permite que se realice una copia de seguridad del
registro de transacciones, pero avisa de que debe realizarse antes una copia de seguridad de la
base de datos con el fin de preservar los cambios en el caso de que deba restaurarse la base de
datos.

3.3.4.2 Archivos de registro virtuales

Cada archivo de registro de transacciones se divide lógicamente en segmentos más pequeños,


denominados archivos de registro virtuales. Los archivos de registro virtuales son las unidades de
truncamiento del registro de transacciones. Cuando un archivo de registro virtual ya no contiene
registros para transacciones activas, puede truncarse con el fin de que haya espacio suficiente
para registrar nuevas transacciones.

El tamaño mínimo de un archivo de registro virtual es de 256 KB. El tamaño mínimo de un registro
de transacciones es de 512 KB, lo que proporciona dos archivos de registro virtuales de 256 KB.
El número y el tamaño de los archivos de registro virtuales en un archivo de transacciones se
incrementa a medida que lo hace el archivo de registro. Un archivo de registro de pequeño
tamaño puede tener un número reducido de pequeños archivos de registro virtuales (por ejemplo,
un archivo de registro de 5 MB puede estar compuesto por cinco archivos virtuales de 1 MB). Un
archivo de registro de gran tamaño tendrá archivos de registro virtuales más grandes (por
ejemplo, un archivo de registro de 500 MB puede contener diez archivos de registro virtuales de
50 MB).

Microsoft SQL Server intenta evitar que haya muchos archivos de registro virtuales de pequeño
tamaño. El número de archivos de registro virtuales crece mucho más lentamente que su tamaño.
Si un archivo de registro crece en pequeños incrementos, tenderá a tener muchos archivos de
registro virtuales de pequeño tamaño. Si el archivo de registro crece en incrementos mayores,
SQL Server creará un número inferior de archivos de registro virtual de mayor tamaño. Por
ejemplo, si el registro de transacciones está creciendo en incrementos de 1 MB, los archivos de
registro virtuales serán menores y más numerosos que los de un registro de transacciones que
crezca en incrementos de 50 MB. Un número elevado de archivos de registro virtuales puede
aumentar el tiempo necesario para recuperar la base de datos.

A medida que se escribe en el registro, el final del registro crece y pasa de un archivo de registro
virtual al siguiente. Si hay más de un archivo de registro físico para una base de datos, el final del
registro crece a través de cada archivo de registro virtual antes de volver al primer archivo de
registro virtual del primer archivo físico. El registro empezará a crecer automáticamente sólo
cuando se hayan llenado todos los archivos de registro.

Material de estudio Página: 131 de 249


Visual Basic 6.0 y SQLServer 7.0

3.3.5 Consideraciones sobre el diseño de Base de Datos


 Normalización

El diseño lógico de la base de datos, que incluye las tablas y sus relaciones, es la clave de una
base de datos relacional optimizada. Un buen diseño lógico de la base de datos puede asentar
los cimientos de un rendimiento óptimo de la aplicación y de la base de datos. Un diseño lógico
deficiente puede comprometer el rendimiento de todo el sistema.

La normalización de un diseño lógico de base de datos implica la utilización de métodos formales


para separar los datos en varias tablas relacionadas. Las bases de datos normalizadas se
caracterizan por tener un mayor número de tablas estrechas (con pocas columnas). Un número
escaso de tablas anchas (con más columnas) suele ser característico de las bases de datos no
normalizadas.

Por lo general, una normalización razonable permitirá mejorar el rendimiento. Cuando se


disponga de índices útiles, el optimizador de consultas de Microsoft SQL Server será una
herramienta eficiente en la selección rápida y eficaz de combinaciones entre tablas.

La normalización ofrece diversas ventajas:


• Mayor rapidez en la ordenación y en la creación de índices.
• Un número mayor de índices agrupados.
• Índices más estrechos y compactos.
• Menos índices por tabla, con lo que se mejora el rendimiento de las instrucciones
INSERT, UPDATE y DELETE.
• Menos valores NULL y reducción de las posibilidades de incoherencia, con lo que la base
de datos resulta más compacta.

A medida que progresa la normalización, aumentará el número y la complejidad de las


combinaciones necesarias para recuperar los datos. Un número muy elevado de combinaciones
relacionales complejas entre demasiadas tablas puede afectar al rendimiento. Una normalización
razonable suele incluir un número reducido de consultas que se ejecutan con regularidad y
utilizan combinaciones en las que intervienen más de cuatro tablas.

A veces, el diseño lógico de la base de datos es fijo y su remodelación resulta inviable. No


obstante, incluso en esos casos puede normalizarse de forma selectiva una tabla de gran tamaño
para crear tablas más pequeñas. Si el acceso a la base de datos se realiza mediante
procedimientos almacenados, este cambio del esquema puede llevarse a cabo sin que afecte a
las aplicaciones. De lo contrario, también puede crearse una vista que oculte a las aplicaciones el
cambio de esquema.

En la teoría del diseño de bases de datos relacionales, las reglas de normalización identifican
ciertos atributos que deben estar presentes o ausentes en una base de datos bien diseñada.
Aunque una discusión completa de las reglas de normalización se sale del objetivo de este tema,
hay algunas reglas que pueden ayudarle a mejorar el diseño de una base de datos:

• Una tabla debe tener un identificador.


La regla fundamental en la teoría del diseño de bases de datos es que cada tabla tenga
un sólo identificador de filas, una columna o un conjunto de columnas que puedan
utilizarse para diferenciar a un registro de cualquier otro de la tabla. Cada tabla debe
tener una columna de identificador, y el valor de cada identificador no debe ser
compartido por dos registros. La columna o columnas que sirvan como identificador único
de fila para una tabla constituyen la clave principal de la tabla.

Material de estudio Página: 132 de 249


Visual Basic 6.0 y SQLServer 7.0

• Una tabla sólo debe almacenar datos para un único tipo de entidad.
Si intenta almacenar demasiada información en una tabla, la confiabilidad y la eficiencia
en la administración de los datos de la tabla pueden verse afectadas. En el ejemplo
anterior de la base de datos pubs, la información acerca de los títulos y de los editores se
almacena en dos tablas distintas. Aunque es posible incluir columnas para la información
acerca de los libros y de los editores en la tabla de títulos, este tipo de diseño entraña
diversos problemas. La información acerca del editor debe ser agregada y almacenada de
forma redundante para cada libro publicado por un editor. Con este sistema, la base de
datos utiliza más espacio. Si cambia la dirección del editor, debe realizarse el cambio en
cada libro. Cuando se quita de la tabla de títulos el último libro de un editor, se pierde la
información de ese editor.

En la base de datos pubs, se almacena la información de los libros y editores en las


tablas de títulos y editores. La información acerca del editor debe especificarse una sola
vez y vincularse a cada libro. Cuando se modifica la información relativa al editor, deberá
cambiarse únicamente en un punto, y se mantendrá allí aunque no haya títulos de ese
editor en la base de datos.

• En una tabla deben evitarse las columnas que acepten valores NULL.
Las tablas pueden tener columnas definidas para permitir valores NULL. Un valor NULL
indica que no hay ningún valor. Si bien puede resultar útil permitir valores NULL en
determinados casos, es preferible no utilizarlos muy a menudo, dado que necesitan un
tratamiento especial que aumenta la complejidad de las operaciones con datos. Si tiene
una tabla con varias columnas que aceptan valores NULL y varias filas tienen valores
NULL en las columnas, conviene que considere la posibilidad de colocar esas columnas
en otra tabla vinculada con la tabla principal. Si almacena los datos en dos tablas
distintas, el diseño de la tabla principal será simple pero seguirá permitiendo almacenar
ocasionalmente ese tipo de información.

• Una tabla no debe tener valores ni columnas que se repitan.


La tabla para un elemento de la base de datos no debe contener una lista de valores para
una información específica. Por ejemplo, en un libro que figura en la base de datos pubs
pueden haber colaborado dos autores. Si sólo hay una columna para el nombre del autor
en la tabla titles, esto supone un problema. Una solución consistiría en almacenar el
nombre de los dos autores en la misma columna, pero eso dificultaría mostrar una lista de
autores. Otra solución posible sería cambiar la estructura de la tabla para agregar otra
columna para el nombre del segundo autor, pero esta solución sólo es válida cuando se
trata de dos autores. Sería necesario agregar otra columna en los casos en que tres
autores colaboraran en la creación de un libro.

Si cree que necesita almacenar una lista de valores en una sola columna, o si tiene varias
columnas para representar el mismo tipo de datos (au_lname1, au_lname2, etc.),
conviene que considere la colocación de los datos duplicados en otra tabla e incluya un
vínculo con la tabla principal. La base de datos pubs tiene una tabla para la información
acerca de los libros y otra en la que se almacenan únicamente los identificadores de los
libros y de los autores. Este diseño permite la inclusión de un número indeterminado de
autores para el mismo libro sin necesidad de modificar la definición de la tabla, y no
asigna espacio de almacenamiento sin utilizar para los libros de un solo autor.

Material de estudio Página: 133 de 249


Visual Basic 6.0 y SQLServer 7.0

 Integridad de los datos

La integridad de los datos garantiza la calidad de los datos de la base de datos. Por ejemplo, si se
especifica para un empleado el valor de employee_id (IdEmpleado) “123”, la base de datos no
debe permitir que ningún otro empleado tenga el mismo valor de identificador. Si tiene una
columna employee_rating (clasificaciónEmpleado) para la que se prevea valores entre el 1 y el
5, la base de datos no debe aceptar el valor 6. Si en la tabla hay una columna dept_id (IdDepto)
en la que se almacene el número de departamento del empleado, la base de datos sólo debe
permitir valores que correspondan a los números de departamento de la compañía.

Dos pasos importantes en el diseño de las tablas son la identificación de valores válidos para una
columna y la determinación de cómo forzar la integridad de los datos en la columna. Hay cuatro
categorías de integridad de datos:

• Integridad de entidad
• Integridad de dominio
• Integridad referencial
• Integridad definida por el usuario.

Hay varias maneras de forzar cada tipo de integridad.


Tipo de integridad Opciones recomendadas
Restricción PRIMARY KEY
Entidad Restricción UNIQUE
Propiedad IDENTITY
Definición predeterminada (DEFAULT)
Restricción FOREIGN KEY
Dominio
Restricción CHECK
NOT NULL
Restricción FOREIGN KEY
Referencial
Restricción CHECK
Todas las restricciones en columnas y tablas de CREATE TABLE
Definidos por el usuario Procedimientos almacenados
Desencadenadores

Integridad de entidad
La integridad de entidad define una fila como entidad única para una tabla determinada. La
integridad de entidad fuerza la integridad de la columna o columnas de los identificadores o la
clave principal de una tabla (mediante índices, restricciones UNIQUE, restricciones PRIMARY
KEY o propiedades IDENTITY).

Integridad de dominio
La integridad de dominio viene dada por la validez de las entradas para una columna
determinada. Puede forzar la integridad de dominio si restringe el tipo (mediante tipos de datos),
el formato (mediante las reglas y las restricciones CHECK), o el intervalo de valores posibles
(mediante restricciones FOREIGN KEY, restricciones CHECK, definiciones DEFAULT,
definiciones NOT NULL y reglas).

Integridad referencial
La integridad referencial protege las relaciones definidas entre las tablas cuando se crean o se
eliminan registros. En Microsoft SQL Server, la integridad referencial se basa en las relaciones

Material de estudio Página: 134 de 249


Visual Basic 6.0 y SQLServer 7.0

entre las claves externas y las claves principales o entre las claves externas y las claves únicas.
La integridad referencial garantiza que los valores clave son coherentes en las distintas tablas.
Para conseguir esa coherencia, es preciso que no haya referencias a valores inexistentes y que,
si cambia el valor de una clave, todas las referencias a ella se cambien en consecuencia en toda
la base de datos.

Cuando se fuerza la integridad referencial, SQL Server impide a los usuarios:


• Agregar registros a una tabla relacionada si no hay ningún registro asociado en la tabla
principal.
• Cambiar valores en una tabla principal de manera que queden registros huérfanos en una
tabla relacionada.
• Eliminar registros de una tabla principal cuando hay registros relacionados coincidentes.

Por ejemplo, con las tablas sales (compras) y titles (títulos) de la base de datos pubs, la
integridad referencial se basa en la relación entre la clave externa (title_id) de la tabla sales y la
clave principal (title_id) de la tabla titles.
¡Error! Marcador no definido.

Integridad definida por el usuario


La integridad definida por el usuario le permite definir reglas de la compañía específicas que no
pertenecen a ninguna otra categoría de integridad. Todas las categorías de integridad son
compatibles con la integridad definida por el usuario.

 Rendimiento de la base de datos


Cuando diseñe una base de datos, deberá asegurarse de que realice todas las operaciones
importantes rápida y correctamente. Algunos problemas de rendimiento pueden resolverse
cuando la base de datos ya se utiliza en la producción, pero otros pueden derivar de un diseño
deficiente de la base de datos, y sólo es posible corregirlos si se cambia su estructura y diseño.

Cuando diseñe e implemente una base de datos, deberá identificar las tablas de gran tamaño y
los procesos más complejos que vaya a realizar la base de datos, y prestar atención especial al
rendimiento al diseñar esas tablas. Considere también los efectos que puede tener en el
rendimiento el aumento del número de usuarios con acceso a la base de datos.

Los siguientes cambios, entre otros, pueden contribuir a mejorar el rendimiento:

• Si una tabla que contiene cientos de miles de filas tiene que resumirse en un informe
diario, puede agregar una o varias columnas que contengan datos previamente
agregados para utilizarlos únicamente en el informe.

• Se puede aplicar una normalización exhaustiva en las bases de datos, lo que significa que
se definen un gran número de tablas pequeñas interrelacionadas. Cuando la base de
datos procese los datos de estas tablas, deberá realizar muchas más operaciones para
combinar los datos relacionados. Este procesamiento adicional puede repercutir
negativamente en el rendimiento de la base de datos. En esos casos, una reducción de la
normalización de la base de datos para simplificar procesos complejos puede contribuir a
mejorar el rendimiento.

Además de un diseño adecuado de la base de datos, el uso correcto de los índices, sistemas
RAID (matriz redundante de discos independientes) y los grupos de archivos es importante para
conseguir un buen rendimiento.

Material de estudio Página: 135 de 249


Visual Basic 6.0 y SQLServer 7.0

Consideraciones acerca del hardware

Por lo general, cuanto mayor sea la base de datos, habrá más requisitos de hardware, aunque el
número de sesiones o usuarios simultáneos, el rendimiento de las transacciones y el tipo de
operaciones que se realicen en la base de datos también determinarán dichos requisitos. Por
ejemplo, los requisitos de hardware de una base de datos que contenga datos que se actualicen
con poca frecuencia (para una biblioteca escolar, por ejemplo), serán inferiores a los requisitos de
hardware de un almacén de datos de 1 terabyte (TB) que contenga datos de acceso frecuente de
ventas, productos y clientes de una gran compañía. Además de los requisitos de almacenamiento
en disco, se necesitará más memoria y procesadores más rápidos para que el almacén de datos
permita colocar más datos en memoria caché y para que las consultas con referencias a grandes
cantidades de datos sean procesadas con rapidez por Microsoft SQL Server.

 Mantenimiento
Después de crear una base de datos, y cuando se hayan agregado y estén operativos todos los
objetos y datos, será necesario realizar determinadas operaciones de mantenimiento. Por
ejemplo, es importante realizar copias de seguridad de la base de datos periódicamente. Es
posible que también necesite crear algunos índices adicionales para mejorar el rendimiento. Estas
cuestiones deben tenerse en cuenta a la hora de diseñar la base de datos, con el fin de reducir
los efectos en los usuarios, el tiempo necesario para realizar la tarea y el esfuerzo dedicado. A
continuación, se ofrecen algunas indicaciones para el mantenimiento:

• Diseñar la base de datos para que sea lo más pequeña posible y excluya la información
redundante. (La normalización de la base de datos puede ayudarle a conseguirlo). Por
ejemplo, si reduce el tamaño de la base de datos, puede reducir también el tiempo
necesario para realizar una copia de seguridad o, lo que es aún más importante, para
restaurar la base de datos. Esto es especialmente importante durante una operación de
restauración porque la base de datos no está disponible mientras está siendo restaurada.

• Diseñar particiones de tablas en vez de tablas únicas, si la tabla debe contener un gran
número de filas. Por ejemplo, una tabla que contenga todas las transacciones realizadas
con tarjeta de crédito que recibe un banco debe dividirse en varias tablas en las que se
distribuyan los datos por meses, por ejemplo. Así se puede facilitar el mantenimiento de
los índices, en el caso de que tuvieran que agregarse nuevos índices para mejorar el
rendimiento. Puede que sea necesario crear el índice sólo para los datos de los últimos
tres meses, debido a que ya no se hace referencia a los datos más antiguos. Cuanto
mayor sea la tabla, más tiempo se necesitará para crear nuevos índices.

Microsoft SQL Server proporciona el Asistente para planes de mantenimiento de bases de datos
con el fin de automatizar muchas de estas tareas, con lo que se reduce o se elimina el trabajo
necesario para el mantenimiento de la base de datos.

3.3.6 Estimar el tamaño de una base de datos


Cuando diseñe la base de datos, puede que necesite realizar una estimación del tamaño que
tendrá la base de datos cuando esté llena. Esta estimación puede ayudarle a determinar la
configuración de hardware que necesitará para:

• Conseguir el rendimiento que necesitan sus aplicaciones.


• Asegurar la cantidad física adecuada de espacio en disco para almacenar los datos y los
índices.

Asimismo, la estimación del tamaño de la base de datos puede ayudarle a determinar si el diseño
de su base de datos necesita reajustes. Por ejemplo, puede determinar que el tamaño estimado

Material de estudio Página: 136 de 249


Visual Basic 6.0 y SQLServer 7.0

es demasiado grande para realizar una implementación práctica en su organización y que se


necesita un mayor grado de normalización. Por el contrario, el tamaño estimado puede ser menor
del esperado, con lo que podrá reducir la normalización de la base de datos para mejorar el
rendimiento de las consultas.

Para realizar una estimación del tamaño de una base de datos, efectúe una estimación de cada
tabla por separado y sume los valores obtenidos. El tamaño de una tabla depende de si tiene
índices y, si los tiene, qué tipo de índices.

 Estimar el tamaño de una tabla


Los siguientes pasos permiten estimar la cantidad de espacio necesario para almacenar los datos
en una tabla:

1. Especifique el número de filas que habrá en la tabla.


Número de filas de la tabla = númFilas
2. Si la definición de la tabla contiene columnas de longitud fija y de longitud variable, calcule
el espacio que ocupa cada uno de estos grupos de columnas en la fila de datos. El
tamaño de una columna depende del tipo y de la longitud especificados para los datos.
Número de columnas = númCols
Suma de los bytes de todas las columnas de longitud fija = datosTñoFijo
Número de columnas de longitud variable = númColsVariables
Tamaño máximo de todas las columnas de longitud variable = tñoMáxVar
3. Si hay columnas de longitud fija en la tabla, una parte de la fila, conocida como el mapa
de bits nulo, se reserva para administrar la aceptación de valores nulos en las columnas.
Calcule su tamaño:
Mapa de bits nulo (mapaBitsNulo) = 2 + (( númCols + 7) / 8 )
Sólo debe utilizarse la parte entera de la expresión anterior; descarte el resto.
4. Si hay columnas de longitud variable en la tabla, determine cuánto espacio se utiliza para
almacenar las columnas de la fila:
Tamaño total de las columnas de longitud variable (datosTñoVar) = 2 +
(númColsVariables x 2) + tñoMáxVar
Si no hay columnas de longitud variable, establezca datosTñoVar al valor 0.
En esta fórmula, se supone que todas las columnas de longitud variable están llenas al
100 %. Si prevé que va a utilizarse un porcentaje inferior del espacio de almacenamiento
de las columnas de longitud variable, puede ajustar el resultado en función de ese
porcentaje para obtener una estimación más precisa del tamaño de la tabla.
5. Calcule el tamaño de la fila:
Tamaño total de la fila (tñoFila) = datosTñoFijo + datosTñoVar + mapaBitsNulo +4
El valor final 4 representa al encabezado de la fila de datos.
6. A continuación, calcule el número de filas por página (8096 bytes disponibles por página):
Número de filas por página (filasPorPág) = ( 8096 ) / (tñoFila + 2)
Dado que las filas no abarcan varias páginas, el número de filas por página debe
redondearse a la fila completa anterior.
7. Si va a crear un índice agrupado en la tabla, calcule el número de filas libres reservadas
por página según el factor de relleno especificado. Si no va a crear ningún índice
agrupado, establezca factorRelleno al valor 100.
Número de filas libres por página (filasLibresPorPág) = 8096 x ((100 - factorRelleno) /
100) / tñoFila
El factor de relleno que se utiliza en el cálculo es un valor entero y no un porcentaje.
Dado que las filas no abarcan varias páginas, el número de filas por página debe
redondearse a la fila completa anterior.
8. Calcule el número de páginas necesarias para almacenar todas las filas:
Número de páginas (númPágs) = númFilas / (filasPorPág - filasLibresPorPág)
El número de páginas estimado debe redondearse a la siguiente página completa.

Material de estudio Página: 137 de 249


Visual Basic 6.0 y SQLServer 7.0

9. Finalmente, calcule la cantidad de espacio necesario para almacenar los datos en una
tabla (8192 bytes por página):
Tamaño de la tabla (bytes) = 8192 x númPágs

 Estimar el tamaño de una tabla sin un índice agrupado

Los siguientes pasos permiten estimar la cantidad de espacio necesario para almacenar los datos
y los índices no agrupados adicionales en una tabla que no contiene un índice agrupado:

1. Calcule el espacio utilizado para almacenar datos.


2. Calcule el espacio utilizado para almacenar cada índice no agrupado adicional.
3. Sume los valores calculados.

Para cada cálculo, especifique el número de filas que habrá en la tabla. El número de filas de la
tabla influirá directamente en el tamaño de la tabla.
Número de filas de la tabla = númFilas

Calcular el espacio utilizado para almacenar datos


Para calcular el espacio utilizado para almacenar datos, consulte Estimar el tamaño de una tabla.
Anote el valor calculado:
Espacio utilizado para almacenar datos = espacioDatosUtilizado
Calcular el espacio utilizado para almacenar cada índice no agrupado adicional
Los siguientes pasos permiten estimar el tamaño de un índice no agrupado en una tabla que no
contiene un índice agrupado:

1. Si la definición del índice contiene columnas de longitud fija y de longitud variable, calcule
el espacio que ocupa cada uno de estos grupos de columnas en la fila del índice. El
tamaño de una columna depende del tipo y de la longitud especificados para los datos.
Para obtener más información, consulte Tipos de datos
Número de columnas de la clave del índice = númColsClave
Suma de los bytes de todas las columnas de clave de longitud fija = tñoFijoClave
Número de columnas de longitud variable de la clave del índice = númColsVarClave
Tamaño máximo de todas las columnas de clave de longitud variable = tñoVarMáxClave
2. Si hay columnas de longitud fija en el índice, una parte de la fila del índice se reserva para
el mapa de bits nulo. Calcule su tamaño:
Mapa de bits nulo del índice (mapaBitsNuloÍnd) = 2+ (( númColsClave + 7) / 8 )
Sólo debe utilizarse la parte entera de la expresión anterior; descarte el resto.
3. Si hay columnas de longitud variable en el índice, determine cuánto espacio se utiliza
para almacenar las columnas de la fila del índice:
Tamaño total de las columnas de longitud variable (tñoVarClave) = 2 + (númColsVarClave
x 2) + tñoVarMáxClave
Si no hay columnas de longitud variable, establezca tñoVarClave al valor 0.
En esta fórmula, se supone que todas las columnas de clave de longitud variable están
llenas al cien por cien. Si prevé que va a utilizarse un porcentaje inferior del espacio de
almacenamiento de las columnas de clave de longitud variable, puede ajustar el resultado
en función de ese porcentaje para obtener una estimación más precisa del tamaño del
índice.
4. Calcule el tamaño de la fila del índice:
Tamaño total de la fila del índice (tñoFilaÍnd) = tñoFijoClave + tñoVarClave +
mapaBitsNuloÍnd + 1 + 8
5. A continuación, calcule el número de filas de índice por página (8096 bytes libres por
página):

Material de estudio Página: 138 de 249


Visual Basic 6.0 y SQLServer 7.0

Número de filas de índice por página (filasÍndPorPág) = ( 8096 ) / (tñoFilaÍnd + 2)


Dado que las filas de índice no abarcan varias páginas, el número de filas de índice por
página debe redondearse a la fila completa anterior.
6. Calcule el número de filas de índice libres reservadas por página de hoja según el factor
de relleno especificado para el índice no agrupado. Para obtener más información,
consulte Factor de relleno.
Número de filas de índice libres por página de hoja (filasÍndLibresPorPág) = 8096 x ((100
- factorRelleno) / 100) /
tñoFilaÍnd
El factor de relleno que se utiliza en el cálculo es un valor entero y no un porcentaje.
Dado que las filas de índice no abarcan varias páginas, el número de filas de índice por
página debe redondearse a la fila completa anterior.
7. A continuación, calcule el número de páginas necesarias para almacenar todas las filas
en cada nivel del índice:
Número de páginas (nivel 0) (númPágsNivel0) = númFilas / (filasÍndPorPág -
filasÍndLibresPorPág)
Número de páginas (nivel 1) (númPágsNivel1) = númPágsNivel0 / filasÍndPorPág
Repita el segundo cálculo, pero divida el número de páginas calculado a partir del nivel
anterior n por filasÍndPorPág hasta que el número de páginas para un nivel n dado
(númPágsNiveln) sea igual a una (página raíz). Por ejemplo, para calcular el número de
páginas necesarias para el segundo nivel del índice:
Número de páginas (nivel 2) (númPágsNivel2) = númPágsNivel1 / filasÍndPorPág
Para cada nivel, el número estimado de páginas debe redondearse a la siguiente página
completa.
Sume el número de páginas necesarias para almacenar cada nivel del índice:
Número total de páginas (númPágsÍnd) = númPágsNivel0 + númPágsNivel1 +
númPágsNivel2 + … + númPágsNiveln
8. Finalmente, calcule el tamaño del índice (8192 bytes por página):
Tamaño del índice no agrupado (bytes) = 8192 x númPágsÍnd

Calcular el tamaño de la tabla


Calcule el tamaño de la tabla:
Tamaño total de la tabla (bytes) = espacioDatosUtilizado + Tamaño del índice no agrupado + …n

Estimar el tamaño de una tabla con un índice agrupado


Los siguientes pasos permiten estimar la cantidad de espacio necesario para almacenar los datos
y los índices no agrupados adicionales en una tabla que contiene un índice agrupado:

1. Calcule el espacio utilizado para almacenar datos.


2. Calcule el espacio utilizado para almacenar el índice agrupado.
3. Calcule el espacio utilizado para almacenar cada índice no agrupado adicional.
4. Sume los valores calculados.

Para cada cálculo, especifique el número de filas que habrá en la tabla. El número de filas de la
tabla influirá directamente en el tamaño de la tabla.
Número de filas de la tabla = númFilas

Calcular el espacio utilizado para almacenar datos


Para calcular el espacio utilizado para almacenar datos, consulte Estimar el tamaño de una tabla.
Anote el valor calculado:

Material de estudio Página: 139 de 249


Visual Basic 6.0 y SQLServer 7.0

Espacio utilizado para almacenar datos = espacioDatosUtilizado

Calcular el espacio utilizado para almacenar el índice agrupado

Los siguientes pasos permiten estimar la cantidad de espacio necesario para almacenar el índice
agrupado:
1. La definición del índice agrupado puede contener columnas de longitud fija y de longitud
variable. Para estimar el tamaño del índice agrupado, deberá especificar el espacio que
ocupa cada uno de estos grupos de columnas en la fila del índice.
Número de columnas de la clave del índice = númColsClaveAgr
Suma de los bytes de todas las columnas de clave de longitud fija = tñoFijoClaveAgr
Número de columnas de longitud variable de la clave del índice = númColsVarClaveAgr
Tamaño máximo de todas las columnas de clave de longitud variable =
tñoVarMáxClaveAgr
2. Si hay columnas de longitud fija en el índice agrupado, una parte de la fila del índice se
reserva para el mapa de bits nulo. Calcule su tamaño:
Mapa de bits nulo del índice (mapaBitsNuloÍndAgr) = 2 + (( númColsClaveAgr + 7) / 8 )
Sólo debe utilizarse la parte entera de la expresión anterior; descarte el resto.
3. Si hay columnas de longitud variable en el índice, determine cuánto espacio se utiliza
para almacenar las columnas de la fila del índice:
Tamaño total de las columnas de longitud variable (tñoVarClaveAgr) = 2 +
(númColsVarClaveAgr x 2) + tñoVarMáxClaveAgr
Si no hay columnas de longitud variable, establezca tñoVarClaveAgr al valor 0.
En esta fórmula, se supone que todas las columnas de la clave de longitud variable están
llenas al cien por cien. Si prevé que va a utilizarse un porcentaje inferior del espacio de
almacenamiento de las columnas de la clave de longitud variable, puede ajustar el
resultado en función de ese porcentaje para obtener una estimación más precisa del
tamaño del índice.
4. Calcule el tamaño de la fila del índice:
Tamaño total de la fila del índice (tñoFilaÍndAgr) = tñoFijoClaveAgr + tñoVarClaveAgr +
mapaBitsNuloÍndAgr + 1 + 8
5. A continuación, calcule el número de filas de índice por página (8096 bytes libres por
página):
Número de filas de índice por página (filasÍndAgrPorPág) = ( 8096 ) / (tñoFilaÍndAgr + 2)
Dado que las filas de índice no abarcan varias páginas, el número de filas de índice por
página debe redondearse a la fila completa anterior.
6. A continuación, calcule el número de páginas necesarias para almacenar todas las filas
en cada nivel del índice:
Número de páginas (nivel 0) (númPágsNivelAgr0) = (espacioDatosUtilizado / 8192) /
filasÍndAgrPorPág
Número de páginas (nivel 1) (númPágsNivelAgr1) = númPágsNivelAgr0 /
filasÍndAgrPorPág
Repita el segundo cálculo, pero divida el número de páginas calculado a partir del nivel
anterior n por filasÍndAgrPorPág hasta que el número de páginas para un nivel n dado
(númPágsNivelAgrn) sea igual a una (página raíz del índice). Por ejemplo, para calcular el
número de páginas necesarias para el segundo nivel del índice:
Número de páginas (nivel 2) (númPágsNivelAgr2) = númPágsNivelAgr1 /
filasÍndAgrPorPág
Para cada nivel, el número estimado de páginas debe redondearse a la siguiente página
completa.
Sume el número de páginas necesarias para almacenar cada nivel del índice:
Número total de páginas (númPágsÍndAgr) = númPágsNivelAgr0 + númPágsNivelAgr1 +
númPágsNivelAgr2 + … + númPágsNivelAgrn
7. Calcule el tamaño del índice agrupado (8192 bytes por página):

Material de estudio Página: 140 de 249


Visual Basic 6.0 y SQLServer 7.0

Tamaño del índice agrupado (bytes) = 8192 x númPágsÍndAgr

 Calcular el espacio utilizado para almacenar cada índice no agrupado adicional

Los siguientes pasos permiten estimar la cantidad de espacio necesario para almacenar cada
índice no agrupado adicional:
1. La definición del índice no agrupado puede contener columnas de longitud fija y de
longitud variable. Para estimar el tamaño del índice no agrupado, deberá calcular el
espacio que ocupa cada uno de estos grupos de columnas en la fila del índice.
Número de columnas de la clave del índice = númColsClave
Suma de los bytes de todas las columnas de la clave de longitud fija = tñoFijoClave
Número de columnas de longitud variable de la clave del índice = númColsVarClave
Tamaño máximo de todas las columnas de clave de longitud variable = tñoVarMáxClave
2. Si hay columnas de longitud fija en el índice, una parte de la fila del índice se reserva para
el mapa de bits nulo. Calcule su tamaño:
Mapa de bits nulo del índice (mapaBitsNuloÍnd) = 2 + (( númColsClave + 7) / 8 )
Sólo debe utilizarse la parte entera de la expresión anterior; descarte el resto.
3. Si hay columnas de longitud variable en el índice, determine cuánto espacio se utiliza
para almacenar las columnas de la fila del índice:
Tamaño total de las columnas de longitud variable (tñoVarClave) = 2 + (númColsVarClave
x 2) + tñoVarMáxClave
Si no hay columnas de longitud variable, establezca tñoVarClave al valor 0.
En esta fórmula, se supone que todas las columnas de la clave de longitud variable están
llenas al cien por cien. Si prevé que va a utilizarse un porcentaje inferior del espacio de
almacenamiento de las columnas de la clave de longitud variable, puede ajustar el
resultado en función de ese porcentaje para obtener una estimación más precisa del
tamaño del índice.
4. Calcule el tamaño de la fila del índice que no es una hoja:
Tamaño total de la fila del índice no de hoja (tñoFilaÍndNH) = tñoFijoClave + tñoVarClave
+ mapaBitsNuloÍnd + 1 + 8
5. A continuación, calcule el número de filas de índice que no es hoja por página:
Número de filas de índice no de hoja por página (filasÍndNHPorPág) =
( 8096 ) / (tñoFilaÍndNH + 2)
Dado que las filas de índice no abarcan varias páginas, el número de filas de índice por
página debe redondearse a la fila completa anterior.
6. Calcule el tamaño de la fila del índice de hoja:
Tamaño total de la fila del índice de hoja (tñoFilaÍnd) = tñoFilaÍndAgr + tñoFijoClave +
tñoVarClave + mapaBitsNuloÍnd + 1
El valor final 1 representa el encabezado de la fila del índice. tñoFilaÍndAgr es el tamaño
total de la fila del índice para la clave del índice agrupado.
7. A continuación, calcule el número de filas de índice de nivel de hoja por página:
Número de filas de índice de nivel de hoja por página (filasÍndPorPág) = ( 8096 ) /
(tñoFilaÍnd + 2)
Dado que las filas de índice no abarcan varias páginas, el número de filas de índice por
página debe redondearse a la fila completa anterior.
8. Calcule el número de filas de índice libres reservadas por página según el factor de
relleno especificado para el índice no agrupado. Para obtener más información, consulte
Factor de relleno.
Número de filas de índice libres por página (filasÍndLibresPorPág) = 8096 x ((100 -
factorRelleno) / 100) /
tñoFilaÍnd
El factor de relleno que se utiliza en el cálculo es un valor entero y no un porcentaje.
Dado que las filas de índice no abarcan varias páginas, el número de filas de índice por
página debe redondearse a la fila completa anterior.

Material de estudio Página: 141 de 249


Visual Basic 6.0 y SQLServer 7.0

9. A continuación, calcule el número de páginas necesarias para almacenar todas las filas
en cada nivel del índice:
Número de páginas (nivel 0) (númPágsNivel0) = númFilas / (filasÍndPorPág -
filasÍndLibresPorPág)
Número de páginas (nivel 1) (númPágsNivel1) = númPágsNivel0 / filasÍndNHPorPág
Repita el segundo cálculo, pero divida el número de páginas calculado a partir del nivel
anterior n por filasÍndNHPorPág hasta que el número de páginas para un nivel n dado
(númPágsNiveln) sea igual a una (página raíz).
Por ejemplo, para calcular el número de páginas necesarias para los niveles segundo y
tercero del índice:
Número de páginas de datos (nivel 2) (númPágsNivel2) = númPágsNivel1 /
filasÍndNHPorPág
Número de páginas de datos (nivel 3) (númPágsNivel3) = númPágsNivel2 /
filasÍndNHPorPág
Para cada nivel, el número estimado de páginas debe redondearse a la siguiente página
completa.
Sume el número de páginas necesarias para almacenar cada nivel del índice:
Número total de páginas (númPágsÍnd) = númPágsNivel0 + númPágsNivel1
+númPágsNivel2 + … + númPágsNiveln
10. Finalmente, calcule el tamaño del índice no agrupado:
Tamaño del índice no agrupado (bytes) = 8192 x númPágsÍnd

Calcular el tamaño de la tabla


Calcule el tamaño de la tabla:
Tamaño total de la tabla (bytes) = espacioDatosUtilizado + Tamaño del índice agrupado +
Tamaño del índice no agrupado + …n

Material de estudio Página: 142 de 249


Visual Basic 6.0 y SQLServer 7.0

3.4 Crear Bases de datos

Crea una nueva base de datos y los archivos que se utilizan para almacenar la base de datos o
adjunta una base de datos desde los archivos de una base de datos creada anteriormente.

Sintaxis
CREATE DATABASE nombreBaseDatos
[ ON [PRIMARY]
[ <filespec> [,…n] ]
[, <grupoArchivos> [,…n] ]
]
[ LOG ON { <filespec> [,…n]} ]
[ FOR LOAD | FOR ATTACH ]
<filespec> ::=
( [ NAME = nombreArchivoLógico, ]
FILENAME = 'nombreArchivoSO'
[, SIZE = tamaño]
[, MAXSIZE = { tamañoMáximo | UNLIMITED } ]
[, FILEGROWTH = incrementoCrecimiento] ) [,…n]
<grupoArchivos>::=
FILEGROUP nombreGrupoArchivos <filespec> [,…n]

Argumentos

nombreBaseDatos
Es el nombre de la nueva base de datos. Los nombres de base de datos deben ser únicos en un
servidor y deben seguir las reglas de los identificadores. nombreBaseDatos puede tener hasta
128 caracteres, a menos que no se especifique ningún nombre lógico para el registro. Si no se
especifica ningún nombre lógico de archivo de registro, Microsoft SQL Server genera un nombre
lógico al anexar un sufijo a nombreBaseDatos. Esto limita nombreBaseDatos a 123 caracteres,
por lo que el nombre lógico generado del archivo de registro es menor de 128 caracteres.

ON
Especifica que los archivos de disco utilizados para almacenar la parte de datos de la base de
datos (archivos de datos) se han definido explícitamente. La palabra clave va seguida de una lista
delimitada por comas de elementos <filespec> que definen los archivos de datos del grupo de
archivos principal. A continuación de la lista de archivos del grupo de archivos principal se puede
colocar una lista opcional, delimitada por comas, de elementos <grupoArchivos> que definen los
grupos de archivos de usuario y sus archivos.

PRIMARY
Especifica que la lista <filespec> asociada define el archivo principal. El grupo de archivos
principal contiene todas las tablas del sistema de base de datos. También contiene todos los
objetos no asignados a los grupos de archivos de usuario. La primera entrada <filespec> del
grupo de archivos principal pasa a ser el archivo principal, que es el archivo que contiene el inicio
lógico de la base de datos y las tablas del sistema. Una base de datos sólo puede tener un
archivo principal. Si no se especifica PRIMARY, el primer archivo enumerado en la instrucción
CREATE DATABASE se convierte en el archivo principal.
n

Material de estudio Página: 143 de 249


Visual Basic 6.0 y SQLServer 7.0

Es un marcador de posición que indica que se pueden especificar múltiples archivos para la
nueva base de datos.

LOG ON
Especifica que los archivos del disco utilizados para almacenar el registro de la base de datos
(archivos de registro) se han definido explícitamente. La palabra clave va seguida de una lista
delimitada por comas de elementos <filespec> que definen los archivos de registro. Si no se
especifica LOG ON, se crea automáticamente un único archivo de registro con un nombre
generado por el sistema y un tamaño que es el 25 por ciento de la suma de los tamaños de todos
los archivos de datos de la base de datos.

FOR LOAD
Esta cláusula se mantiene por compatibilidad con las versiones anteriores de Microsoft SQL
Server. La base de datos se crea con la opción de base de datos dbo use only activada y el
estado se establece en "cargando". Esto no es necesario en SQL Server versión 7.0 porque la
instrucción RESTORE puede volver a crear una base de datos como parte de la operación de
restauración.

Si adjunta una base de datos a un servidor distinto del que se separó la base de datos y la base
de datos separada estaba habilitada para duplicación, debe ejecutar sp_removedbreplication
para quitar la duplicación de la base de datos.

FOR ATTACH
Especifica que se ha adjuntado una base de datos desde un conjunto existente de archivos del
sistema operativo. Debe haber una entrada <filespec> que especifique el primer archivo principal.
De las restantes entradas <filespec>, las únicas necesarias son las de cualquier otro archivo que
tenga una ruta de acceso distinta de cuando se creó la base de datos por primera vez o se
adjuntó por última vez. Debe especificarse una entrada <filespec> para estos archivos. La base
de datos que se está adjuntando debe haberse creado mediante la misma página de códigos y
ordenación que SQL Server. Utilice el procedimiento almacenado del sistema sp_attach_db en
lugar de emplear CREATE DATABASE FOR ATTACH directamente. Utilice CREATE DATABASE
FOR ATTACH sólo cuando deba especificar más de 16 elementos <filespec>.

NAME
Especifica el nombre lógico del archivo definido por <filespec>. El parámetro NAME no se
requiere cuando se especifica FOR ATTACH.

nombreArchivoLógico
Es el nombre utilizado para hacer referencia al archivo en las instrucciones Transact-SQL que se
ejecuten después de que se haya creado la base de datos. nombreArchivoLógico debe ser único
en la base de datos y debe seguir las reglas de los identificadores. El nombre puede ser un
carácter o una constante Unicode, o un identificador regular o delimitado.

FILENAME
Especifica el nombre de archivo del sistema operativo del archivo definido por <filespec>.
'nombreArchivoSO'
Es la ruta de acceso y nombre de archivo que el sistema operativo utiliza cuando crea el archivo
físico definido por <filespec>. La ruta de acceso de nombreArchivoSO debe especificar un

Material de estudio Página: 144 de 249


Visual Basic 6.0 y SQLServer 7.0

directorio en el servidor en el que está instalado SQL Server. nombreArchivoSO no puede


especificar un directorio en un sistema comprimido de archivos.

Si el sistema se crea en una partición sin formato, nombreArchivoSO sólo debe indicar la letra de
la unidad de una partición sin formato existente. En cada partición sin formato sólo se puede crear
un archivo. Los archivos de las particiones sin formato no aumentan automáticamente; por tanto,
los parámetros MAXSIZE y FILEGROWTH no son necesarios cuando nombreArchivoSO
especifica una partición sin formato.

SIZE
Especifica el tamaño del archivo definido en <filespec>. Cuando en <filespec> no se especifica un
parámetro SIZE para el archivo principal, SQL Server utiliza el tamaño del archivo principal de la
base de datos model. Cuando en <filespec> no se especifica un parámetro SIZE para un archivo
secundario o de registro, SQL Server hace el archivo de 1 MB.

tamaño
Es el tamaño inicial del archivo definido en <filespec>. Se pueden utilizar los sufijos KB y MB para
especificar si se trata de kilobytes o megabytes; el valor predeterminado es MB. Especifique un
número entero; no incluya decimales. El valor mínimo de tamaño es 512 KB. Si no se especifica
tamaño, el valor predeterminado es 1 MB. El tamaño especificado para el archivo principal debe
tener al menos el tamaño del archivo principal de la base de datos model.

MAXSIZE
Especifica el tamaño máximo al que puede aumentar el archivo definido en <filespec>.

tamañoMáximo
Es el tamaño máximo al que puede aumentar el archivo definido en <filespec>. Se pueden utilizar
los sufijos KB y MB para especificar si se trata de kilobytes o megabytes; el valor predeterminado
es MB. Especifique un número entero; no incluya decimales. Si tamañoMáximo no se especifica,
el archivo aumenta hasta que el disco esté lleno.

Nota El registro del sistema S/B de Microsoft Windows NT avisa al administrador del sistema SQL
Server cuando un disco esté a punto de llenarse.

UNLIMITED
Especifica que el archivo definido en <filespec> aumenta hasta que el disco esté lleno.

FILEGROWTH
Especifica el incremento de crecimiento del archivo definido en <filespec>. El valor FILEGROWTH
de un archivo no puede exceder del valor MAXSIZE.

incrementoCrecimiento
Es la cantidad de espacio que se agrega al archivo cada vez que se necesita espacio.
Especifique un número entero; no incluya decimales. Un valor 0 indica que no hay aumento de
tamaño. El valor se puede especificar en MB, KB o %. Si se especifica un número sin los sufijos

Material de estudio Página: 145 de 249


Visual Basic 6.0 y SQLServer 7.0

MB, KB o %, el valor predeterminado es MB. Cuando se especifica %, el tamaño de incremento


de crecimiento es el porcentaje especificado del tamaño del archivo en el momento en que tiene
lugar el incremento. Si no se especifica FILEGROWTH, el valor predeterminado es 10% y el valor
mínimo es 64 KB. El tamaño especificado se redondea al múltiplo de 64 KB más cercano.

Observaciones

Puede utilizar una instrucción CREATE DATABASE para crear una base de datos y los archivos
que almacenan la base de datos. SQL Server implementa la instrucción CREATE DATABASE en
dos pasos:
1. SQL Server utiliza una copia de la base de datos model para inicializar la base de datos y
sus metadatos.
2. SQL Server rellena el resto de la base de datos con páginas vacías, excepto las páginas
que tengan datos internos que registren cómo se emplea el espacio en la base de datos.

Cualquier objeto definido por el usuario de la base de datos model se copiará a todas las bases
de datos recién creadas. Puede agregar a la base de datos model cualquier objeto (como tablas,
procedimientos almacenados, tipos de datos, etc.) que desee tener en todas las bases de datos.

Cada base de datos nueva hereda los valores opcionales de la base de datos model (a menos
que se especifique FOR ATTACH). Por ejemplo, la opción de base de datos select into o copia
masiva se ha establecido como OFF en model y en cualquier base de datos nueva que se cree.
Si utiliza sp_dboption para cambiar las opciones de la base de datos model, estos valores de
opción entrarán en efecto para cualquier base de datos nueva que se cree. Si se especifica FOR
ATTACH en la instrucción CREATE DATABASE, la nueva base de datos hereda los valores
opcionales de la base de datos original.

En un servidor se puede especificar un máximo de 32767 bases de datos.

Para almacenar una base de datos se emplean tres tipos de archivos:


• El archivo principal contiene la información de inicio de la base de datos. El archivo
principal se utiliza también para almacenar datos. Cada base de datos tiene un único
archivo principal.
• Los archivos secundarios almacenan todos los datos que no caben en el archivo principal
de datos. Las bases de datos no necesitan archivos de datos secundarios si el archivo
principal es suficientemente grande para contener todos los datos de la base de datos.
Otras bases de datos pueden ser suficientemente grandes para necesitar múltiples
archivos de datos secundarios o pueden utilizar archivos secundarios en discos
separados para repartir los datos entre múltiples discos.
• Los archivos del registro de transacciones contienen la información del registro que se
utiliza para recuperar la base de datos. Debe haber al menos un archivo de registro de
transacciones para cada base de datos, aunque puede haber más de uno. El tamaño
mínimo de un archivo de registro de transacciones es de 512 KB.

Cada base de datos tiene al menos dos archivos, un archivo principal y un archivo de registro de
transacciones.

Aunque nombreArchivoSO puede ser cualquier nombre de archivo válido del sistema operativo, el
nombre reflejará más claramente el propósito del archivo si utiliza las siguientes extensiones
recomendadas.

Tipo de archivo Extensión de nombre de archivo recomendada


Archivo de datos principal .mdf
Archivo de datos secundario .ndf
Archivo de registro de transacciones .ldf

Material de estudio Página: 146 de 249


Visual Basic 6.0 y SQLServer 7.0

Nota Cada vez que se cree una base de datos de usuario, debe hacerse una copia de seguridad
de la base de datos master.

No es posible especificar fracciones en los parámetros SIZE, MAXSIZE y FILEGROWTH. Para


especificar una fracción de un megabyte en los parámetros de tamaño, conviértalos a kilobytes;
para ello, multiplique el número por 1024. Por ejemplo, especifique 1536 KB en lugar de 1,5 MB
(1,5 por 1024 es igual a 1536).

Cuando se especifica una instrucción individual CREATE DATABASE nombreBaseDatos sin


parámetros adicionales, la base de datos se crea con el mismo tamaño que la base de datos
model.

Todas las bases de datos tienen al menos un grupo de archivos principal. Todas las tablas del
sistema se encuentran en el grupo de archivos principal. Una base de datos puede tener también
grupos de archivos definidos por el usuario. Si se crea un objeto con una cláusula ON
grupoArchivos que especifica un grupo de archivos definido por el usuario, todas las páginas del
objeto se asignan desde el grupo de archivos especificado. Las páginas de todos los objetos de
usuario creados sin una cláusula ON grupoArchivos, o con una cláusula ON DEFAULT, se
asignan desde el grupo de archivos predeterminado. Cuando se crea una base de datos por
primera vez, el grupo de archivos principal es el grupo de archivos predeterminado. Con ALTER
DATABASE, se puede especificar que un grupo de archivos definido por el usuario sea el grupo
de archivos predeterminado:

ALTER DATABASE nombreBaseDatos MODIFY FILEGROUP nombreGrupoArchivos


DEFAULT

Cada base de datos tiene un propietario con capacidad para realizar actividades especiales en la
base de datos. El propietario es el usuario que crea la base de datos. El propietario de la base de
datos se puede cambiar mediante sp_changedbowner.

Para mostrar un informe de una base de datos o de todas las bases de datos de un servidor con
SQL Server, ejecute sp_helpdb. Para obtener un informe acerca del espacio utilizado en una
base de datos, emplee sp_spaceused. Para obtener un informe de los grupos de archivos de una
base de datos, utilice sp_helpfilegroup, y utilice sp_helpfile para obtener el informe de los
archivos de la base de datos.

Las versiones anteriores de SQL Server utilizaban las instrucciones DISK INIT para crear los
archivos de la base de datos antes de que se ejecutara la instrucción CREATE DATABASE. Por
motivos de compatibilidad con las versiones anteriores de SQL Server, la instrucción CREATE
DATABASE puede crear también una nueva base de datos con archivos o dispositivos que se
crearon con la instrucción DISK INIT.

Permisos
De forma predeterminada, los permisos de CREATE DATABASE son los de los miembros de las
funciones fijas de servidor sysadmin y dbcreator. Los miembros de las funciones fijas de
servidor sysadmin y securityadmin pueden conceder permisos CREATE DATABASE a otros
inicios de sesión. Los miembros de las funciones fijas de servidor sysadmin y dbcreator pueden
agregar otros inicios de sesión a la función dbcreator. El permiso CREATE DATABASE debe
concederse explícitamente; no se concede mediante la instrucción GRANT ALL.

El permiso CREATE DATABASE se limita normalmente a unos cuantos inicios de sesión para
mantener el control de la utilización de los discos del equipo que ejecuta SQL Server.

Material de estudio Página: 147 de 249


Visual Basic 6.0 y SQLServer 7.0

Ejemplos

A. Crear una base de datos que especifique los archivos de registro de datos y de transacciones
Este ejemplo crea una base de datos llamada Sales. Debido a que no se utiliza la palabra clave
PRIMARY, el primer archivo (Sales_dat) se convierte, de forma predeterminada, en el archivo
principal. Como no se especifican MB ni KB en el parámetro SIZE del archivo Sales_dat, de
forma predeterminada, dicho parámetro indica MB y el tamaño se asigna en megabytes. El
tamaño del archivo Sales_log se asigna en megabytes porque se ha indicado explícitamente el
sufijo MB en el parámetro SIZE.

USE master
GO
CREATE DATABASE Sales
ON
( NAME = Sales_dat,
FILENAME = 'c:\mssql7\data\saledat.mdf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 )
LOG ON
( NAME = 'Sales_log',
FILENAME = 'c:\mssql7\data\salelog.ldf',
SIZE = 5MB,
MAXSIZE = 25MB,
FILEGROWTH = 5MB )
GO

B. Crear una base de datos mediante la especificación de múltiples archivos de registro de datos y de
transacciones
Este ejemplo crea una base de datos llamada Archive con tres archivos de datos de 100 MB y
dos archivos de registro de transacciones de 100 MB. El archivo principal es el primer archivo de
la lista y se especifica explícitamente con la palabra clave PRIMARY. Los archivos de registro de
transacciones se especifican a continuación de las palabras clave LOG ON. Observe las
extensiones que se emplean para los archivos de la opción FILENAME: .mdf se utiliza para los
archivos principales, .ndf para los archivos secundarios y .ldf para los archivos de registro de
transacciones.

USE master
GO
CREATE DATABASE Archive
ON
PRIMARY ( NAME = Arch1,
FILENAME = 'c:\mssql7\data\archdat1.mdf',
SIZE = 100MB,
MAXSIZE = 200,
FILEGROWTH = 20),
( NAME = Arch2,
FILENAME = 'c:\mssql7\data\archdat2.ndf',
SIZE = 100MB,
MAXSIZE = 200,
FILEGROWTH = 20),
( NAME = Arch3,
FILENAME = 'c:\mssql7\data\archdat3.ndf',
SIZE = 100MB,

Material de estudio Página: 148 de 249


Visual Basic 6.0 y SQLServer 7.0

MAXSIZE = 200,
FILEGROWTH = 20)
LOG ON
( NAME = Archlog1,
FILENAME = 'c:\mssql7\data\archlog1.ldf',
SIZE = 100MB,
MAXSIZE = 200,
FILEGROWTH = 20),
( NAME = Archlog2,
FILENAME = 'c:\mssql7\data\archlog2.ldf',
SIZE = 100MB,
MAXSIZE = 200,
FILEGROWTH = 20)
GO

C. Crear una base de datos individual


En este ejemplo se crea una base de datos llamada Products y se especifica un único archivo.
De forma predeterminada, el archivo especificado se convierte en el archivo principal; se crea
automáticamente un archivo de registro de transacciones de 1 MB. Como no se especifica MB ni
KB en el parámetro SIZE del archivo principal, el tamaño del archivo principal se asigna en
megabytes. Ya que no existe <filespec> para el archivo de registro de transacciones, éste no
tiene MAXSIZE y puede crecer hasta llenar todo el espacio disponible en el disco.

USE master
GO
CREATE DATABASE Products
ON
( NAME = prods_dat,
FILENAME = 'c:\mssql7\data\prods.mdf',
SIZE = 4,
MAXSIZE = 10,
FILEGROWTH = 1 )
GO

D. Crear una base de datos sin especificar los archivos


Este ejemplo crea una base de datos llamada mytest y crea los archivos principal y de registro de
transacciones correspondientes. Debido a que la instrucción no tiene elementos <filespec>, el
archivo principal de la base de datos tiene el tamaño del archivo principal de la base de datos
model. El registro de transacciones tiene el tamaño del archivo del registro de transacciones de la
base de datos model. Como no se ha especificado MAXSIZE, los archivos pueden crecer hasta
llenar todo el espacio disponible en disco.

CREATE DATABASE mytest

E. Crear una base de datos sin especificar SIZE


Este ejemplo crea una base de datos llamada products2. De forma predeterminada, el archivo
prods2_dat se convierte en el archivo principal, con un tamaño igual al tamaño del archivo
principal de la base de datos model. El archivo de registro de transacciones se crea
automáticamente y es un 25 por ciento del tamaño del archivo principal, o 512 KB, el que sea
mayor. Como no se ha especificado MAXSIZE, los archivos pueden crecer hasta llenar todo el
espacio disponible en disco.

Material de estudio Página: 149 de 249


Visual Basic 6.0 y SQLServer 7.0

USE master
GO
CREATE DATABASE Products2
ON
( NAME = prods2_dat,
FILENAME = 'c:\mssql7\data\prods2.mdf' )
GO

F. Crear una base de datos con grupos de archivos


Este ejemplo crea una base de datos llamada sales con tres grupos de archivos:
• El grupo de archivos principal con los archivos Spri1_dat y Spri2_dat. El incremento de
FILEGROWTH de estos archivos se especifica como el 15%.
• Un grupo de archivos llamado SalesGroup1 con los archivos SGrp1Fi1 y SGrp1Fi2.
• Un grupo de archivos llamado SalesGroup2 con los archivos SGrp2Fi1 y SGrp2Fi2.

CREATE DATABASE Sales


ON PRIMARY
( NAME = SPri1_dat,
FILENAME = 'c:\mssql7\data\SPri1dat.mdf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 15% ),
( NAME = SPri2_dat,
FILENAME = 'c:\mssql7\data\SPri2dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 15% ),
FILEGROUP SalesGroup1
( NAME = SGrp1Fi1_dat,
FILENAME = 'c:\mssql7\data\SG1Fi1dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 ),
( NAME = SGrp1Fi2_dat,
FILENAME = 'c:\mssql7\data\SG1Fi2dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 ),
FILEGROUP SalesGroup2
( NAME = SGrp2Fi1_dat,
FILENAME = 'c:\mssql7\data\SG2Fi1dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 ),
( NAME = SGrp2Fi2_dat,
FILENAME = 'c:\mssql7\data\SG2Fi2dt.ndf',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 )
LOG ON
( NAME = 'Sales_log',
FILENAME = 'c:\mssql7\data\salelog.ldf',
SIZE = 5MB,

Material de estudio Página: 150 de 249


Visual Basic 6.0 y SQLServer 7.0

MAXSIZE = 25MB,
FILEGROWTH = 5MB )
GO

G. Adjuntar una base de datos


El ejemplo B creó una base de datos llamada Archive con los siguientes archivos físicos:

c:\mssql7\data\archdat1.mdf
c:\mssql7\data\archdat2.ndf
c:\mssql7\data\archdat3.ndf
c:\mssql7\data\archlog1.ldf
c:\mssql7\data\archlog2.ldf

La base de datos puede separarse con el procedimiento almacenado sp_detach_db y, después,


puede volverse a adjuntar mediante CREATE DATABASE con la cláusula FOR ATTACH:

sp_detach_db Archive
GO
CREATE DATABASE Archive
ON PRIMARY (FILENAME = 'c:\mssql7\data\archdat1.mdf')
FOR ATTACH
GO

H. Utilizar particiones sin formato


Este ejemplo crea una base de datos llamada Employees con particiones sin formato. Las
particiones sin formato deben existir cuando se ejecuta la instrucción y en cada partición sin
formato sólo puede almacenarse un archivo.

USE master
GO
CREATE DATABASE Employees
ON
( NAME = Empl_dat,
FILENAME = 'f:',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 )
LOG ON
( NAME = 'Sales_log',
FILENAME = 'g:',
SIZE = 5MB,
MAXSIZE = 25MB,
FILEGROWTH = 5MB )
GO

3.5 Creación de Tablas


Las tablas son objetos de la base de datos que contienen todos sus datos. Una tabla se define
mediante una colección de columnas. En las tablas, los datos se organizan con arreglo a un
formato de filas y columnas, similar al de una hoja de cálculo. Cada fila representa a un registro
único, y cada columna representa a un campo dentro de un registro. Por ejemplo, en una tabla

Material de estudio Página: 151 de 249


Visual Basic 6.0 y SQLServer 7.0

que contenga los datos de los empleados de una compañía puede haber una fila para cada
empleado y distintas columnas en las que figuren detalles de los empleados tales como el número
de empleado, el nombre, la dirección, el puesto que ocupa y su número de teléfono particular.

Cuando diseñe una base de datos, deberá decidir qué tablas necesita, qué tipo de datos van
destinados a cada tabla, quién puede tener acceso a cada tabla, etc. Cuando cree tablas y trabaje
con ellas, seguirá tomando decisiones más específicas acerca de las mismas.

El método más eficiente para crear una tabla consiste en definir todo lo que se necesita en la
tabla al mismo tiempo, incluidas las restricciones para los datos y los componentes adicionales.
No obstante, también puede crear una tabla básica, agregar algunos datos y trabajar con la tabla
durante algún tiempo. Así, tendrá ocasión de ver cuáles son los tipos de transacciones más
habituales y qué tipos de datos se utilizan con más frecuencia antes de confirmar un diseño más
estable que incluya restricciones, índices, valores predeterminados, reglas y otros objetos.

Puede ser una buena idea que esboce sus planes en papel antes de crear una tabla y sus
objetos.

Entre las decisiones que deben tomarse, se incluyen:


• Los tipos de datos que debe contener la tabla.
• Las columnas de la tabla y los tipos de datos para cada columna (así como su longitud, si
es preciso).
• Qué columnas aceptan valores NULL.
• Si deben utilizarse (y cuándo) restricciones o valores predeterminados y reglas.
• Los tipos de índices necesarios, dónde se necesitan y qué columnas son claves
principales y claves externas.

La asignación de un tipo de datos para cada columna es uno de los primeros pasos que deberá
seguir para diseñar una tabla. Los tipos de datos definen qué valores están permitidos en cada
columna. Para asignar un tipo de datos a una columna, puede utilizar tipos de datos de Microsoft
SQL Server o crear sus propios tipos de datos a partir de los del sistema. Por ejemplo, si sólo
desea incluir nombres en una columna, puede asignar un tipo de datos de carácter para la misma.
Asimismo, si desea que una columna sólo contenga números, puede asignar un tipo de datos
numérico.

Exigir la integridad de los datos

Los tipos de datos del sistema y los definidos por el usuario pueden utilizarse para exigir la
integridad de los datos, ya que los datos que se agregan o que se modifican deben ajustarse al
tipo especificado en la instrucción original CREATE TABLE. Por ejemplo, no podrá almacenar un
nombre en una columna definida con un tipo de datos datetime, porque una columna datetime
sólo acepta fechas válidas. Por lo general, mantenga datos de tipo numérico en las columnas
numéricas, sobre todo si deben realizarse cálculos con ellos más adelante.

 Columnas de numeración automática y de identificadores

En una tabla sólo puede crearse una columna de identificadores que contenga valores
secuenciales generados por el sistema para identificar de forma única a cada fila de la tabla. Por
ejemplo, una columna de identificadores puede generar números únicos de recibos
personalizados de los clientes automáticamente para una aplicación, a medida que se insertan
filas en la tabla. Las columnas de identificadores contienen valores únicos dentro de la tabla en la

Material de estudio Página: 152 de 249


Visual Basic 6.0 y SQLServer 7.0

que son definidas. Esto significa que otras tablas que contengan columnas de identificadores
pueden tener los mismos valores de identidad que utiliza otra tabla. No obstante, esta
coincidencia no suele constituir un problema, ya que los valores de los identificadores suelen
utilizarse únicamente dentro del contexto de una tabla; las columnas de identificadores no están
relacionadas con las columnas de identificadores que se encuentren en otras tablas.

En cada tabla sólo se puede crear una columna de identificadores exclusivos globales; esta
columna contendrá valores únicos para todos los equipos del mundo que estén conectados por
red. Una columna que ofrezca la garantía de contener valores exclusivos globales suele resultar
de utilidad cuando es necesario mezclar datos similares de varios sistemas de bases de datos
(por ejemplo, en un sistema de facturación que se alimente de los datos de las distintas filiales de
una compañía repartidas por todo el mundo). Cuando se mezclan los datos en la sede central de
la compañía para su consolidación y con el fin de elaborar informes, la utilización de valores
exclusivos globales impide que coincidan los números de facturación o los identificadores de dos
clientes en países diferentes.

Microsoft® SQL Server™ utiliza columnas de identificadores exclusivos globales para la


duplicación de mezcla con el fin de garantizar que las filas tengan una identificación exclusiva en
distintas copias de la tabla.

SQL Server utiliza las propiedades IDENTITY y ROWGUIDCOL para implementar columnas de
identificadores.

 Utilizar restricciones, valores predeterminados y valores NULL

Para diseñar las tablas, es necesario identificar los valores válidos para una columna y decidir
cómo se debe exigir la integridad de los datos de la columna. Microsoft® SQL™ Server
proporciona varios mecanismos para exigir la integridad de los datos de una columna:

• Las restricciones de clave principal (PRIMARY KEY).


• Las restricciones de clave externa (FOREIGN KEY).
• Las restricciones de no duplicados (UNIQUE).
• Las restricciones de comprobación (CHECK).
• Las definiciones de valores predeterminados (DEFAULT).
• La aceptación de NULL

3.5.1 Restricciones PRIMARY KEY

Una restricción PRIMARY KEY única se puede:


• Crear cuando se crea la tabla, durante el proceso de definición de la misma.
• Agregar a una tabla existente, siempre que no exista ya otra restricción PRIMARY KEY
(una tabla sólo puede tener una restricción PRIMARY KEY).
• Modificar o eliminar, si ya existe. Por ejemplo, es posible que desee que la restricción
PRIMARY KEY de la tabla haga referencia a otras columnas o bien modificar el orden de
la columna, el nombre del índice, la opción de agrupamiento o el factor de relleno de la
restricción PRIMARY KEY. No se puede cambiar la longitud de una columna definida con
una restricción PRIMARY KEY.

Nota Para modificar una restricción PRIMARY KEY mediante Transact-SQL o SQL-DMO,
antes deberá eliminar la restricción PRIMARY KEY existente y, a continuación, volver a
crearla con la nueva definición.

Material de estudio Página: 153 de 249


Visual Basic 6.0 y SQLServer 7.0

Cuando se agrega una restricción PRIMARY KEY a una o a varias columnas de la tabla, Microsoft
SQL Server comprueba los datos que hay en las columnas para asegurarse de que sigan las
reglas de las claves principales:

• Que no haya ningún valor Null.


• Que no haya ningún valor duplicado.

Si se agrega una restricción PRIMARY KEY a una columna con valores duplicados o valores
NULL, SQL Server devuelve un error y no agrega la restricción. No se puede agregar una
restricción PRIMARY KEY que no cumpla estas reglas.

3.5.2 Restricciones FOREIGN KEY

Las restricciones FOREIGN KEY se pueden:


• Crear cuando se crea la tabla, durante el proceso de definición de la misma.
• Agregar a una tabla ya existente, siempre que la restricción FOREIGN KEY esté
vinculada a una restricción PRIMARY KEY o UNIQUE de otra o de la misma tabla. Una
tabla puede contener varias restricciones FOREIGN KEY.
• Modificar o eliminar si ya existen restricciones FOREIGN KEY. Por ejemplo, es posible
que desee que la restricción FOREIGN KEY de la tabla haga referencia a otras columnas.
No se puede cambiar la longitud de una columna definida con una restricción FOREIGN
KEY.

Nota Para modificar una restricción FOREIGN KEY mediante Transact-SQL o SQL-DMO,
antes deberá eliminar la restricción FOREIGN KEY existente y, a continuación, volver a
crearla con la nueva definición.

Cuando se agrega una restricción FOREIGN KEY a una o a varias columnas de la tabla,
Microsoft® SQL Server™ comprueba de forma predeterminada los datos que hay en las
columnas para asegurarse de que estén todos los valores, excepto NULL, en las columnas de la
restricción PRIMARY KEY o UNIQUE a la que se hace referencia. Sin embargo, se puede impedir
que SQL Server compruebe los datos de la columna con la nueva restricción y exigirle que
agregue la nueva restricción, independientemente de los datos que haya en la columna. Esta
opción resulta de utilidad cuando los datos existentes ya cumplen con la nueva restricción
FOREIGN KEY o cuando una regla de empresa requiere que se exija la restricción sólo a partir de
ese punto.

No obstante, debe actuar con precaución cuando agregue una restricción sin comprobar los datos
existentes porque así se omiten los controles de SQL Server que garantizan la integridad de los
datos de la tabla.

Deshabilitar restricciones FOREIGN KEY

Es posible deshabilitar las restricciones FOREIGN KEY existentes para:


• Las instrucciones INSERT y UPDATE, de modo que los datos de la tabla puedan ser
modificados sin ser validados por las restricciones. Deshabilite una restricción FOREIGN
KEY para las instrucciones INSERT y UPDATE si los nuevos datos infringen la restricción
o si la restricción sólo se aplica a los datos que ya se encuentran en la base de datos.

Material de estudio Página: 154 de 249


Visual Basic 6.0 y SQLServer 7.0

• Procesos de duplicación. Deshabilite una restricción FOREIGN KEY durante la


duplicación si la restricción es específica para la base de datos de origen. Cuando se
duplica una tabla, la definición de la tabla y los datos se copian desde la base de datos de
origen a una base de datos de destino. Estas dos bases de datos suelen encontrarse en
dos servidores distintos (aunque no necesariamente). Si las restricciones FOREIGN KEY
son específicas para la base de datos de origen pero no están deshabilitadas durante la
duplicación, puede que impidan innecesariamente que se escriban nuevos datos en la
base de datos de destino.

Elimine una restricción FOREIGN KEY para que no se exija la integridad referencial entre las
columnas de clave externa y las columnas de la clave principal (o de restricción UNIQUE)
relacionadas que se encuentran en otra tabla.

SQL Server crea automáticamente un índice único para exigir que la restricción PRIMARY KEY
sea única. Si aún no existe un índice agrupado en la tabla o no se ha especificado explícitamente,
se crea un índice agrupado único para exigir la restricción PRIMARY KEY.

Importante No se puede eliminar una restricción PRIMARY KEY si una restricción FOREIGN
KEY de otra tabla está haciendo referencia a ella; antes, es preciso eliminar la restricción
FOREIGN KEY.

3.5.3 Restricciones de no duplicados (UNIQUE)

Las restricciones UNIQUE se pueden:


• Crear cuando se crea la tabla, durante el proceso de definición de la misma.
• Agregar a una tabla existente, siempre que la columna o la combinación de columnas a
las que afecta la restricción UNIQUE sólo contenga valores exclusivos o NULL. Una tabla
puede contener varias restricciones UNIQUE.
• Modificar o eliminar si ya existen. Por ejemplo, es posible que desee que la restricción
UNIQUE de la tabla haga referencia a otras columnas o que desee cambiar el tipo de
agrupación de los índices.

Nota Para modificar una restricción UNIQUE mediante Transact-SQL o SQL-DMO, antes
deberá eliminar la restricción UNIQUE existente y, a continuación, volver a crearla con la
nueva definición.

Cuando se agrega una restricción UNIQUE a una o a varias columnas de una tabla, Microsoft®
SQL Server™ comprueba de forma predeterminada los datos que hay en las columnas para
asegurarse de que todos los valores, excepto los valores NULL, sean únicos. Si se agrega una
restricción UNIQUE a una columna que contiene valores duplicados, SQL Server devuelve un
error y no agrega la restricción.

SQL Server crea automáticamente un índice UNIQUE para exigir, de acuerdo con la restricción
UNIQUE, que no haya duplicados. Por lo tanto, si se intenta insertar una fila duplicada, SQL
Server devolverá un mensaje de error para indicar que se ha infringido la restricción UNIQUE y no
agregará la fila a la tabla. A menos que se especifique explícitamente un índice agrupado, se
creará de forma predeterminada un índice único, no agrupado, para exigir la restricción UNIQUE.

Elimine una restricción UNIQUE para anular el requisito de que sean únicos los valores de una
columna o de una combinación de columnas incluida en la restricción. No es posible eliminar una
restricción UNIQUE si la columna asociada se utiliza como clave de texto de la tabla.

Material de estudio Página: 155 de 249


Visual Basic 6.0 y SQLServer 7.0

3.5.4 Restricciones CHECK

Las restricciones CHECK se pueden:


• Crear cuando se crea la tabla, durante el proceso de definición de la misma.
• Agregar a una tabla ya existente. Las tablas y las columnas pueden contener varias
restricciones CHECK.
• Modificar o eliminar si ya existen. Por ejemplo, puede modificar la expresión utilizada por
la restricción CHECK en una columna de la tabla.

Nota Para modificar una restricción CHECK mediante Transact-SQL o SQL-DMO, antes
deberá eliminar la restricción CHECK existente y, a continuación, volver a crearla con la
nueva definición.

Cuando se agrega una restricción CHECK a una tabla ya existente, puede aplicarse a los nuevos
datos o bien ampliarse también a los datos ya existentes. De forma predeterminada, la restricción
CHECK se aplica a los datos existentes y a los nuevos datos. Puede resultar útil aplicar la
restricción sólo a los datos nuevos cuando los datos existentes ya cumplen la nueva restricción
CHECK o cuando una regla de empresa requiere que se exija la restricción únicamente a partir de
ahora.

Por ejemplo, una restricción anterior podía requerir que los códigos postales estuvieran limitados
a cinco cifras, mientras que una nueva restricción requiere que los códigos postales sean de
nueve cifras. Los datos que figuran en los antiguos códigos postales de cinco cifras siguen siendo
válidos y coexisten con los nuevos datos de los nuevos códigos postales, que tienen nueve cifras.
Por lo tanto, la nueva restricción sólo debe comprobarse con los nuevos datos.

No obstante, conviene actuar con precaución cuando se agrega una restricción sin comprobar los
datos existentes ya que, de ese modo, se omiten los controles de Microsoft® SQL Server™ que
exigen las reglas de integridad para la tabla.

Deshabilitar restricciones CHECK


Se puede deshabilitar las restricciones CHECK para:
• Las instrucciones INSERT y UPDATE, de modo que los datos de la tabla puedan ser
modificados sin ser validados por las restricciones. Deshabilite una restricción CHECK
durante las instrucciones INSERT y UPDATE si los nuevos datos no cumplen la
restricción o si la restricción debe aplicarse únicamente a los datos que ya se encuentren
en la base de datos.
• Procesos de duplicación. Deshabilite una restricción CHECK durante la duplicación si la
restricción es específica para la base de datos de origen. Cuando se duplica una tabla, la
definición de la tabla y los datos se copian desde la base de datos de origen a una base
de datos de destino. Estas dos bases de datos suelen encontrarse en dos servidores
distintos (aunque no necesariamente). Si las restricciones CHECK específicas para la
base de datos de origen no están deshabilitadas, puede que impidan innecesariamente
que se escriban datos nuevos en la base de datos de destino.

Elimine una restricción CHECK para quitar las limitaciones acerca de los valores aceptables para
las columnas incluidas en la expresión de la restricción.

Material de estudio Página: 156 de 249


Visual Basic 6.0 y SQLServer 7.0

3.5.5 Dfiniciones DEFAULT

Las definiciones DEFAULT se pueden:


• Crear cuando se crea la tabla, durante el proceso de definición de la misma.
• Agregar a una tabla ya existente. Cada columna de una tabla puede contener una sola
definición DEFAULT.
• Modificar o eliminar, si ya existen definiciones DEFAULT. Por ejemplo, puede modificar el
valor que se inserta en una columna cuando no se escribe ningún valor.

Nota Para modificar una definición DEFAULT mediante Transact-SQL o SQL-DMO, antes deberá
eliminar la definición DEFAULT existente y, a continuación, volver a crearla con la nueva
definición.

No se puede crear definiciones DEFAULT para columnas definidas con:


• Un tipo de datos timestamp.
• Una propiedad IDENTITY o ROWGUIDCOL.
• Una definición DEFAULT o un objeto DEFAULT ya existentes.

Nota El valor predeterminado debe ser compatible con el tipo de datos de la columna a la que se
aplica la definición DEFAULT. Por ejemplo, el valor predeterminado para una columna int debe
ser un número entero, no una cadena de caracteres.

Cuando se agrega una definición DEFAULT a una columna ya existente en una tabla, Microsoft®
SQL Server™ aplica de forma predeterminada el nuevo valor predeterminado a las nuevas filas
de datos que se agregan a la tabla; los datos existentes que se hayan insertados mediante la
definición DEFAULT anterior no se ven afectados. No obstante, cuando agregue una nueva
columna a una tabla ya existente, puede especificar que SQL Server inserte en la nueva columna
el valor predeterminado (especificado mediante la definición DEFAULT) en vez de un valor Null
para las filas existentes en la tabla.

Cuando elimine una definición DEFAULT, SQL Server insertará un valor Null en vez del valor
predeterminado si no se inserta ningún valor para las nuevas filas de la columna. No obstante, no
se realizan cambios en los datos existentes en la tabla.

3.5.6 Columnas de identificadores

En cada tabla sólo se puede crear una columna de identificadores y una columna de
identificadores exclusivos globales.

Propiedad de identidad (IDENTITY)


Se puede implementar las columnas de identificadores mediante la propiedad de identidad, que
permite que el programador de la aplicación especifique un número de identidad para la primera
fila insertada en la tabla (propiedad inicialización de identidad (identity seed)) y un incremento
(incremento de identidad (identity increment)) que debe agregarse al valor inicial para
determinar los números de identidad sucesivos. Cuando se insertan valores en una tabla con una
columna de identificadores, Microsoft® SQL Server™ genera automáticamente el siguiente valor
de identidad mediante la suma del incremento a la inicialización.

Cuando utilice la propiedad IDENTITY para definir una columna de identificadores, tenga en
cuenta lo siguiente:

Material de estudio Página: 157 de 249


Visual Basic 6.0 y SQLServer 7.0

• Una tabla sólo puede tener una columna definida con la propiedad IDENTITY y esa
columna sólo se puede definir con los tipos de datos decimal, int, numeric, smallint o
tinyint.
• Se pueden especificar los valores de inicialización e incremento. El valor predeterminado
es 1 para ambos.
• La columna de identificadores no debe aceptar valores NULL ni contener una definición ni
un objeto DEFAULT.
• Es posible hacer referencia a la columna desde una lista de selección mediante la palabra
clave IDENTITYCOL después de que se configure la propiedad IDENTITY.
• Es posible utilizar la función OBJECTPROPERTY para determinar si una tabla tiene una
columna IDENTITY, y la función COLUMNPROPERTY para determinar el nombre de la
columna IDENTITY.

Identificadores exclusivos globales


Aunque la propiedad de identidad (IDENTITY) automatice la numeración de las filas de una tabla,
dos tablas distintas con sendas columnas de identificadores pueden generar los mismos valores.
Esto es debido a que se garantiza que la propiedad de identidad IDENTITY es única sólo para la
tabla en la que se utiliza. Si una aplicación debe generar una columna de identificadores única
para toda la base de datos o para todas las bases de datos de todos los equipos conectados en
red en todo el mundo, utilice la propiedad ROWGUIDCOL, el tipo de datos uniqueidentifier y la
función NEWID.

Cuando utilice la propiedad ROWGUIDCOL para definir una columna de identificadores


exclusivos globales, tenga en cuenta lo siguiente:

• Una tabla sólo podrá tener una columna ROWGUIDCOL, y esa columna debe definirse
mediante el tipo de datos uniqueidentifier.
• SQL Server no genera valores para la columna de forma automática. Para insertar un
valor exclusivo global, cree una definición DEFAULT en la columna que utilice la función
NEWID para generar un valor exclusivo global.
• Es posible hacer referencia a la columna desde una lista de selección mediante la palabra
clave ROWGUIDCOL, después de que se establezca la propiedad ROWGUIDCOL. Este
método es similar al que permite hacer referencia a una columna de identidad (IDENTITY)
mediante la palabra clave IDENTITYCOL.
• Se puede utilizar la función OBJECTPROPERTY para determinar si una tabla tiene una
columna ROWGUIDCOL y la función COLUMNPROPERTY para determinar el nombre de
la columna ROWGUIDCOL.
• Dado que la propiedad ROWGUIDCOL no exige la exclusividad, deberá utilizar la
restricción de exclusividad (UNIQUE) para asegurarse de que se insertan valores
exclusivos en la columna ROWGUIDCOL.

Nota Si hay una columna de identificadores para una tabla en la que se realizan eliminaciones
frecuentemente, pueden quedar espacios entre los valores de identidad; los valores de identidad
eliminados no se vuelven a utilizar. Para evitar esos espacios, no utilice la propiedad IDENTITY.
En su lugar, cree un desencadenador que, a medida que se inserten filas, determine un nuevo
valor de identificador basado en los valores existentes de la columna de identificadores.

3.5.7 SET ANSI_NULLS (T-SQL)

Especifica el comportamiento conforme a SQL-92 de los operadores de comparación Igual a (=) y


Diferente de (<>) cuando se utilizan con valores nulos.

Material de estudio Página: 158 de 249


Visual Basic 6.0 y SQLServer 7.0

Sintaxis
SET ANSI_NULLS {ON | OFF}
Observaciones

El estándar SQL-92 requiere que las comparaciones de igualdad (=) o desigualdad (<>) con un
valor nulo se evalúen como FALSE. Cuando SET ANSI_NULLS es ON, una instrucción SELECT
con la cláusula WHERE nombreColumna = NULL devolverá cero filas, incluso cuando haya
valores nulos en nombreColumna. Una instrucción SELECT con la cláusula WHERE
nombreColumna <> NULL devolverá cero filas, incluso cuando haya valores no nulos en
nombreColumna.
Cuando SET ANSI_NULLS es OFF, los operadores de comparación Igual a (=) y Diferente de
(<>) no siguen el estándar de SQL-92. Una instrucción SELECT con la cláusula WHERE
nombreColumna = NULL devolverá las filas que tengan valores nulos en nombreColumna. Una
instrucción SELECT con la cláusula WHERE nombreColumna <> NULL devolverá las filas con
valores no nulos en esa columna.

Nota El hecho de que Microsoft® SQL Server™ interprete una cadena vacía como un carácter
espacio o como una auténtica cadena vacía se controla con la opción de nivel de compatibilidad
de sp_dbcmptlevel. Si el nivel de compatibilidad es menor o igual que 65, SQL Server interpreta
las cadenas vacías como espacios individuales. Si el nivel de compatibilidad es igual a 70, SQL
Server interpreta las cadenas vacías como tales.

Cuando SET ANSI_NULLS es ON, todas las comparaciones con un valor nulo se evalúan como
UNKNOWN. Cuando SET ANSI_NULLS es OFF, la comparación de cualquier dato con un valor
nulo se evalúa como TRUE si el valor del dato es NULL. Si no se especifica, se aplica el valor de
la opción ANSI nulls de la base de datos actual..

Para que una secuencia de comandos funcione como se pretende, independientemente de la


opción de base de datos ANSI nulls o de la opción SET ANSI_NULLS, utilice IS NULL e IS NOT
NULL en las comparaciones que puedan contener valores nulos.

En los procedimientos almacenados, SQL Server utiliza el valor de la opción SET ANSI_NULLS
establecido en el momento de crear el procedimiento almacenado. En las siguientes ejecuciones
del procedimiento almacenado, se restablece y se aplica la opción SET ANSI_NULLS original.
Cuando se invoca dentro de un procedimiento almacenado, la opción SET ANSI_NULLS no
cambia.

SET ANSI_NULLS debe estar activado para ejecutar consultas distribuidas.

El controlador ODBC de SQL Server y el proveedor de Microsoft OLE DB para SQL Server
establecen automáticamente ANSI_NULLS en ON al conectar. Esta opción se puede configurar
en los orígenes de datos ODBC, en los atributos de conexión ODBC o en las propiedades de
conexión OLE DB establecidas en la aplicación antes de conectar con SQL Server. SET
ANSI_NULLS tiene como opción predeterminada OFF en las conexiones desde aplicaciones de
biblioteca de base de datos.

Cuando SET ANSI_DEFAULTS es ON, se habilita SET ANSI_NULLS.

La opción SET ANSI_NULLS se establece en tiempo de ejecución, no en tiempo de análisis.

Permisos
De forma predeterminada, todos los usuarios tienen permisos para ejecutar SET ANSI_NULLS.

Material de estudio Página: 159 de 249


Visual Basic 6.0 y SQLServer 7.0

Por ejemplo

-- El primer proceso por lotes devolverá 2 filas

use pubs
set ansi_nulls off
go
select * from titles where price = null
go

--El segundo proceso por lotes no devolverá ninguna fila

/* Este secuencia de instrucciones ilustra la utilización de ANSI_NULLS


*/
use pubs
set ansi_nulls on
go
select * from titles where price = null
go

3.5.8 EJEMPLOS

1. Esta secuencia de instrucciones crea dos tablas con una relación compuesta. Clave
primaria/Clave externa. Después presenta las restricciones sobre cada tabla.

CREATE TABLE cliente


(
id_cliente int NOT NULL,
num_ubicación smallint NULL,
nombre_cliente varchar(50) NOT NULL,
CONSTRAINT CLIENTE_EXC UNIQUE CLUSTERED (num_ubicación, id_cliente)
)

CREATE TABLE pedidos


(
id_pedido int NOT NULL IDENTITY CONSTRAINT PEDIDO_PK
PRIMARY KEY NONCLUSTERED,
num_cliente int NOT NULL,
ubic_cliente smallint NULL,
CONSTRAINT FK_PEDIDO_CLIENTE FOREIGN KEY (ubic_cliente, num_cliente)
REFERENCES cliente (num_ubicación, id_cliente)
)

GO

EXEC sp_helpconstraint cliente


EXEC sp_helpconstraint pedidos
GO

2.- Esta secuencia de instrucciones crea una tabla con varias restricciones y una clave externa
que hace referencia a sí misma. Después muestra las restricciones sobre la tabla.

Material de estudio Página: 160 de 249


Visual Basic 6.0 y SQLServer 7.0

USE pubs
GO

CREATE TABLE empleado


(
id_empleado int NOT NULL PRIMARY KEY
CHECK (id_empleado BETWEEN 0 AND 1000),

nombre_empleado varchar(30) NOT NULL CONSTRAINT sin_números


CHECK (nombre_empleado NOT LIKE '%[0-9]%'),

id_admin int NOT NULL REFERENCES empleado(id_empleado),

fecha_introducción datetime NULL CHECK (fecha_introducción >=


GETDATE()),

introducido_por int CHECK (introducido_por IS NOT NULL),


CONSTRAINT introducido_por_valido CHECK
(introducido_por = SUSER_ID(NULL) AND
introducido_por <> id_empleado),

CONSTRAINT admin_valido CHECK (id_admin <> id_empleado OR id_empleado=1),

CONSTRAINT fin_de_mes CHECK (DATEPART(DAY, GETDATE()) < 28)


)
GO

EXEC sp_helpconstraint empleado


GO

4.- Esta secuencia de instrucciones crea una tabla con varias restriccione, algunos valores
predeterminados y una clave externa de referencia a sí misma. Después muestra las restricciones
sobre la tabla.

USE pubs
GO

CREATE TABLE empleado


(
id_empleado int NOT NULL PRIMARY KEY
CHECK (id_empleado BETWEEN 0 AND 1000),

nombre_empleado varchar(30) NOT NULL CONSTRAINT sin_números


CHECK (nombre_empleado NOT LIKE '%[0-9]%'),

id_admin int NOT NULL REFERENCES empleado(id_empleado),

fecha_introducción datetime NULL CHECK (fecha_introducción >=


CURRENT_TIMESTAMP),

introducido_por int CHECK (introducido_por IS NOT NULL),


CONSTRAINT introducido_por_válido CHECK
(introducido_por = SUSER_ID(NULL) AND
introducido_por <> id_empleado),

Material de estudio Página: 161 de 249


Visual Basic 6.0 y SQLServer 7.0

CONSTRAINT admin_válido CHECK (id_admin <> id_empleado OR id_empleado=1),

CONSTRAINT fin_de_mes CHECK (DATEPART(DAY, GETDATE()) < 28)


)
GO

EXEC sp_helpconstraint empleado


GO

5.- Esta secuencia de instrucciones decodifica la información de la tabla sysconstraints para


presentar información sobre las restricciones de una tabla.

USE ejemplo
GO

SELECT
OBJECT_NAME(constid) 'Nombre de la restricción',
constid 'ID de la restricción',
CASE (status & 0xF)
WHEN 1 THEN 'Clave primaria'
WHEN 2 THEN 'Exclusiva'
WHEN 3 THEN 'Clave externa'
WHEN 4 THEN 'Comprobación'
WHEN 5 THEN 'Predeterminado'
ELSE 'No definido'
END 'Tipo de restricción',
CASE (status & 0x30)
WHEN 0x10 THEN 'Columna'
WHEN 0x20 THEN 'Tabla'
ELSE 'ND'
END 'Nivel'
FROM sysconstraints
WHERE id=OBJECT_ID('tEmpleado')

6.- Esta secuencia de instrucciones crea una tabla con varias restricciones y una clave externa
que hace referencia a sí misma. Después muestra las restricciones sobre la tabla.

USE pubs
GO

CREATE TABLE empleado


(
id_empleado int NOT NULL PRIMARY KEY
CHECK (id_empleado BETWEEN 0 AND 1000),

nombre_empleado varchar(30) NOT NULL CONSTRAINT sin_números


CHECK (nombre_empleado NOT LIKE '%[0-9]%'),

id_admin int NOT NULL REFERENCES empleado(id_empleado),

fecha_introducción datetime NULL CHECK (fecha_introducción >=


CURRENT_TIMESTAMP),

introducido_por int CHECK (introducido_por IS NOT NULL),

Material de estudio Página: 162 de 249


Visual Basic 6.0 y SQLServer 7.0

CONSTRAINT introducido_por_válido CHECK


(introducido_por = SUSER_ID(NULL) AND
introducido_por <> id_empleado),

CONSTRAINT admin_válido CHECK (id_admin <> id_empleado OR id_empleado=1),

CONSTRAINT fin_de_mes CHECK (DATEPART(DAY, GETDATE()) < 28)


)
GO

EXEC sp_helpconstraint empleado


GO

7.- La siguientes instrucciones ejemplifican el uso de transacciones.

USE Ejemplo
go

if exists (select * from sysobjects where name='SHOW_ERROR' and type='U')


DROP TABLE SHOW_ERROR
go

CREATE TABLE SHOW_ERROR


(
col1 smallint NOT NULL PRIMARY KEY,
col2 smallint NOT NULL
)
go

BEGIN TRANSACTION

INSERT SHOW_ERROR VALUES (1,1)


INSERT SHOW_ERROR VALUES (1,2)
INSERT SHOW_ERROR VALUES (2,2)

COMMIT TRANSACTION
go

SELECT * FROM SHOW_ERROR


go

/*
Servidor: mensaje 2627, nivel 14, estado 1, línea 1
Infracción de la restricción PRIMARY KEY 'PK__mostrar_error__5DCAEF64'. No se puede
insertar una clave -----duplicada en el objeto 'mostrar_error'.
Se terminó la instrucción.

col1 col2
---- ----
1 1
2 2

A continuación se presenta una versión modificada de la transacción que acabamos de ver. Este
ejemplo realiza

Material de estudio Página: 163 de 249


Visual Basic 6.0 y SQLServer 7.0

una comprobación sencilla de errores utilizando la función del sistema incorporada @@error, y
anula la transacción, si cualuqiera de las instrucciones tiene como resultado un error.

En este ejemplo no se insertan filas.

*/

if exists (select * from sysobjects where name='SHOW_ERROR' and type='U')


DROP TABLE SHOW_ERROR
go

CREATE TABLE SHOW_ERROR


(
col1 smallint NOT NULL PRIMARY KEY,
col2 smallint NOT NULL
)
go

BEGIN TRANSACTION
INSERT SHOW_ERROR VALUES (1,1)
if @@error <> 0 GOTO TRAN_ABORT
INSERT SHOW_ERROR VALUES (1,2)
if @@error <> 0 GOTO TRAN_ABORT
INSERT SHOW_ERROR VALUES (2,2)
if @@error <> 0 GOTO TRAN_ABORT
COMMIT TRANSACTION
-- GOTO ENDIT

TRAN_ABORT:
ROLLBACK TRANSACTION

ENDIT:
go

SELECT * FROM SHOW_ERROR


go

/* Como algunas personas manejan los errores en las transacciones mal, y como puede ser
tedioso añadir comprobaciones de error después de cada comando, la versión 6.5 añadió una
nueva instrucción SET que cancela una transacción si se produce cualquier error durante la
misma (no existe instrucción WHENEVER en Transact-SQL actualmente, aunque dicha
característica resultaría muy útil para situaciones como ésta).

La utilización de SET XACT_ABORT ON hace que se cancele y se anule toda la transacción si


se produce un error.

El valor predereminado de esta opción es OFF, que es coherente con la semántica anterior a la
versión 6.5, además de con el comportamiento del estándar ANSI. Activando la opción
XACT_ABORT ON, ahora podemos volver a ejecutar el ejemplo y ver que no se han insertado
filas.

*/
if exists (select * from sysobjects where name='SHOW_ERROR' and type='U')
DROP TABLE SHOW_ERROR
go

Material de estudio Página: 164 de 249


Visual Basic 6.0 y SQLServer 7.0

CREATE TABLE SHOW_ERROR


(
col1 smallint NOT NULL PRIMARY KEY,
col2 smallint NOT NULL
)
go

SET XACT_ABORT ON
BEGIN TRANSACTION

INSERT SHOW_ERROR VALUES (1,1)


INSERT SHOW_ERROR VALUES (1,2)
INSERT SHOW_ERROR VALUES (2,2)

COMMIT TRANSACTION
go

SET XACT_ABORT OFF


SELECT * FROM SHOW_ERROR
go

Material de estudio Página: 165 de 249


Visual Basic 6.0 y SQLServer 7.0

3.6 Elementos de sintaxis de Transact-SQL

Transact-SQL tiene varios elementos de sintaxis que son utilizados por, o influyen en, la mayor
parte de las instrucciones:
Identificadores : Son los nombres de objetos como, por ejemplo, tablas, vistas, columnas,
bases de datos y servidores.
Tipos de datos : Definen el tipo de datos que los objetos de datos pueden contener como,
por ejemplo, columnas, variables y parámetros. La mayor parte de las instrucciones de
Transact-SQL no hacen referencia explícitamente a tipos de datos, sino que sus resultados
están influidos por las interacciones entre los tipos de datos de los objetos a los que se
hace referencia en la instrucción.
Funciones : Son elementos de sintaxis que toman cero, uno o más valores de entrada y
devuelven un valor escalar o un conjunto de valores en forma de tabla. Ejemplos de
funciones son la función SUM para sumar varios valores, la función DATEDIFF para
determinar el número de unidades de tiempo que separan dos fechas, la función
@@SERVERNAME para obtener el nombre del servidor que ejecuta SQL Server o la
función OPENQUERY para ejecutar una instrucción SQL en un servidor remoto y
recuperar el conjunto de resultados.
Expresiones : Son una unidad de sintaxis que Microsoft SQL Server puede resolver en
un valor único. Ejemplos de expresiones son las constantes, las funciones que devuelven
un valor único, una referencia a una columna o una variable.
Operadores : Funcionan con una o más expresiones individuales para formar una
expresión más compleja. Por ejemplo, combinar el operador - (negativo) con la constante
12 da como resultado la constante -12. El operador * (multiplicación) de la expresión
PrecioColumna *1.1 aumenta el precio en un 10 por ciento.
Comentarios: Son fragmentos de texto insertado en instrucciones o secuencias de
comandos de Transact-SQL para explicar el objetivo de la instrucción. Los comentarios no
son ejecutados por SQL Server.
Palabras clave reservadas : Son palabras reservadas que utiliza SQL Server y no deben
emplearse como nombres de objetos de una base de datos.

1.5.1 Conversión de tipos de datos

En Transact-SQL, hay dos niveles posibles de conversión de tipos de datos:


• Cuando los datos de un objeto se mueven a, se comparan o se combinan con los datos
de otro objeto, puede que sea necesario convertir los datos desde el tipo de datos de un
objeto al tipo de datos del otro.
• Cuando los datos de una columna de resultados, un código devuelto o un parámetro de
salida de Transact-SQL se mueven a una variable de programa, deben ser convertidos
desde el tipo de datos de Microsoft SQL Server al tipo de datos de la variable.

Hay dos categorías de conversiones de tipo de datos:

Material de estudio Página: 166 de 249


Visual Basic 6.0 y SQLServer 7.0

• Las conversiones implícitas son transparentes para el usuario.


SQL Server convierte automáticamente los datos desde un tipo de datos al otro. Por
ejemplo, si un smallint se compara con un int, el smallint se convierte implícitamente a
int antes de realizarse la comparación.
• Las conversiones explícitas las realiza el usuario mediante las funciones CAST o
CONVERT.
Las funciones CAST y CONVERT convierten un valor (una variable local, una columna u otra
expresión) de un tipo de datos a otro. Por ejemplo, la siguiente función CAST convierte el valor
numérico $157.27 a una cadena de caracteres ‘$157.27’:
CAST ( $157.27 AS VARCHAR(10) )
CAST se basa en el estándar SQL-92 y se prefiere antes que CONVERT.
Cuando se realizan conversiones desde el tipo de datos de un objeto SQL Server a otro, no se
admiten algunas conversiones implícitas y explícitas de tipos de datos. Por ejemplo, un valor
nchar no se puede convertir de ninguna forma a un valor image. Un nchar sólo se puede
convertir a binary con una conversión explícita, mientras que la conversión implícita a binary no
se admite. Un nchar puede ser convertido a nvarchar explícita o implícitamente..

Cuando se realiza una conversión entre una variable de aplicación y una columna de conjunto de
resultados, código de retorno, parámetro o marcador de parámetro de SQL Server, la API de base
de datos define cuáles son las conversiones de tipos de datos admitidas.

Uso de CAST: CAST(expresión AS tipoDatos)


Uso de CONVERT: CONVERT (tipoDatos[(longitud)], expresión [, estilo])
Argumentos

expresión : Es cualquier expresión válida de Microsoft SQL Server.


TipoDatos: Es el tipo de datos destino proporcionado por el sistema. No se pueden utilizar
tipos de datos definidos por el usuario.
longitud : Es un parámetro opcional de los tipos de datos nchar, nvarchar, char,
varchar, binary o varbinary.
Estilo : Es el estilo del formato de fecha que se desea al convertir datos datetime o
smalldatetime a datos de cadenas de caracteres (tipos de datos nchar,
nvarchar, char, varchar, nchar o nvarchar), o el formato de cadena cuando
se convierten datos float, real, money o smallmoney a datos de cadenas de
caracteres (tipos de datos nchar, nvarchar, char, varchar, nchar o
nvarchar).

Material de estudio Página: 167 de 249


Visual Basic 6.0 y SQLServer 7.0

En la siguiente tabla, las dos columnas de la izquierda representan los valores de estilo
para la conversión de datetime o smalldatetime en cadenas de caracteres. Agregue 100 al
valor de estilo para obtener el año con cuatro cifras, incluido el siglo (yyyy).
Sin el siglo Con el siglo
Estándar Entrada/Salida**
(yy) (yyyy)
- 0 o 100 (*) Predeterminado mon dd yyyy hh:miAM (o PM)
1 101 EE.UU. mm/dd/yy
2 102 ANSI yy.mm.dd
3 103 Británico/Francés dd/mm/yy
4 104 Alemán dd.mm.yy
5 105 Italiano dd-mm-yy
6 106 - dd mon yy
7 107 - mon dd, yy
8 108 - hh:mm:ss
Predeterminado +
- 9 o 109 (*) mon dd yyyy hh:mi:ss:mmmAM (o PM)
milisegundos
10 110 EE.UU. mm-dd-yy
11 111 JAPÓN yy/mm/dd
12 112 ISO yymmdd
Europeo predeterminado +
- 13 o 113 (*) dd mon yyyy hh:mm:ss:mmm(24h)
milisegundos
14 114 - hh:mi:ss:mmm(24h)
- 20 o 120 (*) ODBC canónico yyyy-mm-dd hh:mi:ss(24h)
ODBC canónico (con
- 21 o 121 (*) yyyy-mm-dd hh:mi:ss.mmm(24h)
milisegundos)
* Los valores predeterminados (estilo 0 o 100, 9 o 109, 13 o 113, 20 o 120, y 21 o 121) siempre
devuelven el siglo (yyyy).
** Entrada cuando se convierte a datetime; Salida cuando se convierte a cadenas de caracteres.

Importante: De forma predeterminada, SQL Server interpreta los años de dos cifras
con el año 2049 como límite. Es decir, el año 49 se interpreta como 2049 y el año 50
se interpreta como 1950. Muchas aplicaciones de cliente, como las basadas en objetos
de Automatización OLE, utilizan como año límite el año 2030. SQL Server
proporciona una opción de configuración (two digit year cutoff o reducción del año a
dos dígitos) que cambia el año límite en SQL Server y permite el tratamiento
coherente de las fechas. Sin embargo, el método más seguro es especificar los años
con cuatro cifras.

Cuando se convierte a datos de cadenas de caracteres desde smalldatetime, los estilos


que incluyen segundos o milisegundos muestran ceros en dichas posiciones. Puede
recortar las partes de la fecha que no desee cuando convierta valores datetime o
smalldatetime si utiliza la longitud apropiada en el tipo de datos char o varchar.

Material de estudio Página: 168 de 249


Visual Basic 6.0 y SQLServer 7.0

Esta tabla muestra los valores de estilo para la conversión de float o real a datos de
cadenas de caracteres.
Valor Salida
0 (predeterminado) 6 cifras como máximo. Utiliza la notación científica cuando es apropiado.
1 Siempre 8 cifras. Utiliza siempre la notación científica.
2 Siempre 16 cifras. Utiliza siempre la notación científica.
En la siguiente tabla, la columna de la izquierda representa el valor de estilo para la
conversión de money o smallmoney a datos de cadenas de caracteres.
Valor Salida
Sin separadores de millar cada tres cifras a la izquierda del separador decimal
0 (predeterminado)
y dos cifras a la derecha del separador decimal; por ejemplo, 4235,98.
Separadores de millar cada tres cifras a la izquierda del separador decimal y
1
dos cifras a la derecha del separador decimal; por ejemplo, 3.510,92.
Sin separadores de millar cada tres cifras a la izquierda del separador decimal
2
y cuatro cifras a la derecha del separador decimal; por ejemplo, 4235,9819.
Tipos devueltos
Devuelve el mismo valor que el tipo de datos 0.
Observaciones
Las conversiones implícitas son aquellas conversiones que ocurren sin especificar las funciones
CAST o CONVERT. Las conversiones explícitas son aquellas conversiones que requieren que se
especifique la función CAST (CONVERT). Este gráfico muestra todas las conversiones de tipos
de datos explícitas e implícitas permitidas entre los tipos de datos del sistema de SQL Server.

¡Error! Marcador no definido.Nota Como los datos Unicode siempre utilizan un número par de
bytes, preste atención al convertir binary o varbinary a 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)

No se acepta la conversión automática de tipos de datos para los tipos de datos text e image.
Puede convertir explícitamente datos text en cadenas de caracteres y datos image en binary o
varbinary, pero la máxima longitud que puede especificar es 8000. Si intenta una conversión
imposible (por ejemplo, si convierte una expresión de cadena de caracteres que incluya letras a
int), SQL Server genera un mensaje de error.
Al convertir expresiones de caracteres o binarias (char, nchar, nvarchar, varchar, binary o
varbinary) en una expresión de un tipo de datos diferente, los datos pueden quedar recortados,
se pueden presentar parcialmente o se puede devolver un error porque el resultado sea
demasiado corto para ser presentado. Las conversiones a char, varchar, nchar, nvarchar,
binary y varbinary se recortan, excepto en las conversiones que se muestran en esta tabla.

Del tipo de datos Al tipo de datos Resultado


int, smallint o tinyint char *
varchar *
nchar E
nvarchar E
money, smallmoney, numeric,
decimal, float o real
char E
varchar E
nchar E

Material de estudio Página: 169 de 249


Visual Basic 6.0 y SQLServer 7.0

nvarchar E
* Resultado con longitud demasiado corta para ser presentada.
E Error devuelto porque la longitud del resultado es demasiado corta para ser
presentada.

Microsoft SQL Server garantiza que sólo las conversiones circulares, las conversiones que
convierten un tipo de datos en otro y después vuelven a convertirlo al tipo de datos original,
devolverán los mismos valores de versión a versión. Este ejemplo muestra una conversión
circular:

DECLARE @myval decimal (5, 2)


SET @myval = 193.57
SELECT CAST(CAST(@myval AS varbinary(20)) AS decimal(10,5))
-- Or, using CONVERT
SELECT CONVERT(decimal(10,5), CONVERT(varbinary(20), @myval))

No intente generar, por ejemplo, valores binary y convertirlos a un tipo de datos de la categoría
de tipos de datos numéricos. SQL Server no garantiza que el resultado de una conversión de
tipos de datos decimal o numeric a binary sea igual entre distintas versiones de SQL Server.
Cuando se convierten tipos de datos que tienen un número diferente de posiciones decimales, el
valor queda recortado hasta la cifra de mayor precisión. Por ejemplo, el resultado de SELECT
CAST(10,6496 AS int) es 10.
Este ejemplo muestra una expresión resultante demasiado corta para ser presentada.
USE pubs
SELECT SUBSTRING(title, 1, 25) AS Title, CAST(ytd_sales AS char(2))
FROM titles
WHERE type = 'trad_cook'

Éste es el conjunto de resultados:


Title
------------------------- --
Onions, Leeks, and Garlic *
Fifty Years in Buckingham *
Sushi, Anyone? *
(3 row(s) affected)

Cuando se convierten tipos de datos en los que el tipo de datos destino tiene menos posiciones
decimales que el tipo de datos origen, el valor se redondea. Por ejemplo, el resultado de
CAST(10,3496 AS money) es $10,35.
SQL Server devuelve un mensaje de error cuando se convierten datos char, nchar, varchar o
nvarchar a int, float, numeric o decimal; o cuando una cadena vacía (“ “) se convierte a int o
float.
Usar datos de cadenas Binary
Cuando se convierten datos binary o varbinary a datos de cadena de caracteres y se especifica
un número impar de valores a continuación de la x, SQL Server agrega un 0 (cero) después de la
x para tener un número par de valores.
Los datos binarios consisten en los caracteres 0 a 9 y A a F (o f), en grupos de dos caracteres
cada uno. Las cadenas binarias tienen que estar precedidas por 0x. Por ejemplo, para
representar FF, escriba 0xFF. El valor máximo es un valor binario de 8000 bytes, todos ellos
establecidos con FF. Los tipos de datos binary no son para datos hexadecimales, sino para
patrones de bits. Puede que las conversiones y cálculos de números hexadecimales
almacenados como datos binarios no sean confiables.
Cuando se especifica la longitud de un tipo de datos binary, cada dos caracteres cuentan como
uno. La longitud de 10 significa que hay 10 grupos de dos caracteres.
Las cadenas binarias vacías, representadas como 0x, se pueden almacenar como datos binarios.

Material de estudio Página: 170 de 249


Visual Basic 6.0 y SQLServer 7.0

Ejemplos

A. Utilizar CAST y CONVERT


Los dos ejemplos devuelven los títulos de aquellos libros que tienen un 3 en la primera cifra de las
ventas anuales y convierten ytd_sales a char(20).
-- Use CAST.
USE pubs
GO
SELECT SUBSTRING(title, 1, 30) AS Title, ytd_sales
FROM titles
WHERE CAST(ytd_sales AS char(20)) LIKE '3%'
GO
-- Use CONVERT.
USE pubs
GO
SELECT SUBSTRING(title, 1, 30) AS Title, ytd_sales
FROM titles
WHERE CONVERT(char(20), ytd_sales) LIKE '3%'
GO
Éste es el conjunto de resultados de las consultas:
Title ytd_sales
------------------------------ -----------
Cooking with Computers: Surrep 3876
Computer Phobic AND Non-Phobic 375
Emotional Security: A New Algo 3336
Onions, Leeks, and Garlic: Coo 375
(4 row(s) affected)
B. Utilizar CAST con operadores aritméticos
Este ejemplo calcula una única columna (Copies) dividiendo las ventas anuales totales
(ytd_sales) por el precio individual del libro (price). El resultado se convierte al tipo de datos int
después de ser redondeado al número entero más próximo.
USE pubs
GO
SELECT CAST(ROUND(ytd_sales/price, 0) AS int) AS 'Copies'
FROM titles
GO
Éste es el conjunto de resultados:
Copies
-----------
205
324
6262
205
102
7440
NULL
383
205
NULL
17
187
16
204
418
18

Material de estudio Página: 171 de 249


Visual Basic 6.0 y SQLServer 7.0

1263
273
(18 row(s) affected)
C. Utilizar CAST para concatenar
Este ejemplo concatena expresiones que no son de texto ni binarias 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
Éste es el conjunto de resultados:
-------------------------
The price is 19.99
The price is 11.95
The price is 19.99
The price is 19.99
The price is 22.95
The price is 20.00
The price is 21.59
The price is 10.95
The price is 19.99
The price is 20.95
The price is 11.95
The price is 14.99
(12 row(s) affected)
D. Utilizar CAST para obtener texto más legible
Este ejemplo utiliza CAST en la lista seleccionada para convertir la columna title a char(50), para
que los resultados sean más legibles.
USE pubs
GO
SELECT CAST(title AS char(50)), ytd_sales
FROM titles
WHERE type = 'trad_cook'
GO
Éste es el conjunto de resultados:
ytd_sales
-------------------------------------------------- ---------
Onions, Leeks, and Garlic: Cooking Secrets of the 375
Fifty Years in Buckingham Palace Kitchens 15096
Sushi, Anyone? 4095
(3 row(s) affected)
E. Utilizar CAST con una cláusula LIKE
Este ejemplo convierte una columna int (la columna ytd_sales) a char(20) para que se puede
utilizar en una cláusula LIKE.
USE pubs
GO
SELECT title, ytd_sales
FROM titles
WHERE CAST(ytd_sales AS char(20)) LIKE '15%'
AND type = 'trad_cook'
GO
Éste es el conjunto de resultados:

Material de estudio Página: 172 de 249


Visual Basic 6.0 y SQLServer 7.0

title ytd_sales
------------------------------------------------------------ -----------
Fifty Years in Buckingham Palace Kitchens 15096
(1 row(s) affected)

1.5.2 Utilizar funciones

Microsoft SQL Server dispone de funciones integradas para realizar ciertas operaciones rápida y
fácilmente. Las categorías en que se dividen las funciones son:
Funciones de agregado:Realizan operaciones que combinan varios valores en uno.
Ejemplos son COUNT, SUM, MIN y MAX.
Funciones de configuración :Son funciones escalares que devuelven información acerca
de la configuración.
Funciones de cursores :Devuelven información acerca del estado de un cursor.
Funciones de fecha y hora :Tratan valores datetime y smalldatetime.
Funciones matemáticas :Realizan operaciones trigonométricas, geométricas y demás
operaciones numéricas.
Funciones de metadatos :Devuelven información acerca de los atributos de las bases de
datos y de los objetos de base de datos.
Funciones de conjuntos de filas :Devuelven conjuntos de filas que se pueden usar en el
lugar de una referencia de tabla de una instrucción de Transact-SQL.
Funciones de seguridad : Devuelven información acerca de usuarios y funciones.
Funciones de cadena :Tratan valores char, varchar, nchar, nvarchar, binary y
varbinary.
Funciones del sistema :Funcionan en o informan acerca de varias opciones y objetos del
sistema.
Funciones de estadísticas del sistema :Devuelven información relacionada con el
rendimiento de SQL Server.
Funciones de texto e imagen :Tratan valores text e image.
Las funciones se pueden usar o incluir en:
• La lista de selección de una consulta que usa una instrucción SELECT para devolver un
valor.
SELECT DB_NAME()
• Una condición de búsqueda de una cláusula WHERE de una instrucción SELECT o de
modificación de datos (SELECT, INSERT, DELETE o UPDATE) para limitar las filas
adecuadas para la consulta.
SELECT *
FROM [Order Details]
WHERE Quantity =
(SELECT MAX(Quantity) FROM [Order Details])

Material de estudio Página: 173 de 249


Visual Basic 6.0 y SQLServer 7.0

• La condición de búsqueda (condición WHERE) de una vista para hacer que la vista se
adapte dinámicamente al usuario o entorno en tiempo de ejecución.
CREATE VIEW ShowMyEmploymentInfo AS
SELECT * FROM Employees
WHERE EmployeeID = SUSER_SID()
GO
• Cualquier expresión.
• Un desencadenador o restricción CHECK para comprobar los valores especificados
cuando se insertan datos.
CREATE TABLE SalesContacts
(SalesRepID INT PRIMARY KEY CHECK (SalesRepID = SUSER_SID() ),
ContactName VARCHAR(50) NULL,
ContactPhone VARCHAR(13) NULL)
• Un desencadenador o restricción DEFAULT para suministrar un valor en el caso de que
no se especifique ninguno en una instrucción INSERT.
CREATE TABLE SalesContacts
(
SalesRepID INT PRIMARY KEY CHECK (SalesRepID = SUSER_SID() ),
ContactName VARCHAR(50) NULL,
ContactPhone VARCHAR(13) NULL,
WhenCreated DATETIME DEFAULT GETDATE(),
Creator INT DEFAULT SUSER_SID()
)
GO

Al utilizar las funciones tome en cuenta los siguiente puntos:

 Las funciones se usan siempre con paréntesis, incluso cuando no haya parámetros. Una
excepción son las funciones niládicas (funciones que no toman parámetros) usadas con la
palabra clave DEFAULT.
 Algunas veces, los parámetros que especifican una base de datos, equipo, inicio de sesión o
usuario de base de datos son opcionales. Si no se proporcionan, el valor predeterminado es
el de la base de datos, equipo host, inicio de sesión o usuario de base de datos actual.
 Las funciones se pueden anidar (una función se usa dentro de otra función).

1.5.3 Programar tareas en Transac-SQL

Para realizar procesos que no se pueden llevar a cabo con una sola instrucción de Transact-SQL,
Microsoft SQL Server permite agrupar instrucciones de Transact-SQL de varias formas:
• Usar lotes : Un lote es un grupo compuesto por una o varias instrucciones de Transact-
SQL que se envían desde una aplicación al servidor como una unidad. SQL Server
ejecuta cada lote como una unidad ejecutable individual.
• Utilizar procedimientos almacenados : Un procedimiento almacenado es un grupo de
instrucciones de Transact-SQL que han sido definidas y compiladas previamente en el
servidor. El procedimiento almacenado puede aceptar parámetros y devolver conjuntos
de resultados, códigos de retorno y parámetros de salida a la aplicación que realiza la
llamada.
• Utilizar desencadenadores :Un desencadenador es un tipo especial de procedimiento
almacenado. No es llamado directamente por las aplicaciones. En su lugar, se ejecuta
cuando un usuario realiza una modificación determinada (INSERT, UPDATE o DELETE)
en una tabla.
• Utilizar secuencias de comandos : Una secuencia de comandos es una serie de
instrucciones de Transact-SQL almacenadas en un archivo. El archivo se puede usar

Material de estudio Página: 174 de 249


Visual Basic 6.0 y SQLServer 7.0

como entrada para la herramienta osql o para el Analizador de consultas de SQL Server.
Las herramientas ejecutarán entonces las instrucciones de Transact-SQL almacenadas
en el archivo.
Las siguientes características de SQL Server permiten controlar la utilización de varias
instrucciones de Transact-SQL a la vez:
• Instrucciones de control de flujo : Le permiten incluir lógica condicional. Por ejemplo, si
el país es Canadá, se realiza una serie de instrucciones de Transact-SQL. Si el país es
Reino Unido, se realiza otra serie de instrucciones de Transact-SQL.
• Variables : Le permiten almacenar datos para ser utilizados posteriormente como entrada
de una instrucción de Transact-SQL. Por ejemplo, puede que tenga que codificar una
consulta que necesite especificar distintos valores de datos en la cláusula WHERE cada
vez que se ejecuta la consulta. Puede escribir la consulta para que use variables en la
cláusula WHERE y codificar la lógica para que rellene las variables con los datos
adecuados. Los parámetros de los procedimientos almacenados son una clase especial
de variables.
• Tratamiento de errores : Le permite personalizar la forma en la que SQL Server
responde a los problemas. Pueden especificar las acciones apropiadas que se llevarán a
cabo cuando se produzcan errores, o generar mensajes de error personalizados que sean
más informativos para el usuario que los errores genéricos de SQL Server.

1.5.4 Variables y parámetros

Transact-SQL tiene varias formas de pasar datos entre instrucciones de Transact-SQL. Entre
éstas se encuentran:
• Las variables locales de Transact-SQL :Una variable de Transact-SQL es un objeto de
lotes y secuencias de comandos de Transact-SQL que puede contener un valor de datos.
Una vez que la variable se ha declarado o definido, una instrucción de Transact-SQL de
un lote puede establecer la variable a un valor y otra instrucción posterior del lote puede
obtener el valor de la variable, por ejemplo:
DECLARE @EmpIDVar INT
SET @EmpIDVar = 1234
SELECT *
FROM Employees
WHERE EmployeeID = @EmpIDVar
• Parámetros de Transact-SQL :Un parámetro es un objeto usado para pasar datos entre
un procedimiento almacenado y el lote o secuencia de comandos que lo ejecuta. Los
parámetros pueden ser de entrada o de salida, como, por ejemplo:
CREATE PROCEDURE ParmSample @EmpIDParm INT AS
SELECT *
FROM Employees
WHERE EmployeeID = @EmpIDParm
GO
EXEC ParmSample @EmpIDParm = 1234
GO
Las aplicaciones usan variables de aplicación y marcadores de parámetros para trabajar con los
datos de las instrucciones de Transact-SQL.
• Variables de aplicación :Los lenguajes de programación de aplicaciones como C, C++,
Basic y Java tienen sus propias variables para contener datos. Las aplicaciones que usan
las API de base de datos tienen que mover los datos devueltos por las instrucciones de
Transact-SQL a las variables de aplicación antes de que puedan trabajar con los datos.
Esto se hace normalmente en un proceso llamado enlace. La aplicación usa una función
de API para enlazar una columna del conjunto de resultados a una variable del programa.
Cuando se recupera una fila, el proveedor o controlador de API mueve los datos desde la
columna a la variable del programa enlazada.

Material de estudio Página: 175 de 249


Visual Basic 6.0 y SQLServer 7.0

• Marcadores de parámetros :Los marcadores de parámetros son admitidos por ADO,


OLE DB y las API de base de datos basadas en ODBC. Un marcador de parámetro es un
signo de interrogación (?) colocado en la posición de una expresión de entrada en una
instrucción de Transact-SQL. El marcador de parámetro se enlaza a una variable de
aplicación. Esto permite que los datos de variables de aplicación se usen como entradas
de las instrucciones de Transact-SQL. Los marcadores de parámetros permiten también
que los parámetros de salida y los códigos de retorno de los procedimientos almacenados
se enlacen a variables de aplicación. Cuando se ejecuta el procedimiento, los datos de
salida se devuelven a las variables enlazadas. La API de las bibliotecas de bases de
datos admite también que se enlacen los parámetros de los procedimientos almacenados
y los códigos de retorno a las variables del programa.

1.5.5 Control de flujo.

Transact-SQL proporciona palabras especiales que forman parte del llamado lenguaje de control
de flujo con el que se controla la ejecución de instrucciones de Transact-SQL, bloques de
instrucciones y procedimientos almacenados. Estas palabras se pueden usar en las instrucciones
"ad hoc" de Transact-SQL, en los lotes y en los procedimientos almacenados.
Sin el lenguaje de control de flujo, las instrucciones independientes de Transact-SQL se ejecutan
secuencialmente, tal como se producen. El lenguaje de control de flujo permite que las
instrucciones estén conectadas, se relacionen entre ellas y se hagan interdependientes con
construcciones similares a las de la programación.
Estas palabras para el control de flujo son útiles cuando es necesario dirigir a Transact-SQL para
que realice alguna clase de acción. Por ejemplo, use un par de instrucciones BEGIN…END
cuando incluya más de una instrucción de Transact-SQL en un bloque lógico. Use un par de
instrucciones IF…ELSE cuando una determinada instrucción o bloque de instrucciones tenga que
ser ejecutado IF (si) se cumple alguna condición, y deba ejecutarse otra instrucción o bloque de
instrucciones si esa condición no se cumple (la condición ELSE).
Las instrucciones de control de flujo no pueden dividirse en varios lotes o procedimientos
almacenados.
Las palabras clave del lenguaje de control de flujo son:

BEGIN…END WAITFOR
GOTO WHILE
IF…ELSE BREAK
RETURN CONTINUE

1.5.5.1 BEGIN…END

Las instrucciones BEGIN y END se usan para agrupar varias instrucciones de Transact-SQL en
un bloque lógico. Use las instrucciones BEGIN y END en cualquier parte donde una instrucción de
control de flujo deba ejecutar un bloque con dos o más instrucciones de Transact-SQL.
Por ejemplo, cuando una instrucción IF controla la ejecución de una única instrucción de
Transact-SQL, no se necesita ninguna instrucción BEGIN o END:
IF (@@ERROR <> 0)
SET @ErrorSaveVariable = @@ERROR
Si @@ERROR es 0, sólo se salta la instrucción individual SET.
Use las instrucciones BEGIN y END para hacer que la instrucción IF salte un bloque de
instrucciones cuando el resultado de la evaluación sea FALSE (falso):
IF (@@ERROR <> 0)
BEGIN
SET @ErrorSaveVariable = @@ERROR

Material de estudio Página: 176 de 249


Visual Basic 6.0 y SQLServer 7.0

PRINT 'Error encountered, ' +


CAST(@ErrorSaveVariable AS VARCHAR(10))
END
Las instrucciones BEGIN y END deben usarse como un par: no se puede usar una sin la otra. La
instrucción BEGIN aparece sola en una línea, seguida de un bloque de instrucciones de Transact-
SQL. Finalmente, la instrucción END aparece sola en una línea para indicar el fin del bloque.
Las instrucciones BEGIN y END se usan cuando:
• Es necesario que un bucle WHILE incluya un bloque de instrucciones.
• Es necesario que un elemento de una función CASE incluya un bloque de instrucciones.
• Es necesario que una cláusula IF o ELSE incluya un bloque de instrucciones

1.5.5.2 GOTO

La instrucción GOTO provoca que, en la ejecución de un lote de Transact-SQL, se salte a una


etiqueta. Ninguna de las instrucciones situadas entre la instrucción GOTO y la etiqueta se
ejecutarán. El nombre de la etiqueta se define con la sintaxis:
nombreEtiqueta:
No abuse de la utilización de la instrucción GOTO. Una utilización excesiva de esta instrucción
puede hacer que resulte difícil entender la lógica de un lote de Transact-SQL. La lógica
desarrollada con GOTO casi siempre se puede implementar con las instrucciones de control de
flujo. La mejor utilización de GOTO se produce cuando se necesita romper la anidación profunda
de instrucciones de control de flujo.
La etiqueta que constituye el objetivo de un GOTO sólo identifica el destino del salto. No hace
nada para aislar las instrucciones que le siguen de las instrucciones que le preceden. Cualquier
usuario que ejecute las instrucciones situadas justo antes de la etiqueta se la saltará y ejecutará
las instrucciones posteriores a la misma. Esto ocurrirá a menos que las instrucciones que
preceden a la etiqueta sean a su vez instrucciones de control de flujo como, por ejemplo,
RETURN.

Esto es un ejemplo de un GOTO:


IF (SELECT SYSTEM_USER()) = 'payroll'
GOTO Vete_a
UPDATE ‘una tabla’
DELETE ‘una tabla’
--si la condición es verdadera se ignorán las dos
--intsrucciones anteriores-- statements following the GOTO are executed.
Vete_a:
--Sigue el flujo del programa

1.5.5.3 IF…ELSE

La instrucción IF se usa para probar una condición. El control de flujo resultante depende de si se
especifica o no la instrucción ELSE opcional:
• IF especificado sin ELSE.
Cuando la instrucción IF da como resultado TRUE (verdadero), se ejecuta la instrucción o bloque
de instrucciones que sigue a la instrucción IF. Cuando la instrucción IF da como resultado FALSE
(falso), se salta la instrucción o bloque de instrucciones que sigue a la instrucción IF.
• IF especificado con ELSE.
Cuando la instrucción IF da como resultado TRUE, se ejecuta la instrucción o bloque de
instrucciones que siguen a IF y el control salta al punto posterior a la instrucción o bloque
de instrucciones que sigue a ELSE. Cuando la instrucción IF da como resultado FALSE,
se salta la instrucción o bloque de instrucciones que sigue a IF y se ejecuta la instrucción
o bloque de instrucciones que sigue a la instrucción ELSE opcional.

Material de estudio Página: 177 de 249


Visual Basic 6.0 y SQLServer 7.0

Por ejemplo, si un procedimiento almacenado ha estado guardando los códigos de error


devueltos por @@ERROR durante una transacción, podría tener una instrucción IF similar a la
siguiente al final del procedimiento:
IF (@ErrorSaveVariable <> 0)
BEGIN
PRINT 'Errores encontrados, va pa tras.'
CAST(@ErrorSaveVariable AS VARCHAR(10))
ROLLBACK
END
ELSE
BEGIN
PRINT 'No existen errores, aceptamos trasacción.'
COMMIT
END
RETURN @ErrorSaveVariable

1.5.5.4 RETURN

La instrucción RETURN termina incondicionalmente una consulta, procedimiento almacenado o


lote. Ninguna de las instrucciones de un procedimiento almacenado o lote que siga a la
instrucción RETURN se ejecutará.
Cuando se usa en un procedimiento almacenado, la instrucción RETURN puede especificar un
valor entero para devolver a la aplicación, lote o procedimiento que realiza la llamada. Si no se
especifica ningún valor en la instrucción RETURN, un procedimiento almacenado devuelve el
valor 0.
La mayor parte de los procedimientos almacenados siguen la convención de usar el código de
retorno para indicar si el procedimiento almacenado se ha ejecutado correctamente o no. Los
procedimientos almacenados devuelven el valor 0 cuando no se encontraron errores. Cualquier
valor distinto de cero indica que se produjo un error. Por ejemplo:
USE Northwind
GO
-- Create a procedure that takes one input parameter
-- and returns one output parameter and a return code.
CREATE PROCEDURE SampleProcedure @EmployeeIDParm INT,
@MaxQuantity INT OUTPUT
AS
-- Declare and initialize a variable to hold @@ERROR.
DECLARE @ErrorSave INT
SET @ErrorSave = 0
-- Do a SELECT using the input parameter.
SELECT FirstName, LastName, Title
FROM Employees
WHERE EmployeeID = @EmployeeIDParm
-- Save any nonzero @@ERROR value.
IF (@@ERROR <> 0)
SET @ErrorSave = @@ERROR
-- Set a value in the output parameter.
SELECT @MaxQuantity = MAX(Quantity)
FROM [Order Details]
IF (@@ERROR <> 0)
SET @ErrorSave = @@ERROR
-- Returns 0 if neither SELECT statement had
-- an error, otherwise returns the last error.
RETURN @ErrorSave
GO

Material de estudio Página: 178 de 249


Visual Basic 6.0 y SQLServer 7.0

Un lote o procedimiento almacenado de Transact-SQL que ejecuta un procedimiento almacenado


puede recuperar el código de retorno en una variable de tipo entero:
DECLARE @ReturnStatus INT
DECLARE @MaxQtyVariable INT
EXECUTE @ReturnStatus = SampleProcedure @EmployeeIDParm = 9,
@MaxQtyVariable = @MaxQuantity OUTPUT
-- Show the values returned.
PRINT ' '
PRINT 'Return code = ' + CAST(@ReturnStatus AS CHAR(10))
PRINT 'Maximum Quantity = ' + CAST(@MaxQtyVariable AS CHAR(10))
GO
Las aplicaciones que llaman a un procedimiento almacenado pueden enlazar a una variable de
tipo entero el marcador de parámetro que corresponda al código de retorno.

1.5.5.5 WAITFOR
La instrucción WAITFOR suspende la ejecución de una conexión hasta que:
 Haya pasado un intervalo especificado de tiempo.
 Se haya alcanzado una hora especificada del día.

La instrucción WAITFOR se especifica con una de estas dos cláusulas:


 La palabra clave DELAY seguida de una cantidadTiempoQuePasar antes de que
se complete la instrucción WAITFOR. El tiempo que puede pasar antes de la finalización
de la instrucción WAITFOR puede ser de hasta 24 horas.
 La palabra clave TIME seguida de una horaDeEjecución que especifica cuándo
se completa la instrucción WAITFOR.

En este ejemplo se usa la palabra clave DELAY para esperar dos segundos antes de realizar una
instrucción SELECT:
WAITFOR DELAY '00:00:02'
SELECT EmployeeID FROM Northwind.dbo.Employees
En este ejemplo se usa la palabra clave TIME para esperar hasta las 10 p.m. para realizar una
comprobación de la base de datos especificada pubs con el fin de asegurar que todas las
páginas están asignadas y se usan correctamente.
USE pubs
BEGIN
WAITFOR TIME '22:00'
DBCC CHECKALLOC
END
La desventaja de la instrucción WAITFOR es que la conexión de la aplicación permanece
suspendida hasta que finaliza WAITFOR. El mejor uso de WAITFOR se produce cuando se
necesita suspender el procesamiento de una aplicación o procedimiento almacenado durante un
tiempo limitado. La utilización del Agente SQL Server o de SQL-DMO para programar una tarea
constituye un método más adecuado para ejecutar una acción a una hora determinada del día.

1.5.5.6 WHILE…BREAK o CONTINUE


La instrucción WHILE repite una instrucción o bloque de instrucciones mientras la condición
especificada siga siendo verdadera.
Con WHILE se usan normalmente dos instrucciones de Transact-SQL: BREAK o CONTINUE. La
instrucción BREAK sale del bucle WHILE más profundo, y la instrucción CONTINUE reinicia un
bucle WHILE. Un programa podría ejecutar una instrucción BREAK si, por ejemplo, no hubiera
más filas que procesar. Una instrucción CONTINUE podría ejecutarse si, por ejemplo, la ejecución
del código debiera continuar.

Material de estudio Página: 179 de 249


Visual Basic 6.0 y SQLServer 7.0

Nota Si una instrucción SELECT se usa como condición de la instrucción WHILE, la instrucción
SELECT debe ir entre paréntesis.

En este ejemplo se usa una instrucción WHILE para controlar el número de recopilaciones
realizadas:
USE Northwind
GO
DECLARE abc CURSOR FOR
SELECT * FROM Shippers
OPEN abc
FETCH NEXT FROM abc
WHILE (@@FETCH_STATUS = 0)
FETCH NEXT FROM abc
CLOSE abc
DEALLOCATE abc
GO
Otras pruebas válidas de la condición WHILE podrían ser las siguientes:
WHILE (@ACounterVariable < 100)
- O bien -
WHILE EXISTS(SELECT au_lname FROM authors WHERE au_fname = 'Anne')

1.5.5.5 CASE

La función CASE es una expresión especial de Transact-SQL que permite que se muestre un
valor alternativo dependiendo del valor de una columna. Este cambio es temporal, con lo que no
hay cambios permanentes en los datos. Por ejemplo, la función CASE puede mostrar California
en un conjunto de resultados de una consulta de las filas que tengan el valor CA en la columna
state.
La función CASE está compuesta de:
• La palabra clave CASE.
• El nombre de columna que se va a transformar.
• Cláusulas WHEN que especifican las expresiones que se van a buscar y cláusulas THEN
que especifican las expresiones que las van a reemplazar.
• La palabra clave END.
• Una cláusula AS opcional que define un alias de la función CASE.
En este ejemplo se muestra, en el conjunto de resultados de la consulta, el nombre completo del
estado en el que vive cada autor:
SELECT au_fname, au_lname,
CASE state
WHEN 'CA' THEN 'California'
WHEN 'KS' THEN 'Kansas'
WHEN 'TN' THEN 'Tennessee'
WHEN 'OR' THEN 'Oregon'
WHEN 'MI' THEN 'Michigan'
WHEN 'IN' THEN 'Indiana'
WHEN 'MD' THEN 'Maryland'
WHEN 'UT' THEN 'Utah'
END AS StateName
FROM pubs.dbo.authors
ORDER BY au_lname

Material de estudio Página: 180 de 249


Visual Basic 6.0 y SQLServer 7.0

1.6 Transacciones
Una transacción es una secuencia de operaciones realizadas como una sola unidad lógica de
trabajo. Una unidad lógica de trabajo debe exhibir cuatro propiedades, conocidas como
propiedades ACID (atomicidad, coherencia, aislamiento y durabilidad), para ser calificada como
transacción:
Atomicidad :Una transacción debe ser una unidad atómica de trabajo, tanto si se realizan
todas sus modificaciones en los datos, como si no se realiza ninguna de ellas.
Coherencia :Cuando finaliza, una transacción debe dejar todos los datos en un estado
coherente. En una base de datos relacional, se debe aplicar todas las reglas a las
modificaciones de la transacción para mantener la integridad de todos los datos. Todas las
estructuras internas de datos, como índices de árbol B o listas doblemente vinculadas,
deben estar correctos al final de la transacción.
Aislamiento :Las modificaciones realizadas por transacciones simultáneas se deben aislar
de las modificaciones llevadas a cabo por otras transacciones simultáneas. Una
transacción ve los datos en el estado en que estaban antes de que otra transacción
simultánea los modificara o después de que la segunda transacción se haya concluido,
pero no ve un estado intermedio. Esto se conoce como seriabilidad debido a que su
resultado es la capacidad de volver a cargar los datos iniciales y reproducir una serie de
transacciones para finalizar con los datos en el mismo estado en que estaban después de
realizar las transacciones originales.
Durabilidad :Una vez concluida una transacción, sus efectos son permanentes en el
sistema. Las modificaciones persisten aún en el caso de producirse un error del sistema.
Especificar y exigir transacciones
Los programadores de SQL son los responsables de iniciar y finalizar las transacciones en puntos
que exijan la coherencia lógica de los datos. El programador debe definir la secuencia de
modificaciones de datos que los dejan en un estado coherente en relación a las reglas
corporativas de la organización. A continuación, el programador incluye estas instrucciones de
modificación en una sola transacción de forma que Microsoft SQL Server puede exigir la
integridad física de la misma.
Es responsabilidad de un sistema de base de datos corporativo como SQL Server proporcionar
los mecanismos que aseguren la integridad física de cada transacción. SQL Server proporciona:
• Servicios de bloqueo que preservan el aislamiento de la transacción.
• Servicios de registro que aseguran la durabilidad de la transacción. Aún en el caso de que
falle el hardware del servidor, el sistema operativo o el propio SQL Server, SQL Server
utiliza registros de transacciones, al reinicio, para deshacer automáticamente las
transacciones incompletas en el momento en que se produjo el error en el sistema.
• Características de administración de transacciones que exigen la atomicidad y coherencia
de la transacción. Una vez iniciada una transacción, debe concluirse correctamente o
SQL Server deshará todas las modificaciones de datos realizadas desde que se inició la
transacción.

1.6.1 Controlar las transacciones.

Las aplicaciones controlan las transacciones principalmente al especificar cuándo se inicia y


finaliza una transacción. Esto se puede especificar mediante la utilización de instrucciones de

Material de estudio Página: 181 de 249


Visual Basic 6.0 y SQLServer 7.0

Transact-SQL o funciones de la API de base de datos. El sistema también debe ser capaz de
controlar correctamente los errores que terminan una transacción antes de que se concluya.
Las transacciones se administran en las conexiones. Cuando se inicia una transacción en una
conexión, todas las instrucciones de Transact-SQL ejecutadas en esa conexión forman parte de la
transacción hasta que la transacción finaliza.
Puede iniciar transacciones en Microsoft SQL Server como transacciones explícitas, de confirmación
automática o implícitas.

Transacciones explícitas:Inicie una transacción de forma explícita mediante la


instrucción BEGIN TRANSACTION.
Transacciones de confirmación automática :Éste es el modo predeterminado de SQL
Server. Cada instrucción individual de Transact-SQL se confirma cuando termina. No
tiene que especificar instrucciones para controlar las transacciones.
Transacciones implícitas :Establezca el modo de transacción implícita a través de una
función de la API o la instrucción SET IMPLICIT_TRANSACTIONS ON de Transact-
SQL . La siguiente instrucción inicia automáticamente una nueva transacción. Cuando se
concluye la transacción, la instrucción de Transact-SQL siguiente inicia una nueva
transacción.
Los modos de conexión se administran en las conexiones. Si una transacción cambia de un modo
de transacción a otro, no tiene efecto sobre los modos de transacción de otras conexiones.
Finalizar transacciones
Puede finalizar las transacciones con la instrucción COMMIT o la instrucción ROLLBACK.
COMMIT
Si una transacción es correcta, confírmela. La instrucción COMMIT garantiza que
todas las modificaciones de la transacción se convierten en una parte permanente de la
base de datos. La instrucción COMMIT también libera recursos que utiliza la
transacción como, por ejemplo, los bloqueos.
ROLLBACK
Si se produce un error en una transacción o el usuario decide cancelar la transacción,
deshaga la transacción. La instrucción ROLLBACK deshace todas las modificaciones
realizadas en la transacción al devolver los datos al estado en que estaban al inicio de
la transacción. La instrucción ROLLBACK también libera los recursos que mantiene
la transacción.
Especificar los límites de la transacción
Puede identificar si las transacciones de SQL Server se inician y finalizan con instrucciones de
Transact-SQL o con funciones y métodos de la API.
Instrucciones de Transact-SQL
Utilice las instrucciones BEGIN TRANSACTION, COMMIT TRANSACTION,
COMMIT WORK, ROLLBACK TRANSACTION, ROLLBACK WORK y SET
IMPLICIT_TRANSACTIONS para delinear transacciones. Se utilizan principalmente
en aplicaciones de Bibliotecas de bases de datos y en secuencias de comandos de

Material de estudio Página: 182 de 249


Visual Basic 6.0 y SQLServer 7.0

Transact-SQL, como las secuencias de comandos que se ejecutan con el programa del
símbolo del sistema osql.
Funciones y métodos de la API
Las API de bases de datos, como ODBC, OLE DB y ADO contienen funciones o
métodos utilizados para delinear transacciones. Éstos son los principales mecanismos
utilizados para controlar transacciones en una aplicación de SQL Server.
Cada transacción se debe administrar solamente mediante uno de estos métodos. La utilización
de ambos métodos en la misma transacción puede conducir a resultados no definidos. Por
ejemplo, no debe iniciar una transacción con las funciones de la API de ODBC y después utilizar
la instrucción COMMIT de Transact-SQL para concluir la transacción. De esta forma, no notificaría
al controlador ODBC de SQL Server que se confirmó la transacción. En este caso, utilice la
función SQLEndTran de ODBC para finalizar la transacción.
Errores al procesar la transacción
Si un error grave impide la terminación correcta de una transacción, SQL Server deshace
automáticamente la transacción y libera todos los recursos que mantiene la transacción. Si se
interrumpe la conexión de red del cliente con SQL Server, las transacciones pendientes de la
conexión se deshacen cuando la red notifica a SQL Server la interrupción. Si la aplicación cliente
falla o si el equipo cliente se bloquea o se reinicia, también se interrumpe la conexión y SQL
Server deshace las conexiones pendientes cuando la red le notifica la interrupción. Si el cliente
cierra la aplicación, se deshacen las transacciones pendientes.
Si se produce el error de una instrucción en tiempo de ejecución (como una infracción de
restricciones) en un archivo por lotes, el comportamiento predeterminado de SQL Server consiste
en deshacer solamente la instrucción que generó el error. Puede modificar este comportamiento
con la instrucción SET XACT_ABORT. Una vez ejecutada la instrucción SET XACT_ABORT ON,
los errores de instrucciones en tiempo de ejecución hacen que se deshaga automáticamente la
transacción actual. Los errores de compilación como, por ejemplo, un error de sintaxis no se ven
afectados por la instrucción SET XACT_ABORT.
Es responsabilidad del programador codificar la aplicación para especificar la acción correcta
(COMMIT o ROLLBACK) si se produce un error de compilación o en tiempo de ejecución.

1.6.2 Transacciones explícitas

Una transacción explícita es aquella en que se define explícitamente el inicio y el final de la


transacción. Las transacciones explícitas también recibían el nombre de transacciones definidas
por el usuario o especificadas por el usuario en versiones anteriores de Microsoft SQL Server .
Las aplicaciones de bibliotecas de base de datos y secuencias de comandos de Transact-SQL
utilizan las instrucciones de Transact-SQL BEGIN TRANSACTION, COMMIT TRANSACTION,
COMMIT WORK, ROLLBACK TRANSACTION o ROLLBACK WORK para definir transacciones
explícitas.
BEGIN TRANSACTION :Marca el punto de inicio de una transacción explícita de una
conexión.
COMMIT TRANSACTION o COMMIT WORK :Se utiliza para finalizar una
transacción correctamente si no hubo errores. Todas las modificaciones de datos
realizadas en la transacción se convierten en parte permanente de la base de datos. Los
recursos mantenidos por la transacción se liberan.

Material de estudio Página: 183 de 249


Visual Basic 6.0 y SQLServer 7.0

ROLLBACK TRANSACTION o ROLLBACK WORK :Se utiliza para eliminar una


transacción en la que se encontraron errores. Se devuelven todos los datos que modifica la
transacción al estado en que estaba al inicio de la transacción. Los recursos mantenidos
por la transacción se liberan.
También puede utilizar transacciones explícitas en OLE DB. Llame al método
ITransactionLocal::StartTransaction para iniciar una transacción. Llame al método
ITransaction::Commit o ITransaction::Abort con FALSE establecido en fRetener para finalizar
la transacción sin iniciar automáticamente otra transacción.
En ADO, utilice el método BeginTrans en un objeto Connection para iniciar una transacción
explícita. Para finalizar la transacción, llame a los métodos CommitTrans o RollbackTrans del
objeto Connection.
La API de ODBC no acepta transacciones explícitas, sólo acepta transacciones de confirmación
automática y transacciones implícitas.
El modo de transacciones explícitas se mantiene solamente durante la transacción. Cuando la
transacción termina, la conexión vuelve al modo de transacción en que estaba antes de iniciar la
transacción explícita, es decir, el modo implícito o el modo de confirmación automática.

1.6.3 Transacciones de confirmación automática

El modo de confirmación automática es el modo predeterminado de administración de


transacciones de Microsoft SQL Server . Toda instrucción de Transact-SQL se confirma o se
deshace cuando termina. Si una instrucción termina correctamente, se confirma; si encuentra un
error, se deshace. Una conexión de SQL Server funciona en modo de confirmación automática
siempre que no se suplante el modo predeterminado mediante transacciones explícitas o
implícitas. El modo de confirmación automática es también el modo predeterminado para la
biblioteca de bases de datos, ODBC, OLE DB y ADO.
Una conexión de SQL Server funcionará en modo de confirmación automática hasta que la
instrucción BEGIN TRANSACTION inicie una transacción explícita o se active el modo de
transacciones implícitas. Cuando la transacción explícita se confirma o se deshace, o cuando se
desactiva el modo de transacciones implícitas, SQL Server vuelve al modo de confirmación
automática.
 Errores de compilación y en tiempo de ejecución
En el modo de confirmación automática, a veces parece que SQL Server ha deshecho un proceso
por lotes completo en vez de deshacer solamente una instrucción SQL. Esto sólo sucede si se
trata de un error de compilación, no en el caso de un error en tiempo de ejecución. Los errores de
compilación impiden que SQL Server genere un plan de ejecución, por lo que no se ejecuta
ninguna instrucción del proceso por lotes. Aunque parezca que se ha deshecho todas las
instrucciones anteriores a la que generó el error, el error impidió que se ejecutara ninguna
instrucción del proceso por lotes. En este ejemplo, no se ejecutó ninguna de las instrucciones
INSERT del tercer proceso por lotes debido a un error de compilación. Parece que se han
deshecho las dos primeras instrucciones INSERT cuando, en realidad, nunca se ejecutaron.
USE pubs
GO
CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3))
GO
INSERT INTO TestBatch VALUES (1, 'aaa')
INSERT INTO TestBatch VALUES (2, 'bbb')
INSERT INTO TestBatch VALUSE (3, 'ccc') /* Syntax error */
GO
SELECT * FROM TestBatch /* Returns no rows */
GO

Material de estudio Página: 184 de 249


Visual Basic 6.0 y SQLServer 7.0

En este ejemplo, la tercera instrucción INSERT genera un error de clave principal duplicada en
tiempo de ejecución. Las dos primeras instrucciones INSERT eran correctas y se han confirmado,
por lo que permanecen después de producirse el error en tiempo de ejecución.
USE pubs
GO
CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3))
GO
INSERT INTO TestBatch VALUES (1, 'aaa')
INSERT INTO TestBatch VALUES (2, 'bbb')
INSERT INTO TestBatch VALUES (1, 'ccc') /* Duplicate key error */
GO
SELECT * FROM TestBatch /* Returns rows 1 and 2 */
GO
SQL Server versión 7.0 introduce la resolución demorada de nombres, en la que no se resuelven
los nombres de los objetos hasta la ejecución. Las versiones anteriores de SQL Server resolvían
los nombres en tiempo de compilación. Algunos errores que eran de compilación y evitaban la
ejecución de un proceso por lotes en versiones anteriores de SQL Server son errores en tiempo
de ejecución en SQL Server 7.0. En este ejemplo, se ejecutaron y confirmaron las dos primeras
instrucciones INSERT y las dos filas permanecen en la tabla TestBatch después de que la
tercera instrucción INSERT generara un error en tiempo de ejecución al hacer referencia a una
tabla que no existe.
USE pubs
GO
CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3))
GO
INSERT INTO TestBatch VALUES (1, 'aaa')
INSERT INTO TestBatch VALUES (2, 'bbb')
INSERT INTO TestBch VALUES (3, 'ccc') /* Table name error */
GO
SELECT * FROM TestBatch /* Returns rows 1 and 2 */
GO

1.7 Cursores
Las operaciones de una base de datos relacional actúan en un conjunto completo de filas. El
conjunto de filas que devuelve una instrucción SELECT está compuesto de todas las filas que
satisfacen las condiciones de la cláusula WHERE de la instrucción. Este conjunto completo de
filas que devuelve la instrucción se conoce como el conjunto de resultados. Las aplicaciones,
especialmente las aplicaciones interactivas en línea, no siempre pueden trabajar de forma
efectiva con el conjunto de resultados completo como una unidad. Estas aplicaciones necesitan
un mecanismo que funcione con una fila o un pequeño bloque de filas a la vez. Los cursores son
una extensión de los conjuntos de resultados que proporcionan dicho mecanismo.
Los cursores amplían el procesamiento de los resultados debido a que:
• Permiten situarse en filas específicas del conjunto de resultados.
• Recuperan una fila o bloque de filas de la posición actual en el conjunto de resultados.
• Aceptan modificaciones de los datos de las filas en la posición actual del conjunto de
resultados
• Aceptan diferentes grados de visibilidad de los cambios que realizan otros usuarios en los
datos de la base de datos que se presentan en el conjunto de resultados.
• Proporcionan instrucciones de Transact-SQL en secuencias de comandos,
procedimientos almacenados y acceso de desencadenadores a los datos de un conjunto
de resultados.
Pedir un cursor
Microsoft SQL Server acepta dos métodos para pedir un cursor:

Material de estudio Página: 185 de 249


Visual Basic 6.0 y SQLServer 7.0

• Transact-SQL
El lenguaje Transact-SQL admite una sintaxis para utilizar cursores modelados a partir de
la sintaxis de cursores de SQL-92.
• Funciones de cursores de interfaces de programación de aplicaciones (API) de bases de
datos.
SQL Server admite la funcionalidad de cursores de las siguientes API de bases de datos:
• ADO (Microsoft ActiveX Data Object)
• OLE DB
• ODBC (Conectividad abierta de bases de datos)
• Bibliotecas de bases de datos
Una aplicación nunca debe mezclar estos dos métodos de petición de cursores. Una aplicación
que ha utilizado la API para especificar comportamientos de cursores no debe ejecutar una
instrucción DECLARE CURSOR de Transact-SQL para pedir también un cursor de Transact-SQL.
Una aplicación sólo debe ejecutar DECLARE CURSOR si ha devuelto todos los atributos de
cursores de la API a su configuración predeterminada.
Si no se ha pedido un cursor de Transact-SQL ni un cursor de la API, la configuración
predeterminada de SQL Server consiste en devolver un conjunto de resultados completo,
conocido como conjunto de resultados predeterminado, a la aplicación.
Proceso de cursores
Los cursores de Transact-SQL y los cursores de la API tienen una sintaxis diferente, pero se
utiliza el siguiente proceso general con todos los cursores de SQL Server:
1. Asocie un cursor con el conjunto de resultados de una instrucción Transact-SQL y defina
las características del cursor como, por ejemplo, si se puede actualizar las filas del cursor.
2. Ejecute la instrucción de Transact-SQL para llenar el cursor.
3. Recupere las filas del cursor que desea ver. La operación de recuperar una fila o un
bloque de filas de un cursor recibe el nombre de recopilación. Realizar series de
recopilaciones para obtener filas con desplazamientos adelante o hacia atrás recibe el
nombre de desplazamiento.
4. Opcionalmente, realice operaciones de modificación (actualización o eliminación) en la fila
de la posición actual del cursor.
5. Cierre el cursor.

1.7.1 Cursores de Transact-SQL

Los cursores de Transact-SQL se utilizan principalmente en procedimientos almacenados,


desencadenadores y secuencias de comandos de Transact-SQL en los que el contenido de un
conjunto de resultados está disponible para otras instrucciones de Transact-SQL.
El proceso típico para utilizar un cursor de Transact-SQL en un procedimiento almacenado o
desencadenador es:
1. Declare las variables de Transact-SQL que contendrán los datos que devuelva el cursor.
Declare una variable para cada columna del conjunto de resultados. Declare las variables
lo suficientemente grandes como para que contengan los valores que devuelve la
columna y con un tipo de datos que se pueda convertir implícitamente desde el tipo de
datos de la columna.
2. Asocie un cursor de Transact-SQL con una instrucción SELECT mediante la instrucción
DECLARE CURSOR. La instrucción DECLARE CURSOR también define las
características del cursor como, por ejemplo, el nombre del cursor y si el cursor es de sólo
lectura o de desplazamiento sólo hacia delante.
3. Utilice la instrucción OPEN para ejecutar la instrucción SELECT y llenar el cursor.
4. Utilice la instrucción FETCH INTO para recopilar filas individuales y mover los datos de
cada columna a la variable especificada. Otras instrucciones de Transact-SQL pueden
hacer referencia a estas variables para tener acceso a los valores de los datos

Material de estudio Página: 186 de 249


Visual Basic 6.0 y SQLServer 7.0

recopilados. Los cursores de Transact-SQL no admiten la recopilación de bloques de


columnas.
5. Cuando haya terminado con el cursor, utilice la instrucción CLOSE. Cerrar un cursor
libera algunos recursos, como el conjunto de resultados del cursor y sus bloqueos en la
fila actual, pero la estructura del cursor sigue disponible para procesarla si vuelve a emitir
una instrucción OPEN. Dado que el cursor sigue presente, no puede volver a utilizar el
nombre del cursor en este momento. La instrucción DEALLOCATE libera completamente
todos los recursos asignados al cursor, incluido el nombre del cursor. Una vez que se ha
cancelado la asignación de un cursor, debe emitir una instrucción DECLARE para volver
a generar el cursor.
Supervisar la actividad de cursores de Transact-SQL
Puede utilizar el procedimiento almacenado del sistema sp_cursor_list para obtener una lista de
los cursores visibles en la conexión actual y sp_describe_cursor,
sp_describe_cursor_columns y sp_describe_cursor_tables para determinar las
características de un cursor.
Una vez abierto el cursor, la función @@CURSOR_ROWS o la columna cursor_rows que
devuelve sp_cursor_list o sp_describe_cursor indican el número de filas del cursor.
Tras cada instrucción FETCH, se actualiza @@FETCH_STATUS para reflejar el estado de la
última recopilación. También puede obtener esta información de estado en la columna
fetch_status que devuelve sp_describe_cursor. @@FETCH_STATUS informa de condiciones
como, por ejemplo, si se recopila más allá de la primera o última fila del cursor.
@@FETCH_STATUS es global para la conexión y se restablece por cada recopilación que se
realiza en cualquier cursor abierto en la conexión. Si va a necesitar el estado posteriormente,
guarde @@FETCH_STATUS en una variable de usuario antes de ejecutar otra instrucción en la
conexión. Aunque la siguiente instrucción no sea FETCH, puede ser una instrucción INSERT,
UPDATE o DELETE que activa el desencadenador. Éste contiene instrucciones FETCH que
restablecen @@FETCH_STATUS. La columna fetch_status que devuelve sp_describe_cursor
es específica del cursor especificado y no se ve afectada por las instrucciones FETCH que hagan
referencia a otros cursores. Sin embargo, sp_describe_cursor se ve afectada por las
instrucciones FETCH que hacen referencia al mismo cursor, por lo que se debe utilizar con
cuidado.
Cuando se completa la instrucción FETCH, se dice que el cursor está ubicado en la fila
recopilada. La fila recopilada se conoce como la fila actual. Si no se declaró el cursor como de
sólo lectura, puede ejecutar una instrucción UPDATE o DELETE con la cláusula WHERE
CURRENT OF nombreCursor para modificar la fila actual.
El nombre que asigna a un cursor de Transact-SQL la instrucción DECLARE CURSOR puede ser
global o local. Cualquier lote, procedimiento almacenado o desencadenador que se ejecute en la
misma conexión puede hacer referencia a nombres de cursores globales. No se puede hacer
referencia a nombres de cursores locales fuera del lote, procedimiento almacenado o
desencadenador en que se declaró el cursor. Por lo tanto, los cursores locales de los
desencadenadores y procedimientos almacenados están protegidos contra referencias no
deseadas fuera del procedimiento almacenado o desencadenador.
Utilizar la variable cursor
Microsoft SQL Server también admite variables con el tipo de datos cursor. Se puede asociar un
cursor con una variable de tipo cursor mediante dos métodos:
/* Use DECLARE @local_variable, DECLARE CURSOR and SET. */
DECLARE @MyVariable CURSOR
DECLARE MyCursor CURSOR FOR
SELECT LastName FROM Northwind.dbo.Employees
SET @MyVariable = MyCursor
/* Use DECLARE @local_variable and SET */
DECLARE @MyVariable CURSOR
SET @MyVariable = CURSOR SCROLL KEYSET FOR
SELECT LastName FROM Northwind.dbo.Employees

Material de estudio Página: 187 de 249


Visual Basic 6.0 y SQLServer 7.0

Tras asociar un cursor a una variable de tipo cursor, se puede utilizar la variable cursor en lugar
del nombre del cursor en las instrucciones de cursor de Transact-SQL. El tipo de datos cursor
también se puede asignar a los parámetros de salida de un procedimiento almacenado y
asociarlo a un cursor. Esto permite que los procedimientos almacenados expongan cursores
locales de una forma controlada.
Hacer referencia a cursores de Transact-SQL
Sólo se puede hacer referencia a nombres de cursores de Transact-SQL y variables mediante
instrucciones de Transact-SQL; no se les puede hacer referencia desde funciones de la API de
OLE DB, ODBC, ADO y bibliotecas de bases de datos. Por ejemplo, si utiliza DECLARE
CURSOR y OPEN en un cursor de Transact-SQL, no hay forma de utilizar las funciones
SQLFetch o SQLFetchScroll de ODBC para recopilar una fila del cursor de Transact-SQL. La
aplicaciones que necesitan procesamiento de cursores y utilizan estas API deben utilizar la
compatibilidad de cursor integrada en la API de base de datos en lugar de cursores de Transact-
SQL.
Puede utilizar cursores de Transact-SQL en aplicaciones si utiliza FETCH y enlaza cada columna
que devuelve FETCH a una variable de programa. Sin embargo, dado que la instrucción FETCH
de Transact-SQL no admite lotes, ésta es la forma menos eficaz de devolver datos a una
aplicación. Recopilar cada fila requiere un viaje de ida y vuelta al servidor. Es más eficaz utilizar la
funcionalidad de cursor integrada en la API de la base de datos que admitir la recopilación de
lotes de filas.
Los cursores de Transact-SQL son extremadamente eficaces cuando se incluyen en
procedimientos almacenados y desencadenadores. Esto se debe a que todo se compila en un
plan de ejecución en el servidor y no hay tráfico de red asociado con la recopilación de filas.

 Recopilar y desplazar
La operación que consiste en recuperar una fila de un cursor recibe el nombre de recopilación.
Éstas son las opciones de recopilación:
• FETCH FIRST
Recopila la primera fila del cursor.
• FETCH NEXT
Recopila la fila siguiente a la última fila recopilada.
• FETCH PRIOR
Recopila la fila anterior a la última fila recopilada.
• FETCH LAST
Recopila la última fila del cursor.
• FETCH ABSOLUTE n
Recopila la enésima fila a partir de la primera fila del cursor, si n es un entero positivo. Si
n es un entero negativo, se recopila la fila que está n filas antes del final del cursor. Si n
es 0, no se recopila ninguna fila.
• FETCH RELATIVE n
Recopila la fila que está n filas a partir de la última fila recopilada. Si n es positivo, se
recopila la fila que está n filas después de la última fila recopilada. Si n es negativo, se
recopila la fila que está n filas delante de la última fila recopilada. Si n es 0, se recopila de
nuevo la misma fila.
Cuando se abre un cursor, la posición de la fila actual del cursor está lógicamente delante de la
primera fila. Esto hace que las diferentes opciones de recopilación tengan el siguiente
comportamiento si se trata de la primera recopilación que se realiza tras abrir el cursor:
• FETCH FIRST
Recopila la primera fila del cursor.
• FETCH NEXT
Recopila la primera fila del cursor.
• FETCH PRIOR
No recopila una fila.
• FETCH LAST

Material de estudio Página: 188 de 249


Visual Basic 6.0 y SQLServer 7.0

Recopila la última fila del cursor.


• FETCH ABSOLUTE n
Recopila la enésima fila a partir de la primera fila del cursor, si n es un entero positivo. Si
n es un entero negativo, se recopila la fila que está n filas delante del final del cursor (por
ejemplo, n = -1 devuelve la última fila del cursor). Si n es 0, no se recopila ninguna fila.
• FETCH RELATIVE n
Recopila la enésima fila del cursor, si n es positivo. No se recopila ninguna fila si n es
negativo o 0.
Los cursores de Transact-SQL están limitados a recopilar una fila cada vez. Los cursores de
servidor de la API admiten la recopilación de bloques de filas en cada recopilación. Un cursor que
admite la recopilación de varias filas a la vez recibe el nombre de cursor de bloque.
Clasificaciones de cursores
Se puede clasificar un cursor por las opciones de recopilación que admite:
• Desplazamiento sólo hacia delante
Se debe recopilar las filas en serie desde la primera a la última fila. FETCH NEXT es la
única operación de recopilación permitida.
• Desplazable
Se puede recopilar las filas aleatoriamente desde cualquier posición del cursor. Se
permiten todas las operaciones de recopilación (excepto que los cursores dinámicos no
admiten la recopilación absoluta).
Los cursores desplazables son especialmente útiles para las aplicaciones en pantalla. Se puede
asignar un cursor a una cuadrícula o cuadro de lista de la aplicación. A medida que el usuario se
desplaza hacia delante y hacia atrás en la cuadrícula, la aplicación utiliza recopilaciones de
desplazamiento para recopilar las filas del cursor que desea ver el usuario.

1.7.2 Tipos de cursores

ODBC, ADO y la biblioteca de bases de datos definen cuatro tipos de cursores que admite
Microsoft SQL Server . Con SQL Server versión 7.0, se ha ampliado la instrucción DECLARE
CURSOR para que pueda especificar cuatro tipos de cursor para cursores de Transact-SQL.
Estos cursores varían en su capacidad para detectar cambios en el conjunto de resultados y en
los recursos, como la memoria y espacio de tempdb, que consumen. Un cursor puede detectar
cambios en las filas sólo cuando intenta volver a recopilar dichas filas; no hay forma de que el
origen de datos notifique al cursor las modificaciones realizadas en las filas actualmente
recopiladas. La capacidad de un cursor para detectar las cambios también está influida por el
nivel de aislamiento de la transacción.
Los cuatro tipos de cursores de servidor de la API que admite SQL Server son:
• Cursores estáticos
• Cursores dinámicos
• Cursores de desplazamiento sólo hacia delante
• Cursores controlados por conjunto de claves
Los cursores estáticos detectan pocos o ningún cambio pero consumen relativamente pocos
recursos al desplazarse, aunque almacenan el cursor completo en tempdb. Los cursores
dinámicos detectan todos los cambios pero consumen más recursos al desplazarse, aunque
realizan el uso más ligero de tempdb. Los cursores controlados por conjunto de claves se
encuentran entre los anteriores: detectan la mayor parte de los cambios pero con un consumo
menor que los cursores dinámicos.
Aunque los modelos de cursor de la API de bases de datos consideran un cursor de
desplazamiento sólo hacia delante como un cursor de distinto tipo, SQL Server no hace esta
distinción. SQL Server considera que las opciones de desplazamiento sólo hacia delante y de
desplazamiento son las que se puede aplicar a los cursores estáticos, controlados por conjunto
de claves y dinámicos.

Material de estudio Página: 189 de 249


Visual Basic 6.0 y SQLServer 7.0

1.7.3 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 de SQL-92
DECLARE nombreCursor [INSENSITIVE] [SCROLL] CURSOR
FOR instrucciónSELECT
[FOR {READ ONLY | UPDATE [OF listaColumnas [,...n]]}]
Sintaxis extendida de Transact-SQL
DECLARE nombreCursor CURSOR
[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR instrucciónSELECT
[FOR UPDATE [OF nombreColumna [,...n]]]

Argumentos de SQL-92

nombreCursor : Se trata del nombre del cursor de servidor Transact-SQL que se va a


definir. El argumento nombreCursor debe seguir las reglas de los identificadores.
INSENSITIVE :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
tanto, las modificaciones realizadas en las tablas base no se reflejarán en los datos
devueltos por las recuperaciones realizadas en el cursor y además el cursor no admite
modificaciones. Cuando se utiliza la sintaxis de SQL-92, si se omite INSENSITIVE, las
eliminaciones y actualizaciones confirmadas realizadas en las tablas subyacentes (por
cualquier usuario) se reflejan en las siguientes recuperaciones.
SCROLL : Especifica que están disponibles todas las opciones de recuperación (FIRST,
LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE). Si no se especifica SCROLL en una
instrucción DECLARE CURSOR de SQL-92, la única opción de recuperación que se
admite es NEXT. No se puede especificar SCROLL si se especifica también
FAST_FORWARD.
instrucciónSELECT : Es una instrucción SELECT estándar que define el conjunto de
resultados del cursor. Las palabras clave COMPUTE, COMPUTE BY, FOR BROWSE e

Material de estudio Página: 190 de 249


Visual Basic 6.0 y SQLServer 7.0

INTO no están permitidas en el argumento instrucciónSELECT de una declaración de


cursor.
Microsoft SQL Server convierte implícitamente el cursor a otro tipo si las cláusulas
de instrucciónSELECT entran en conflicto con la funcionalidad del tipo de cursor
solicitado.
READ ONLY : Impide que se realicen actualizaciones a través de este cursor. No es
posible hacer referencia al cursor en una cláusula WHERE CURRENT OF de una
instrucción UPDATE o DELETE. Esta opción anula la posibilidad predeterminada de
actualizar el cursor.

UPDATE [OF nombreColumna [,...n]] :Define las columnas del cursor que se pueden
actualizar. Si se especifica el argumento OF nombreColumna [,...n], sólo se podrán
modificar las columnas incluidas en la lista. Si se especifica el argumento UPDATE sin
una lista de columnas, se pueden actualizar todas las columnas.
Argumentos extendidos de Transact-SQL

nombreCursor :Se trata del nombre del cursor de servidor Transact-SQL que se va a
definir. El argumento nombreCursor debe seguir las reglas de los identificadores.
LOCAL :Especifica que el alcance del cursor es local para el proceso por lotes,
procedimiento almacenado o desencadenador en que se creó el cursor. El nombre del
cursor sólo es válido dentro de este alcance. Es posible hacer referencia al cursor mediante
variables de cursor locales del proceso por lotes, procedimiento almacenado,
desencadenador o parámetro OUTPUT del procedimiento almacenado. El parámetro
OUTPUT se utiliza para devolver el cursor local al proceso por lotes, procedimiento
almacenado o desencadenador que realiza la llamada, el cual puede asignar el parámetro a
una variable de cursor para hacer referencia al cursor después de finalizar el
procedimiento almacenado. La asignación del cursor se cancela implícitamente cuando el
proceso por lotes, procedimiento almacenado o desencadenador finalizan, a menos que el
cursor se haya devuelto en un parámetro OUTPUT. En ese caso, se cancela la asignación
del cursor cuando se cancela la asignación de la última variable que le hace referencia o
ésta se sale del alcance.
GLOBAL : Especifica que el alcance del cursor es global para la conexión. Puede hacerse
referencia al nombre del cursor en cualquier procedimiento almacenado o proceso por
lotes que se ejecute durante la conexión. Sólo se cancela implícitamente la asignación del
cursor cuando se realiza la desconexión.

Nota Si no se especifica GLOBAL o LOCAL, el valor predeterminado se controla mediante la


configuración de la opción de base de datos cursor local como predeterminado. En SQL Server
versión 7.0, el valor predeterminado de esta opción es FALSE (falso) para que coincida con las
versiones anteriores de SQL Server, donde todos los cursores eran globales. El valor
predeterminado de esta opción puede cambiar en futuras versiones de SQL Server..

Material de estudio Página: 191 de 249


Visual Basic 6.0 y SQLServer 7.0

FORWARD_ONLY :Especifica que el cursor sólo se puede desplazar desde la primera a


la última fila. FETCH NEXT es la única opción de recuperación aceptada. Si se especifica
FORWARD_ONLY sin las palabras clave STATIC, KEYSET o DYNAMIC, el cursor
funciona como un cursor DYNAMIC. Cuando no se especifica FORWARD_ONLY ni
SCROLL, FORWARD_ONLY es la opción predeterminada, salvo si se incluyen las
palabras clave STATIC, KEYSET o DYNAMIC. De forma predeterminada, con STATIC,
KEYSET y DYNAMIC los cursores son de tipo SCROLL. A diferencia de las API de
bases de datos como ODBC y ADO, FORWARD_ONLY se puede utilizar con los
cursores STATIC, KEYSET y DYNAMIC de Transact-SQL. FAST_FORWARD y
FORWARD_ONLY se excluyen mutuamente; si se especifica uno de ellos, no se puede
especificar el otro.
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 tanto, las
modificaciones realizadas en las tablas base no se reflejarán en los datos devueltos por las
recuperaciones realizadas en el cursor y además el cursor no admite modificaciones.
KEYSET : Especifica que la pertenencia y el orden de las filas del cursor se fijan al abrir
éste. El conjunto de claves que identifica de forma única las filas está integrado en una
tabla de tempdb conocida como keyset. Los cambios en valores que no sean claves de las
tablas base, ya sean realizados por el propietario del cursor o confirmados por otros
usuarios, son visibles cuando el propietario se desplaza por el cursor. Las inserciones
realizadas por otros usuarios no son visibles (no es posible hacer inserciones a través de un
cursor de servidor Transact-SQL). Si se elimina una fila, el intento de recuperarla obtendrá
un valor de -2 en @@FETCH_STATUS. Las actualizaciones de los valores de claves
desde fuera del cursor se asemejan a la eliminación de la fila antigua seguida de la
inserción de la nueva. La fila con los nuevos valores no es visible y los intentos de
recuperar la fila de los valores antiguos devuelven el valor -2 en @@FETCH_STATUS.
Los nuevos valores son visibles si la actualización se realiza a través del cursor, al
especificar la cláusula WHERE CURRENT OF.
DYNAMIC :Define un cursor que, al desplazarse por él, refleja en su conjunto de
resultados todos los cambios realizados en los datos de las filas. Los valores de los datos,
el orden y la pertenencia de las filas pueden cambiar en cada recuperación. La opción de
recuperación ABSOLUTE no se puede utilizar en los cursores dinámicos.
FAST_FORWARD : Especifica un cursor FORWARD_ONLY, READ_ONLY con las
optimizaciones de rendimiento habilitadas. No se puede especificar FAST_FORWARD si
se especifica también SCROLL o FOR_UPDATE. FAST_FORWARD y
FORWARD_ONLY se excluyen mutuamente; si se especifica uno de ellos, no se puede
especificar el otro.
READ_ONLY :Impide que se realicen actualizaciones a través de este cursor. No es
posible hacer referencia al cursor en una cláusula WHERE CURRENT OF de una
instrucción UPDATE o DELETE. Esta opción anula la posibilidad predeterminada de
actualizar el cursor.

Material de estudio Página: 192 de 249


Visual Basic 6.0 y SQLServer 7.0

SCROLL_LOCKS :Especifica que el éxito de las actualizaciones o eliminaciones con


posición, realizadas a través del cursor, está garantizado. Microsoft SQL Server bloquea
las filas al leerlas en el cursor, lo que asegura su disponibilidad para posteriores
modificaciones. No se puede especificar SCROLL_LOCKS si se especifica
FAST_FORWARD.
OPTIMISTIC :Especifica que las actualizaciones o eliminaciones con posición realizadas
a través del cursor no tendrán éxito si la fila se ha actualizado después de leerla en el
cursor. SQL Server no bloquea las filas al leerlas en el cursor. En su lugar, utiliza
comparaciones de valores de columna timestamp o un valor de suma de comprobación si
la tabla no tiene columnas timestamp, para determinar si la fila se ha modificado después
de leerla en el cursor. Si la fila se ha modificado, la actualización o eliminación con
posición fracasa. No se puede especificar OPTIMISTIC si se especifica
FAST_FORWARD.
TYPE_WARNING :Especifica que se envía un mensaje de advertencia al cliente si el
cursor se convierte implícitamente del tipo solicitado a otro.
instrucciónSELECT : Es una instrucción SELECT estándar que define el conjunto de
resultados del cursor. Las palabras clave COMPUTE, COMPUTE BY, FOR BROWSE e
INTO no están permitidas en el argumento instrucciónSELECT de una declaración de
cursor.
SQL Server convierte implícitamente el cursor a otro tipo si las cláusulas de
instrucciónSELECT entran en conflicto con la funcionalidad del tipo de cursor
solicitado.
UPDATE [OF nombreColumna [,...n]] : Define las columnas del cursor que se pueden
actualizar. Si se especifica el argumento OF nombreColumna [,...n], sólo se podrán
modificar las columnas incluidas en la lista. Si se especifica el argumento UPDATE sin
una lista de columnas, se pueden actualizar todas las columnas, a menos que se haya
especificado la opción de simultaneidad READ_ONLY.
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.
La primera forma de la instrucción DECLARE CURSOR utiliza la sintaxis de SQL-92 para declarar
comportamientos de cursores. La segunda forma de DECLARE CURSOR utiliza extensiones de
Transact-SQL que permiten definir cursores con los mismos tipos de cursor utilizados en las
funciones de cursores de la API de bases de datos de ODBC, ADO y Bibliotecas de bases de
datos.
No puede combinar las dos formas. Si especifica las palabras clave SCROLL o INSENSITIVE
antes de la palabra clave CURSOR, no puede utilizar ninguna palabra clave entre los argumentos
CURSOR y FOR instrucciónSELECT. Si especifica palabras clave entre los argumentos
CURSOR y FOR instrucciónSELECT, no puede especificar SCROLL o INSENSITIVE antes de la
palabra clave CURSOR.

Material de estudio Página: 193 de 249


Visual Basic 6.0 y SQLServer 7.0

Si la instrucción DECLARE CURSOR con sintaxis de Transact-SQL no especifica READ_ONLY,


OPTIMISTIC o SCROLL_LOCKS, el valor predeterminado es el siguiente:
• Si la instrucción SELECT no acepta actualizaciones (permisos insuficientes, acceso a
tablas remotas que no aceptan actualizaciones, etc.), el cursor es de tipo READ_ONLY.
• El valor predeterminado de los cursores de tipo STATIC y FAST_FORWARD es
READ_ONLY.
• El valor predeterminado de los cursores de tipo KEYSET y DYNAMIC es OPTIMISTIC.
Sólo se puede hacer referencia a nombres de cursores mediante otras instrucciones Transact-
SQL. No se puede hacer referencia a los nombres de cursores mediante funciones de la API de
base de datos. Por ejemplo, después de declarar un cursor, no se puede hacer referencia al
nombre del cursor desde funciones o métodos de OLE DB, ODBC, ADO o Bibliotecas de bases
de datos. No se pueden recuperar las filas del cursor con las funciones o métodos de
recuperación de las API; las filas sólo se pueden recuperar mediante instrucciones FETCH de
Transact-SQL.
Una vez que se ha declarado un cursor, se pueden utilizar estos procedimientos almacenados del
sistema para determinar las características del cursor.
Procedimiento almacenado
Descripción
del sistema
Devuelve la lista de cursores visibles actualmente en la conexión y sus
sp_cursor_list
atributos.
Describe los atributos de un cursor, por ejemplo si es de desplazamiento
sp_describe_cursor
sólo hacia delante o de desplazamiento.
Describe los atributos de las columnas del conjunto de resultados del
sp_describe_cursor_columns
cursor.
sp_describe_cursor_tables Describe las tablas base a las que tiene acceso el cursor.
Permisos
Los permisos de DECLARE CURSOR son los predeterminados de cualquier usuario que tenga
permisos de SELECT sobre las vistas, tablas y columnas utilizadas en el cursor.
Ejemplos

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

Material de estudio Página: 194 de 249


Visual Basic 6.0 y SQLServer 7.0

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
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

1.7.4 Bloqueo de cursores

En la versión 7.0 de Microsoft SQL Server, la instrucción SELECT de la definición de un cursor


está sujeta a las mismas reglas de bloqueo de transacciones que se aplican a cualquier otra
instrucción SELECT. Sin embargo, en los cursores se puede adquirir un conjunto adicional de
bloqueos de desplazamiento en función del grado de simultaneidad de un cursor.
Los bloqueos de transacciones que adquiere una instrucción SELECT, incluyendo la instrucción
SELECT de la definición de un cursor, se controlan mediante:
• La configuración del nivel de aislamiento de transacciones de la conexión.
• Las sugerencias de bloqueo especificadas en la cláusula FROM.
Estos bloqueos se mantienen hasta el final de la transacción actual para los cursores y las
instrucciones SELECT independientes. Cuando SQL Server se ejecuta en modo de confirmación
automática, cada instrucción de SQL individual es una transacción y los bloqueos se liberan

Material de estudio Página: 195 de 249


Visual Basic 6.0 y SQLServer 7.0

cuando termina la instrucción. Si SQL Server se ejecuta en el modo de transacciones explícitas o


implícitas, se mantienen los bloqueos hasta que la transacción se confirma o deshace.
Por ejemplo, el bloqueo realizado en estos dos ejemplos de Transact-SQL es esencialmente el
mismo:
/* Example 1 */
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRANSACTION
GO
SELECT * FROM authors
GO
/* Example 2 */
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRANSACTION
GO
DECLARE abc CURSOR STATIC FOR
SELECT * FROM authors
GO
OPEN abc
GO
Establecer el nivel de aislamiento de transacciones como lectura repetible significa que la
instrucción SELECT independiente del ejemplo 1 y la instrucción SELECT que contiene
DECLARE CURSOR en el ejemplo 2 generan bloqueos compartidos en cada fila que leen y que
se mantienen los bloqueos compartidos hasta que la transacción se confirma o se deshace.
Adquirir bloqueos
Aunque los cursores obedecen las mismas reglas que las instrucciones SELECT independientes
acerca del tipo de bloqueos de transacciones adquiridos, éstos se adquieren en momentos
diferentes. Los bloqueos que genera una instrucción SELECT independiente o un cursor siempre
se adquieren cuando se recupera una fila. Para una instrucción SELECT independiente, todas las
filas se recuperan cuando se ejecuta la instrucción. Sin embargo, los cursores recuperan las filas
en momentos diferentes según el tipo de cursor:
• Los cursores estáticos recuperan el conjunto de resultados completo en el momento en
que se abre el cursor. Así se bloquea cada fila del conjunto de resultados en el momento
de la apertura.
• Los cursores controlados por conjunto de claves recuperan las claves de cada fila del
conjunto de resultados en el momento en que se abre el cursor. Así se bloquea cada fila
del conjunto de resultados en el momento de la apertura.
• Los cursores dinámicos, incluidos los cursores normales de desplazamiento sólo hacia
adelante, no recuperan las filas hasta que se recopilan. Los bloqueos no se adquieren en
estas filas hasta que se han recopilado.
• Los cursores de desplazamiento rápido sólo adelante se diferencian en que adquieren sus
bloqueos dependiendo del plan de ejecución seleccionado por el optimizador de
consultas. Si se selecciona un plan dinámico, no se adquieren bloqueos hasta que se
recopilan las filas. Si se generan tablas de trabajo, las filas se leen en la tabla de trabajo y
se bloquean en el momento de la apertura.
Los cursores también admiten sus propias especificaciones de simultaneidad, algunas de las
cuales generan bloqueos adicionales en las filas en cada recopilación. Estos bloqueos de
desplazamiento se mantienen hasta la siguiente operación de recopilación o hasta que el cursor
está cerrado, lo que se produzca primero. Si la opción de conexión para mantener cursores
abiertos en una confirmación está activada, estos bloqueos se mantienen en las operaciones de
confirmar o de deshacer.

Material de estudio Página: 196 de 249


Visual Basic 6.0 y SQLServer 7.0

1.7.5 Obtener metadatos de cursores de servidor

Hay dos formas de obtener metadatos que describen un cursor de servidor:


• Las aplicaciones que utilizan cursores de servidor de la API con una API de bases de
datos como ADO, OLE DB, ODBC o bibliotecas de bases de datos, normalmente utilizan
la funcionalidad de cursores de la API para obtener información acerca del estado del
cursor.
• Las secuencias de comandos, procedimientos almacenados y desencadenadores de
Transact-SQL pueden utilizar las funciones de Transact-SQL y procedimientos
almacenados del sistema explicados en este tema para obtener información acerca de un
cursor de Transact-SQL.
Hay varias funciones del sistema que informan del estado de un cursor de servidor o de un cursor
de servidor asignado a una variable de tipo cursor:
• CURSOR_STATUS
Indica si un cursor está abierto o cerrado, o si una variable de tipo cursor está asociada
actualmente a un cursor.
• @@FETCH_STATUS
Indica el éxito o el error de la última operación de recopilación realizada en la conexión.
• @@CURSOR_ROWS
Devuelve el número de filas llenadas en el último cursor abierto en la conexión.
Hay varios procedimientos almacenados del sistema que informan de las características de un
cursor de servidor o de un cursor de servidor asignado a una variable de tipo cursor:
• sp_describe_cursor
Devuelve un cursor que describe los atributos de un cursor como su alcance, nombre,
tipo, estado y número de filas.
• sp_describe_cursor_columns
Devuelve un cursor que describe los atributos de cada columna del cursor, como el
nombre de la columna, posición, tamaño y tipo de datos.
• sp_describe_cursor_tables
Devuelve un cursor que describe las tablas base a las que hace referencia el cursor.
• sp_cursor_list
Devuelve un cursor que enumera todos los cursores actualmente visibles de la conexión.
El formato del cursor que devuelve sp_cursor_list es el mismo que el del cursor de
sp_describe_cursor.
Estos procedimientos almacenados del sistema devuelven sus conjuntos de resultados como
variables de cursores de salida. Las API de bases de datos no admiten variables de tipo cursor,
por lo que no se puede llamar a estos procedimientos desde aplicaciones, solamente desde
secuencias de comandos, procedimientos almacenados y lotes de Transact-SQL. Las
aplicaciones deben utilizar la funcionalidad de cursor de las API de bases de datos para obtener
los metadatos de los cursores de servidor de la API.
Se debe tratar cuidadosamente la información de estado que devuelven estas funciones y
procedimientos almacenados, especialmente @@FETCH_STATUS. La información que devuelve
@@FETCH_STATUS cambia cada vez que se emite una instrucción FETCH contra cualquier
cursor abierto en la conexión. Un procedimiento almacenado o desencadenador que pueda
necesitar hacer referencia a la información de estado tras ejecutar varias instrucciones
adicionales debe guardar @@FETCH_STATUS en una variable de tipo integer inmediatamente
después de la instrucción FETCH. Se puede restablecer @@FETCH_STATUS aunque no haya
instrucciones FETCH en el lote entre la instrucción FETCH y la instrucción que prueba el estado.
Si una instrucción INSERT, UPDATE o DELETE activa un desencadenador, éste puede abrir y
recopilar desde un cursor. @@FETCH_STATUS contendría entonces el estado de la última
instrucción FETCH del desencadenador.
Los procedimientos almacenados informan de su propio estado para un cursor específico, por lo
que su información de estado no se ve afectada por las operaciones de otros cursores. Esta
información sigue afectada por las operaciones realizadas en el mismo cursor, por lo que se debe

Material de estudio Página: 197 de 249


Visual Basic 6.0 y SQLServer 7.0

tener cuidado todavía al utilizar la información de estado que devuelven los procedimientos
almacenados.

1.8 Procedimientos almacenados


Un procedimiento almacenado es un grupo de instrucciones Transact-SQL compiladas en un
único plan de ejecución.
Los procedimientos almacenados de Microsoft SQL Server tienen cuatro maneras de devolver
datos:
• Parámetros de salida, que pueden devolver datos (como valor entero o carácter) o una
variable de cursor (los cursores son conjuntos de resultados que pueden devolver filas de
una en una).
• Códigos de retorno, que siempre son un valor entero.
• Un conjunto de resultados por cada instrucción SELECT contenida en el procedimiento
almacenado o en cualquier otro procedimiento almacenado invocado por el procedimiento
almacenado original.
• Un cursor global al que se puede hacer referencia desde fuera del procedimiento
almacenado.
Los procedimientos almacenados contribuyen a conseguir una implementación coherente de una
lógica entre las aplicaciones. Las instrucciones SQL y la lógica necesarias para ejecutar una tarea
de ejecución frecuente se pueden diseñar, escribir y probar de una sola vez en un procedimiento
almacenado. Así, las aplicaciones que necesiten ejecutar dicha tarea sólo tienen que ejecutar el
procedimiento almacenado. La escritura de la lógica de una función en un solo procedimiento
almacenado también ofrece un único punto de control para asegurar la correcta ejecución de
dicha función.
Los procedimientos almacenados también pueden aumentar el rendimiento. Muchas tareas están
implementadas como series de instrucciones SQL. La lógica condicional aplicada a los resultados
de la primeras instrucciones SQL determina las instrucciones SQL que se ejecutan seguidamente.
Si dichas instrucciones SQL y la lógica condicional se escriben en un procedimiento almacenado,
forman parte de una única unidad de ejecución en el servidor. No es necesario devolver los
resultados al cliente para aplicar la lógica condicional; todo el trabajo se realiza en el servidor. La
instrucción IF de este ejemplo muestra la inclusión de lógica condicional en un procedimiento para
impedir el envío de un conjunto de resultados a la aplicación:

IF (@QuantityOrdered < (SELECT QuantityOnHand


FROM Inventory
WHERE PartID = @PartOrdered) )
BEGIN
-- SQL statements to update tables and process order.
END
ELSE
BEGIN
-- SELECT statement to retrieve the IDs of alternate items
-- to suggest as replacements to the customer.
END
Las aplicaciones no tienen que transmitir todas las instrucciones SQL del procedimiento: sólo
tienen que transmitir una instrucción EXECUTE o CALL que contenga el nombre del
procedimiento y los valores de los parámetros.
Los procedimientos almacenados también aíslan a los usuarios de los detalles de las tablas de la
base de datos. Si un conjunto de procedimientos almacenados implementa todas las funciones
que los usuarios necesitan, los usuarios nunca tienen que tener acceso a las tablas de forma
directa; sólo tienen que ejecutar los procedimientos almacenados que implementan las funciones
diarias de su trabajo.

Material de estudio Página: 198 de 249


Visual Basic 6.0 y SQLServer 7.0

Una ilustración de este uso de los procedimientos almacenados es el sistema de procedimientos


almacenados que SQL Server utiliza para aislar a los usuarios de las tablas del sistema. SQL
Server incluye un conjunto de procedimientos almacenados del sistema cuyos nombres suelen
empezar por sp_. Dichos procedimientos almacenados del sistema aceptan todas las tareas
administrativas requeridas para ejecutar un sistema SQL Server. Los sistemas SQL Server se
pueden administrar mediante las instrucciones Transact-SQL destinadas a la administración
(como CREATE TABLE) o los procedimientos almacenados del sistema, y nunca se tienen que
actualizar directamente las tablas del sistema.
En versiones anteriores de SQL Server, los procedimientos almacenados eran una forma de
precompilar parcialmente un plan de ejecución. En el momento de la creación del procedimiento
almacenado, se almacenaba un plan de ejecución parcialmente compilado en una tabla del
sistema. La ejecución de un procedimiento almacenado era más eficiente que la ejecución de una
instrucción SQL, ya que SQL Server no tenía que compilar el plan de ejecución; sólo tenía que
completar la optimización del plan de ejecución del procedimiento. Además, el plan de ejecución
totalmente compilado del procedimiento almacenado se conservaba en la caché de
procedimientos de SQL Server, lo que significa que las siguientes ejecuciones del mismo
procedimiento almacenado podían utilizar el plan de ejecución precompilado.
SQL Server versión 7.0 introduce varios cambios al proceso de instrucciones que amplían
muchas de las ventajas de rendimiento de los procedimientos almacenados a todas las
instrucciones SQL. SQL Server 7.0 no guarda un plan parcialmente compilado para los
procedimientos almacenados cuando éstos se crean. El procedimiento almacenado se compila en
tiempo de ejecución como cualquier otra instrucción Transact-SQL. SQL Server 7.0 mantiene los
planes de ejecución de todas las instrucciones SQL en la caché de procedimientos, no sólo los
planes de ejecución de los procedimientos almacenados. Utiliza un algoritmo muy eficiente para
comparar nuevas instrucciones Transact-SQL con las instrucciones Transact-SQL de los planes
de ejecución existentes. Si SQL Server 7.0 determina que una nueva instrucción Transact-SQL
coincide con una instrucción Transact-SQL de un plan de ejecución existente, utiliza dicho plan.
Esto reduce la ventaja de rendimiento relativa de la precompilación de los procedimientos
almacenados al ampliar la posibilidad de volver a utilizar los planes de ejecución a todas las
instrucciones SQL.
SQL Server 7.0 ofrece nuevas alternativas para procesar instrucciones SQL. SQL Server también
acepta procedimientos almacenados temporales que, al igual que las tablas temporales, se
eliminan automáticamente al desconectar. Los procedimientos almacenados temporales se
almacenan en tempdb y son útiles en las conexiones con versiones anteriores de SQL Server.
Los procedimientos almacenados temporales se pueden utilizar en el caso en el que una
aplicación genere instrucciones Transact-SQL dinámicas que se ejecuten varias veces. En lugar
de tener que volver a compilar las instrucciones Transact-SQL todas las veces, puede crear un
procedimiento almacenado temporal, que se compila en su primera ejecución, y el resto de las
veces ejecuta el plan precompilado. Sin embargo, el uso intensivo de procedimientos
almacenados temporales puede producir conflictos en las tablas del sistema de tempdb.
Sin embargo, dos características de SQL Server 7.0 eliminan la necesidad de utilizar
procedimientos almacenados temporales:
• SQL Server 7.0 puede utilizar planes de ejecución de instrucciones SQL anteriores. Esto
es especialmente eficaz cuando se utiliza junto con el nuevo procedimiento almacenado
del sistema sp_executesql.
• SQL Server 7.0 acepta de forma nativa el modelo de preparación y ejecución de OLE DB
y ODBC sin el uso de procedimientos almacenados.

Este sencillo procedimiento almacenado de ejemplo ilustra tres formas en que los procedimientos
almacenados pueden devolver datos:
1. Primero emite una instrucción SELECT que devuelve un conjunto de resultados que
resume el orden de actividad de los almacenes de la tabla sales.
2. Después emite una instrucción SELECT que asigna un parámetro de salida.
3. Por último, tiene una instrucción RETURN con una instrucción SELECT que devuelve un
valor entero. Los códigos de retorno se utilizan generalmente para devolver información

Material de estudio Página: 199 de 249


Visual Basic 6.0 y SQLServer 7.0

para la comprobación de errores. Este procedimiento se ejecuta sin errores, de modo que
devuelve otro valor para ilustrar cómo se asignan los códigos de retorno.
USE Northwind
GO
DROP PROCEDURE OrderSummary
GO
CREATE PROCEDURE OrderSummary @MaxQuantity INT OUTPUT AS
-- SELECT to return a result set summarizing
-- employee sales.
SELECT Ord.EmployeeID, SummSales = SUM(OrDet.UnitPrice * OrDet.Quantity)
FROM Orders AS Ord
JOIN [Order Details] AS OrDet ON (Ord.OrderID = OrDet.OrderID)
GROUP BY Ord.EmployeeID
ORDER BY Ord.EmployeeID
-- SELECT to fill the output parameter with the
-- maximum quantity from Order Details.
SELECT @MaxQuantity = MAX(Quantity) FROM [Order Details]
-- Return the number of all items ordered.
RETURN (SELECT SUM(Quantity) FROM [Order Details])
GO
-- Test the stored procedure.
-- DECLARE variables to hold the return code
-- and output parameter.
DECLARE @OrderSum INT
DECLARE @LargestOrder INT
-- Execute the procedure, which returns
-- the result set from the first SELECT.
EXEC @OrderSum = OrderSummary @MaxQuantity = @LargestOrder OUTPUT
-- Use the return code and output parameter.
PRINT 'The size of the largest single order was: ' +
CONVERT(CHAR(6), @LargestOrder)
PRINT 'The sum of the quantities ordered was: ' +
CONVERT(CHAR(6), @OrderSum)
GO
El resultado de la ejecución de este ejemplo es:
EmployeeID SummSales
----------- --------------------------
1 202,143.71
2 177,749.26
3 213,051.30
4 250,187.45
5 75,567.75
6 78,198.10
7 141,295.99
8 133,301.03
9 82,964.00
The size of the largest single order was: 130
The sum of the quantities ordered was: 51317

1.8.1 Programar procedimientos almacenados


Casi cualquier código Transact-SQL que pueda escribirse como un lote puede utilizarse para
crear un procedimiento almacenado.

Material de estudio Página: 200 de 249


Visual Basic 6.0 y SQLServer 7.0

Reglas de procedimientos almacenados


Entre las reglas para la programación de procedimientos almacenados, cabe citar las siguientes:
• La propia definición CREATE PROCEDURE puede incluir cualquier número y tipo de
instrucciones SQL, excepto las siguientes instrucciones CREATE, que no pueden ser
utilizadas nunca dentro de un procedimiento almacenado:
CREATE DEFAULT CREATE TRIGGER
CREATE PROCEDURE CREATE VIEW
CREATE RULE
• Se puede crear otros objetos de base de datos dentro de un procedimiento almacenado.
Puede hacer referencia a un objeto creado en el mismo procedimiento almacenado,
siempre que se cree antes de que se haga referencia al objeto.
• Puede hacer referencia a tablas temporales dentro de un procedimiento almacenado.
• Si crea una tabla temporal privada dentro de un procedimiento almacenado, la tabla
temporal existirá únicamente para los fines del procedimiento; desaparecerá cuando éste
finalice.
• Si ejecuta un procedimiento almacenado que llama a otro procedimiento almacenado, el
procedimiento al que se llama puede tener acceso a todos los objetos creados por el
primer procedimiento, incluidas las tablas temporales.
• Si se ejecuta un procedimiento almacenado remoto que realiza cambios en un servidor
Microsoft® SQL Server™ remoto, los cambios no se podrán deshacer. Los
procedimientos almacenados remotos no intervienen en las transacciones.
• El número máximo de parámetros en un procedimiento almacenado es de 1.024.
• El número máximo de variables locales en un procedimiento almacenado está limitado
únicamente por la memoria disponible.
• En función de la memoria disponible, el tamaño máximo de un procedimiento almacenado
es de 128 MB.
Calificar nombres dentro de procedimientos almacenados
Dentro de un procedimiento almacenado, los nombres de los objetos utilizados en instrucciones
(por ejemplo, SELECT o INSERT) que no sean calificados por el usuario se califican de forma
predeterminada con el nombre del propietario del procedimiento almacenado. Si un usuario que
crea un procedimiento almacenado no califica el nombre de las tablas a las que se hace
referencia en las instrucciones SELECT, INSERT, UPDATE o DELETE dentro del procedimiento
almacenado, de forma predeterminada, el acceso a esas tablas a través del procedimiento
almacenado se restringe al creador del procedimiento.
Los nombres de objetos utilizados con las instrucciones ALTER TABLE, CREATE TABLE, DROP
TABLE, TRUNCATE TABLE, CREATE INDEX, DROP INDEX, UPDATE STATISTICS y DBCC
deben ser calificados con el nombre del propietario del objeto, si otros usuarios van a utilizar el
procedimiento almacenado. Por ejemplo, Marisa, propietaria de la tabla marisatab, debe calificar
el nombre de su tabla cuando se utiliza con una de estas instrucciones, si desea que otros
usuarios puedan ejecutar el procedimiento almacenado en el que se utiliza la tabla.
Esta regla es necesaria porque los nombres de los objetos se resuelven cuando se ejecuta el
procedimiento almacenado. Si marisatab no está calificada y Juan intenta ejecutar el
procedimiento, SQL Server buscará una tabla denominada marisatab que pertenezca a Juan.
Cifrar definiciones de procedimientos
Si está creando un procedimiento almacenado y desea asegurarse de que la definición del
procedimiento no pueda ser vista por otros usuarios, puede utilizar la cláusula WITH
ENCRYPTION. La definición del procedimiento se almacenará en un formato ilegible.
Después de cifrarla, la definición del procedimiento almacenado no puede ser descifrada ni vista
por nadie, ni siquiera por el propietario del procedimiento ni por el administrador del sistema.
Instrucción SET
Cuando se conecta una aplicación ODBC a SQL Server, el servidor configura automáticamente
estas opciones para la sesión:

Material de estudio Página: 201 de 249


Visual Basic 6.0 y SQLServer 7.0

• SET QUOTED_IDENTIFIER ON
• SET TEXTSIZE 2147483647
• SET ANSI_DEFAULTS ON
• SET CURSOR_CLOSE_ON_COMMIT OFF
• SET IMPLICIT_TRANSACTIONS OFF
Esta configuración aumenta la portabilidad de las aplicaciones ODBC. Dado que las aplicaciones
basadas en bibliotecas de bases de datos no suelen configurar estas opciones, se debe probar
los procedimientos almacenados mediante la activación y desactivación de las opciones SET
citadas anteriormente. De ese modo se garantiza que los procedimientos almacenados funcionen
correctamente, independientemente de las opciones que haya configurado una conexión
determinada cuando invoca al procedimiento. Un procedimiento almacenado que necesite una
configuración determinada para una de estas opciones deberá emitir una instrucción SET al
principio del procedimiento almacenado. Esta instrucción SET tendrá efecto únicamente durante
la ejecución del procedimiento almacenado; cuando finalice el procedimiento, se restaurará la
configuración original.
Ejemplos

A. Crear un procedimiento almacenado que utilice parámetros


En este ejemplo se muestra cómo crear un procedimiento almacenado de gran utilidad para la
base de datos pubs. A partir del nombre y primer apellido de un autor, el procedimiento muestra
el título y el editor de cada uno de los libros del autor:
CREATE PROC au_info @lastname varchar(40), @firstname varchar(20)
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors INNER JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
JOIN publishers ON titles.pub_id = publishers.pub_id
WHERE au_fname = @firstname
AND au_lname = @lastname
GO
Se obtiene un mensaje que indica que el comando no devolvió ningún dato ni ninguna fila, lo que
significa que se ha creado el procedimiento almacenado.
Ahora, ejecute au_info:
EXECUTE au_info Ringer, Anne
GO
Éste es el conjunto de resultados:
au_lname au_fname title pub_name
--------- --------- --------------------- ----------------
Ringer Anne The Gourmet Microwave Binnet & Hardley
Ringer Anne Is Anger the Enemy? New Moon Books
(2 row(s) affected)
B. Crear un procedimiento almacenado que utilice valores predeterminados para los parámetros
El procedimiento almacenado pub_info2 muestra los nombres de todos los autores que han
escrito algún libro publicado por el editor que se especifica como parámetro. Si no se facilita
ningún nombre de editor, el procedimiento almacenado muestra los autores cuyos libros han sido
publicados por Algodata Infosystems.
CREATE PROC pub_info2 @pubname varchar(40) = 'Algodata Infosystems'
AS
SELECT au_lname, au_fname, pub_name
FROM authors a INNER JOIN titleauthor ta ON a.au_id = ta.au_id
JOIN titles t ON ta.title_id = t.title_id
JOIN publishers p ON t.pub_id = p.pub_id
WHERE @pubname = p.pub_name
Ejecute pub_info2 sin especificar ningún parámetro:

Material de estudio Página: 202 de 249


Visual Basic 6.0 y SQLServer 7.0

EXECUTE pub_info2
GO
Éste es el conjunto de resultados:
au_lname au_fname pub_name
---------------- ---------------- --------------------
Green Marjorie Algodata Infosystems
Bennet Abraham Algodata Infosystems
O'Leary Michael Algodata Infosystems
MacFeather Stearns Algodata Infosystems
Straight Dean Algodata Infosystems
Carson Cheryl Algodata Infosystems
Dull Ann Algodata Infosystems
Hunter Sheryl Algodata Infosystems
Locksley Charlene Algodata Infosystems
(9 row(s) affected)
C. Ejecutar un procedimiento almacenado que suplante al valor predeterminado para el parámetro
con un valor explícito
En el procedimiento almacenado showind2, se asignan los títulos como valores predeterminados
para el parámetro @table:
CREATE PROC showind2 @table varchar(30) = 'titles'
AS
SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes INNER JOIN sysobjects ON sysobjects.id = sysindexes.id
WHERE sysobjects.name = @table
Los títulos de las columnas (por ejemplo, TABLE_NAME) facilitan la lectura de los resultados.
Esto es lo que muestra el procedimiento almacenado para la tabla authors:
EXECUTE showind2 authors
GO
TABLE_NAME INDEX_NAME INDEX_ID
---------- ---------- ----------
authors UPKCL_auidind 1
authors aunmind 2
(2 row(s) affected)
Si el usuario no especifica ningún valor, SQL Server utiliza la tabla predeterminada, titles:
EXECUTE showind2
GO
Éste es el conjunto de resultados:
TABLE_NAME INDEX_NAME INDEX_ID
---------- ---------- ----------
titles UPKCL_titleidind 1
titles titleind 2
(2 row(s) affected)
D. Crear un procedimiento almacenado que utilice un valor predeterminado NULL para los
parámetros
El valor predeterminado para los parámetros puede ser NULL. En ese caso, si el usuario no
especifica ningún parámetro, SQL Server ejecutará el procedimiento almacenado de acuerdo con
el resto de sus instrucciones. No se muestra ningún mensaje de error.
La definición del procedimiento también puede especificar que se realice alguna otra acción si el
usuario no proporciona ningún parámetro. Por ejemplo:
CREATE PROC showind3 @table varchar(30) = NULL
AS IF @table IS NULL
PRINT 'Give a table name'

Material de estudio Página: 203 de 249


Visual Basic 6.0 y SQLServer 7.0

ELSE
SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes INNER JOIN sysobjects
ON sysobjects.id = sysindexes.id
WHERE sysobjects.name = @table
E. Crear un procedimiento almacenado que utilice un valor predeterminado para un parámetro que
incluya caracteres comodín
El valor predeterminado puede incluir caracteres comodín (%, _, [] y [^]), si el procedimiento
almacenado utiliza el parámetro con la palabra clave LIKE. Por ejemplo, es posible modificar
showind para que se muestre información acerca de las tablas del sistema, si el usuario no
especifica ningún parámetro:
CREATE PROC showind4 @table varchar(30) = 'sys%'
AS SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes INNER JOIN sysobjects
ON sysobjects.id = sysindexes.id
WHERE sysobjects.name LIKE @table
La siguiente variación del procedimiento almacenado au_info utiliza caracteres comodín como
valores predeterminados para ambos parámetros:
CREATE PROC au_info2 @lastname varchar(30) = 'D%',
@firstname varchar(18) = '%'
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors INNER JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
JOIN publishers ON titles.pub_id = publishers.pub_id
WHERE au_fname LIKE @firstname
AND au_lname LIKE @lastname
Si se ejecuta au_info2 sin parámetros, se muestran todos los autores cuyo apellido empiece por
la letra D:
EXECUTE au_info2
GO
Éste es el conjunto de resultados:
au_lname au_fname title pub_name
-------- -------- --------------------- -------------------
Dull Ann Secrets of Silicon Val Algodata Infosystems
del Castillo Innes Silicon Val Gastrono Binnet & Hardley
DeFrance Michel The Gourmet Microwave Binnet & Hardley
(3 row(s) affected)
En este ejemplo se omite el segundo parámetro cuando se han definido valores predeterminados
para dos parámetros, así que puede buscar los libros y los editores para todos los autores cuyo
apellido sea Ringer:
EXECUTE au_info2 Ringer
GO
au_lname au_fname title pub_name
--------- --------- ---------------------- ----------------
Ringer Anne The Gourmet Microwave Binnet & Hardley
Ringer Anne Is Anger the Enemy? New Moon Books
Ringer Albert Is Anger the Enemy? New Moon Books
Ringer Albert Life Without Fear New Moon Books
(4 row(s) affected)

Material de estudio Página: 204 de 249


Visual Basic 6.0 y SQLServer 7.0

1.8.1.1 Devolver datos de un procedimiento almacenado

Los procedimientos almacenados de Microsoft® SQL Server™ pueden devolver los datos de
cuatro formas distintas:
• Parámetros de salida, que pueden devolver datos (como valor entero o carácter) o una
variable de cursor (los cursores son conjuntos de resultados que pueden devolver filas de
una en una).
• Códigos de retorno, que siempre son un valor entero.
• Un conjunto de resultados por cada instrucción SELECT contenida en el procedimiento
almacenado o en cualquier otro procedimiento almacenado invocado por el procedimiento
almacenado original.
• Un cursor global al que se puede hacer referencia desde fuera del procedimiento
almacenado.

1.8.1.2 Devolver datos mediante parámetros OUTPUT

Si especifica la palabra clave OUTPUT para un parámetro de la definición del procedimiento, éste
podrá devolver el valor actual del parámetro al programa que lo llama cuando el procedimiento
termine. Para guardar el valor del parámetro en una variable que pueda utilizarse en el programa
que realiza la llamada, el programa debe utilizar la palabra clave OUTPUT cuando ejecute el
procedimiento almacenado.
Ejemplos
En el ejemplo siguiente se muestra un procedimiento almacenado con un parámetro de entrada y
otro de salida. El primer parámetro del procedimiento almacenado, @title, recibirá el valor de
entrada especificado por el programa que realiza la llamada, mientras que el segundo parámetro,
@ytd_sales, se utilizará para devolver el valor al programa que realiza la llamada. La instrucción
SELECT utiliza el parámetro @title para obtener el valor ytd_sales correcto y asigna ese valor al
parámetro de salida @ytd_sales.
CREATE PROCEDURE get_sales_for_title
@title varchar(80), -- This is the input parameter.
@ytd_sales int OUTPUT -- This is the output parameter.
AS
-- Get the sales for the specified title and
-- assign it to the output parameter.
SELECT @ytd_sales = ytd_sales
FROM titles
WHERE title = @title
RETURN
GO
El programa siguiente ejecuta el procedimiento almacenado con un valor para el parámetro de
entrada y guarda el valor de salida del procedimiento en la variable local @ytd_sales_for_title
del programa que efectúa la llamada.
-- Declare the variable to receive the output value of the procedure.
DECLARE @ytd_sales_for_title int
-- Execute the procedure with a title_id value
-- and save the output value in a variable.
EXECUTE get_sales_for_title
"Sushi, Anyone?", @ytd_sales = @ytd_sales_for_title OUTPUT
-- Display the value returned by the procedure.
PRINT 'Sales for "Sushi, Anyone?": ' +
convert(varchar(6),@ytd_sales_for_title)
GO
Sales for "Sushi, Anyone?": 4095

Material de estudio Página: 205 de 249


Visual Basic 6.0 y SQLServer 7.0

También es posible especificar los valores de entrada para los parámetros OUTPUT cuando se
ejecuta el procedimiento almacenado. Esto permite al procedimiento recibir un valor del programa
que realiza la llamada, cambiarlo o realizar operaciones con el valor, y devolver el nuevo valor al
programa que realiza la llamada. En el ejemplo anterior, es posible asignar un valor a la variable
@ytd_sales_for_title antes de ejecutar el procedimiento. La variable @ytd_sales contiene el
valor del parámetro en el cuerpo del procedimiento almacenado, y el valor de la variable
@ytd_sales se devuelve al programa que realiza la llamada cuando el procedimiento termina. A
esto se le suele denominar “capacidad de paso por referencia”.
Si especifica OUTPUT para un parámetro cuando ejecuta un procedimiento almacenado y el
parámetro no se define mediante OUTPUT en el procedimiento almacenado, se produce un
mensaje de error. Puede ejecutar un procedimiento con parámetros OUTPUT y no especificar
OUTPUT cuando se ejecute el procedimiento. No se devuelve ningún error, pero no podrá utilizar
el valor de salida en el programa que realiza la llamada.

1.8.2.2 Devolver datos mediante un código de retorno

Un procedimiento almacenado puede devolver un valor entero, denominado código de retorno,


para indicar el estado de ejecución de un procedimiento. Se especifica el código de retorno para
un procedimiento mediante la instrucción RETURN. Al igual que con los parámetros OUTPUT,
debe guardar el código de retorno en una variable cuando se ejecute el procedimiento
almacenado para utilizar su valor en el programa que realiza la llamada. Por ejemplo, la variable
de asignación @result del tipo de datos int se utiliza para almacenar el código de retorno del
procedimiento almacenado my_proc:
DECLARE @result int
EXECUTE @result = my_proc
Los códigos de retorno suelen utilizarse en los bloques de control de flujo dentro de los
procedimientos almacenados con el fin de establecer el valor del código de retorno para cada
situación de error posible. Puede utilizar la función @@ERROR después de una instrucción de
Transact-SQL para detectar si se ha producido un error durante la ejecución de una instrucción.
Ejemplos

A. Devolver otro código de retorno en función del tipo de error


En el ejemplo siguiente se muestra el procedimiento get_sales_for_title con un tratamiento
especial que establece valores de código de retorno especiales para distintos errores. En la tabla
se muestra el valor entero asignado por el procedimiento almacenado a cada error posible.
Valor Significado
0 Ejecución correcta.
1 No se ha especificado el valor del parámetro necesario.
2 Valor no válido para el parámetro.
3 Error al obtener el valor de ventas.
4 Valor de ventas NULL para el título.
CREATE PROCEDURE get_sales_for_title
-- This is the input parameter, with a default.
@title varchar(80) = NULL,
-- This is the output parameter.
@ytd_sales int OUTPUT
AS
-- Validate the @title parameter.
IF @title IS NULL
BEGIN
PRINT "ERROR: You must specify a title value."
RETURN(1)
END

Material de estudio Página: 206 de 249


Visual Basic 6.0 y SQLServer 7.0

ELSE
BEGIN
-- Make sure the title is valid.
IF (SELECT COUNT(*) FROM titles
WHERE title = @title) = 0
RETURN(2)
END
-- Get the sales for the specified title and
-- assign it to the output parameter.
SELECT @ytd_sales = ytd_sales
FROM titles
WHERE title = @title
-- Check for SQL Server errors.
IF @@ERROR <> 0
BEGIN
RETURN(3)
END
ELSE
BEGIN
-- Check to see if the ytd_sales value is NULL.
IF @ytd_sales IS NULL
RETURN(4)
ELSE
-- SUCCESS!!
RETURN(0)
END
GO
Si se utilizan de este modo los códigos de retorno, los programas que realicen llamadas podrán
detectar y tratar los errores que se produzcan cuando se ejecute el procedimiento.
B. Tratar los distintos códigos de error devueltos por un procedimiento almacenado
En este ejemplo se crea un programa que trata los códigos de retorno devueltos por el
procedimiento get_sales_for_title.
-- Declare the variables to receive the output value and return code --
of the procedure.
DECLARE @ytd_sales_for_title int, @ret_code INT
-- Execute the procedure with a title_id value
-- and save the output value and return code in variables.
EXECUTE @ret_code = get_sales_for_title
"Sushi, Anyone?",
@ytd_sales = @ytd_sales_for_title OUTPUT
-- Check the return codes.
IF @ret_code = 0
BEGIN
PRINT "Procedure executed successfully"
-- Display the value returned by the procedure.
PRINT 'Sales for "Sushi, Anyone?": ' +
CONVERT(varchar(6),@ytd_sales_for_title)
END
ELSE IF @ret_code = 1
PRINT "ERROR: No title_id was specified."
ELSE IF @ret_code = 2
PRINT "ERROR: An invalid title_id was specified."
ELSE IF @ret_code = 3
PRINT "ERROR: An error occurred getting the ytd_sales."
GO

Material de estudio Página: 207 de 249


Visual Basic 6.0 y SQLServer 7.0

1.8.2.3 Ejecutar un procedimiento almacenado

Cuando necesite ejecutar un procedimiento almacenado, utilice la instrucción EXECUTE de


Transact-SQL. Puede ejecutar un procedimiento almacenado sin necesidad de utilizar la palabra
clave EXECUTE, si el procedimiento almacenado es la primera instrucción del lote.
Es posible suministrar los valores de los parámetros si se escribe un procedimiento almacenado
que los acepte.

Nota Si especifica los parámetros con el formato @parámetro = valor, puede proporcionarlos en
cualquier orden. También puede omitir los parámetros para los que se hayan especificado valores
predeterminados. Si sólo especifica un parámetro con el formato @parámetro = valor, deberá
proporcionar todos los parámetros siguientes del mismo modo. Si no especifica los parámetros
con el formato @parámetro = valor, deberá especificarlos en el orden seguido en la instrucción
CREATE PROCEDURE.
Cuando ejecute un procedimiento almacenado, el servidor rechazará todos los parámetros que no
se incluyeran en la lista de parámetros durante la creación del procedimiento. No se aceptará
ningún parámetro pasado por referencia (el nombre del parámetro se pasa explícitamente) si el
nombre del parámetro no coincide.
Aunque puede omitir los parámetros para los que se hayan especificado valores
predeterminados, sólo puede truncar la lista de parámetros. Por ejemplo, si en un procedimiento
almacenado hay cinco parámetros, puede omitir el cuarto y el quinto, pero no puede omitir el
cuarto e incluir el quinto si no suministra los parámetros con el formato @parámetro = valor.

El valor predeterminado de un parámetro, si se ha definido para el parámetro en el procedimiento


almacenado, se utiliza cuando:
• No se especifica ningún valor para el parámetro en el momento de ejecutar el
procedimiento almacenado.
• Se especifica la palabra clave DEFAULT como valor para el parámetro.
Para ejecutar un procedimiento almacenado que está agrupado con otros procedimientos del
mismo nombre, especifique el número de identificación del procedimiento almacenado dentro del
grupo. Por ejemplo, para ejecutar el segundo procedimiento almacenado del grupo my_proc,
ejecute:
EXECUTE my_proc;2

Material de estudio Página: 208 de 249


Visual Basic 6.0 y SQLServer 7.0

1.9 Trigger (Desencadenadores)


El objeto Trigger expone los atributos de un solo desencadenador de Microsoft® SQL Server™.

Observaciones
SQL Server admite el uso de desencadenadores como una clase de procedimiento almacenado.
Los desencadenadores se ejecutan cuando se intenta una modificación de datos especificada,
como un intento de eliminar una fila, en la tabla en que se ha definido el desencadenador. Con el
objeto Trigger, puede:
• Crear un desencadenador SQL Server en una tabla SQL Server existente.
• Quitar un desencadenador SQL Server existente de una tabla SQL Server.
• Generar una secuencia de comandos Transact-SQL que se pueda utilizar con otras
herramientas para volver a crear un desencadenador SQL Server existente.
• Cambiar el propietario de un desencadenador SQL Server existente.
La propiedad Name de un objeto Trigger es una cadena de caracteres. El valor de la propiedad
identifica un desencadenador SQL Server por el nombre y debe cumplir las reglas de
denominación de desencadenadores. La propiedad Name es necesaria al crear un
desencadenador SQL Server.

Para crear un desencadenador en una tabla SQL Server existente


1. Cree un objeto Trigger.
2. Establezca la propiedad Name.
3. Establezca la propiedad Text para que contenga la secuencia de comandos Transact-
SQL que define el comportamiento del desencadenador SQL Server. Para obtener más
información acerca de las secuencias de comandos de desencadenadores, consulte
CREATE TRIGGER.
4. Obtenga el objeto Table que hace referencia a la tabla SQL Server que desea en la
colección Tables del objeto Database apropiado.
5. Utilice el método BeginAlter del objeto Table para marcar el inicio de los cambios en la
definición de tabla SQL Server.
6. Agregue el nuevo objeto Trigger a la colección Triggers del objeto Table seleccionado.
7. Utilice el método DoAlter del objeto Table para marcar el final de los cambios y crear el
desencadenador SQL Server.

Material de estudio Página: 209 de 249


Visual Basic 6.0 y SQLServer 7.0

1.9.1 Type (Trigger) (SQL-DMO) (Propiedad)

La propiedad Type expone los atributos configurados del componente de Microsoft® SQL
Server™ al que se hace referencia.
Se aplica a
Objeto Trigger
Sintaxis
objeto.Type
Parte Descripción
objeto Expresión que da como resultado un objeto de la lista Se aplica a.
Devuelve
En el objeto Trigger, la propiedad Type se interpreta con estos valores:
Constante Valor Descripción
Activado por cualquier instrucción de modificación
SQLDMOTrig_All 7
de datos.
SQLDMOTrig_Delete 4 Activado por una instrucción DELETE.
SQLDMOTrig_Insert 1 Activado por una instrucción INSERT.
SQLDMOTrig_Unknown 0 Valor incorrecto o no válido.
SQLDMOTrig_Update 2 Activado por una instrucción UPDATE.
Observaciones
Puede activarse un desencadenador de SQL Server cuando una instrucción INSERT, UPDATE o
DELETE de Transact-SQL modifique datos de la tabla en la que está definido.
La secuencia de comandos Transact-SQL que define el desencadenador determina las
instrucciones Transact-SQL que causan su activación.
Tipo de datos
Entero largo, enumerado
Modificable
De sólo lectura

1.9.2 Desencadenadores anidados (recursive)

Con el valor true (verdadero), permite a los desencadenadores activarse de forma


recursiva. La recursión indirecta se produce cuando un desencadenador se activa y realiza
una acción que provoca la activación de un desencadenador de otra tabla, con lo que se
actualiza la tabla original y, a la vez, se produce una nueva activación del desencadenador
original.
Con el valor predeterminado false (falso), no es posible activar los desencadenadores
de forma recursiva.
Es posible determinar el estado de esta opción mediante el examen de la propiedad
IsRecursiveTriggersEnabled de la función DATABASEPROPERTY.

Material de estudio Página: 210 de 249


Visual Basic 6.0 y SQLServer 7.0

Desencadenadores anidados
Los desencadenadores se anidan cuando un desencadenador realiza una acción que provoca la
activación de otro desencadenador que, a su vez, puede activar otro desencadenador y así
sucesivamente. Los desencadenadores puden anidarse hasta un máximo de 32 niveles y es
posible controlar si se pueden anidar mediante la opción de configuración del servidor nested
triggers (desencadenadores anidados).
Si se permiten desencadenadores anidados y un desencadenador de la cadena inicia un bucle
infinito, se superará el nivel de anidamiento y se terminará el desencadenador.
Puede utilizar desencadenadores anidados para realizar funciones de mantenimiento, tales como
el almacenamiento de una copia de seguridad de las filas afectadas por un desencadenador
anterior. Por ejemplo, puede crear un desencadenador en titleauthor (autorTítulo) que guarde
una copia de seguridad de las filas de titleauthor que haya eliminado el desencadenador
delcascadetrig (desEliminCascada). Con la activación de delcascadetrig, la eliminación del
valor PS2091 de la columna title_id de la tabla titles elimina la fila o las filas correspondientes en
titleauthor. Para guardar los datos, cree un desencadenador DELETE en la tabla titleauthor que
guarde los datos eliminados en una nueva tabla, del_save.
CREATE TRIGGER savedel
ON titleauthor
FOR DELETE
AS
INSERT del_save
SELECT * FROM deleted
No es recomendable utilizar los desencadenadores anidados en una secuencia que dependa de
un orden. Utilice desencadenadores diferentes para realizar modificaciones de datos en cascada.

Nota Dado que los desencadenadores se ejecutan dentro de una transacción, un error en
cualquier nivel de un conjunto de desencadenadores anidados anula toda la transacción y
provoca que se deshagan todas las modificaciones de datos. Incluya instrucciones PRINT en los
desencadenadores para poder determinar dónde se produjo el error.

Desencadenadores recursivos
Un desencadenador no se llama a sí mismo de forma recursiva a menos que se active la opción
Desencadenadores recursivos de la base de datos. Hay dos tipos de recursividad:
• La recursividad directa, que se produce cuando un desencadenador se activa y realiza
una acción que provoca que el mismo desencadenador se vuelva a activar. Por ejemplo,
una aplicación actualiza la tabla T3, que provoca la activación del desencadenador Trig3.
Trig3 vuelve a actualizar T3, lo que provoca una nueva activación del mismo
desencadenador Trig3.
• La recursividad indirecta, que se produce cuando un desencadenador se activa y realiza
una acción que provoca la activación de un desencadenador en otra tabla. Este segundo
desencadenador causa una actualización en la tabla original, que, a su vez, provoca que
se vuelva a activar el desencadenador original. Por ejemplo, una aplicación actualiza la
tabla T1, lo que provoca la activación del desencadenador Trig1. Trig1 actualiza la tabla
T2, con lo que se activa el desencadenador Trig2. A su vez, Trig2 actualiza la tabla T1, lo
que provoca que se vuelva a activar Trig1.
Ejemplos
Es posible utilizar los desencadenadores recursivos en una tabla caracterizada por una relación
de referencia a sí misma (también conocida como de cierre transitivo). Por ejemplo, la tabla
emp_mgr (empResp) define:
• A un empleado (emp) de una empresa.
• Al responsable de cada empleado (mgr).
• El número total de empleados en la estructura de la organización que dependen de cada
empleado (NoOfReports).

Material de estudio Página: 211 de 249


Visual Basic 6.0 y SQLServer 7.0

Un desencadenador de actualización recursivo puede servir para mantener actualizada la


columna NoOfReports a medida que se insertan nuevos registros. El desencadenador de
inserción actualiza la columna NoOfReports del registro de responsables, que actualiza de modo
recursivo la columna NoOfReports de otros registros de la jerarquía de administración.
USE pubs
GO
-- Turn recursive triggers ON in the database.
EXECUTE sp_dboption 'pubs', 'recursive triggers', TRUE
GO
CREATE TABLE emp_mgr (
emp char(30) PRIMARY KEY,
mgr char(30) NULL FOREIGN KEY REFERENCES emp_mgr(emp),
NoOfReports int DEFAULT 0
)
GO
CREATE TRIGGER emp_mgrins ON emp_mgr
FOR INSERT
AS
DECLARE @e char(30), @m char(30)
DECLARE c1 CURSOR FOR
SELECT emp_mgr.emp
FROM emp_mgr, inserted
WHERE emp_mgr.emp = inserted.mgr
OPEN c1
FETCH NEXT FROM c1 INTO @e
WHILE @@fetch_status = 0
BEGIN
UPDATE emp_mgr
SET emp_mgr.NoOfReports = emp_mgr.NoOfReports + 1 -- add 1 for newly
WHERE emp_mgr.emp = @e -- added employee
FETCH NEXT FROM c1 INTO @e
END
CLOSE c1
DEALLOCATE c1
GO
-- This recursive UPDATE trigger works assuming:
-- 1. Only singleton updates on emp_mgr.
-- 2. No inserts in the middle of the org tree.
CREATE TRIGGER emp_mgrupd ON emp_mgr FOR UPDATE
AS
IF UPDATE (mgr)
BEGIN
UPDATE emp_mgr
SET emp_mgr.NoOfReports = emp_mgr.NoOfReports + 1 -- Increment mgr's
FROM inserted -- (no. of reports) by
WHERE emp_mgr.emp = inserted.mgr -- 1 for the new report.
UPDATE emp_mgr
SET emp_mgr.NoOfReports = emp_mgr.NoOfReports - 1 -- Decrement mgr's
FROM deleted -- (no. of reports) by 1
WHERE emp_mgr.emp = deleted.mgr -- for the new report
END
GO
-- Insert some test data rows.
INSERT emp_mgr(emp, mgr) VALUES ('Harry', NULL)
INSERT emp_mgr(emp, mgr) VALUES ('Alice', 'Harry')
INSERT emp_mgr(emp, mgr) VALUES ('Paul', 'Alice')
INSERT emp_mgr(emp, mgr) VALUES ('Joe', 'Alice')

Material de estudio Página: 212 de 249


Visual Basic 6.0 y SQLServer 7.0

INSERT emp_mgr(emp, mgr) VALUES ('Dave', 'Joe')


GO
SELECT * FROM emp_mgr
GO
-- Change Dave's manager from Joe to Harry
UPDATE emp_mgr SET mgr = 'Harry'
WHERE emp = 'Dave'
GO
SELECT * FROM emp_mgr
GO
Éstos son los resultados antes de la actualización:
emp mgr NoOfReports
------------------------------ ----------------------------- -----------
Alice Harry 2
Dave Joe 0
Harry NULL 1
Joe Alice 1
Paul Alice 0
Éstos son los resultados después de la actualización:
emp mgr NoOfReports
------------------------------ ----------------------------- -----------
Alice Harry 2
Dave Harry 0
Harry NULL 2
Joe Alice 0
Paul Alice 0

1.9.3 CREATE TRIGGER (Creación de Disparadores)

Crea un desencadenador, que es una clase especial de procedimiento almacenado que se


ejecuta automáticamente cuando un usuario intenta la instrucción especificada de modificación de
datos en la tabla indicada. Microsoft® SQL Server™ permite la creación de varios
desencadenadores para cualquier instrucción INSERT, UPDATE o DELETE dada.
Sintaxis
CREATE TRIGGER nombreDesencadenador
ON tabla
[WITH ENCRYPTION]
{
{FOR { [DELETE] [,] [INSERT] [,] [UPDATE] }
[WITH APPEND]
[NOT FOR REPLICATION]
AS
instrucciónSQL [...n]

}
|
{FOR { [INSERT] [,] [UPDATE] }
[WITH APPEND]
[NOT FOR REPLICATION]
AS
{ IF UPDATE (columna)
[{AND | OR} UPDATE (columna)]

Material de estudio Página: 213 de 249


Visual Basic 6.0 y SQLServer 7.0

[...n]
| IF (COLUMNS_UPDATED() {operadorNivelBit} máscaraBitsActualizada)
{ operadorComparación} máscaraBitsColumna [...n]
}
instrucciónSQL [...n]

}
}
Argumentos

nombreDesencadenador

Es el nombre del desencadenador. Un nombre de desencadenador debe cumplir las reglas de


los identificadores y debe ser único en la base de datos. Especificar el nombre del propietario
del desencadenador es opcional.

tabla

Es la tabla en que se ejecuta el desencadenador; algunas veces se llama la tabla del


desencadenador. Especificar el nombre del propietario de la tabla es opcional. No se pueden
especificar vistas.

WITH ENCRYPTION

Codifica las entradas syscomments que contienen el texto de CREATE TRIGGER.

{ [DELETE] [,] [INSERT] [,] [UPDATE] } | { [INSERT] [,] [UPDATE]}

Son palabras clave que especifican qué instrucciones de modificación de datos activan el
desencadenador cuando se intentan contra esta tabla. Se debe especificar al menos una
opción. En la definición del desencadenador se permite cualquier combinación de éstas. Si
especifica más de una opción, sepárelas con comas.

WITH APPEND

Especifica que debe agregarse un desencadenador adicional de un tipo existente. El uso de


esta cláusula opcional sólo es necesario cuando el nivel de compatibilidad sea menor o igual
que 65. Si el nivel de compatibilidad es mayor o igual que 70, la cláusula opcional WITH
APPEND no es necesaria para agregar un desencadenador adicional de un tipo existente
(éste es el comportamiento predeterminado de CREATE TRIGGER con el valor de nivel de
compatibilidad mayor o igual que 70). Para obtener más información, consulte
sp_dbcmptlevel.

NOT FOR REPLICATION

Indica que el desencadenador no debe ejecutarse cuando un proceso de duplicación modifica


la tabla involucrada en el mismo.

AS

Son las acciones que va a llevar a cabo el desencadenador.

instrucciónSQL

Son las condiciones y acciones del desencadenador. Las condiciones del desencadenador
especifican los criterios adicionales que determinan si los intentos de las instrucciones
DELETE, INSERT o UPDATE hacen que se lleven a cabo las acciones del desencadenador.

Material de estudio Página: 214 de 249


Visual Basic 6.0 y SQLServer 7.0

Las acciones del desencadenador especificadas en las instrucciones Transact-SQL entran en


efecto cuando se intenta la acción del usuario (DELETE, INSERT o UPDATE).

Los desencadenadores pueden incluir cualquier número y clase de instrucciones Transact-


SQL excepto SELECT. Un desencadenador está diseñado para comprobar o cambiar los
datos en base a una instrucción de modificación de datos; no debe devolver datos al usuario.
Las instrucciones Transact-SQL de un desencadenador incluyen a menudo lenguaje de
control de flujo. En las instrucciones CREATE TRIGGER se utilizan unas cuantas tablas
especiales:

• deleted e inserted son tablas lógicas (conceptuales). Son de estructura similar a


la tabla en que se define el desencadenador (es decir, la tabla en que se intenta la
acción del usuario) y mantiene los valores antiguos o nuevos de las filas que la acción
del usuario puede cambiar. Por ejemplo, para recuperar todos los valores de la tabla
deleted, utilice:

SELECT *

FROM deleted

• En un desencadenador DELETE, INSERT o UPDATE, SQL Server no admite


referencias de columnas text, ntext o image en las tablas inserted y deleted si el
nivel de compatibilidad es igual a 70. No se puede tener acceso a los valores text,
ntext e image de las tablas inserted y deleted. Para recuperar el nuevo valor de un
desencadenador INSERT o UPDATE, combine la tabla inserted con la tabla de
actualización original. Cuando el nivel de compatibilidad es 65 o inferior, se devuelven
valores Null para las columnas inserted o deleted text, ntext o image que admiten
valores Null; si las columnas no permiten valores Null, se devuelven cadenas de
longitud cero.

Se trata de un marcador de posición que indica que se pueden incluir varias instrucciones
Transact-SQL en el desencadenador. Para la instrucción IF UPDATE (columna), se pueden
incluir varias columnas al repetir la cláusula UPDATE (columna).

IF UPDATE (columna)

Prueba una acción INSERT o UPDATE en una columna especificada y no se utiliza con
operaciones DELETE. Se puede especificar más de una columna. Como el nombre de la
tabla se especifica en la cláusula ON, no lo incluya antes del nombre de la columna en una
cláusula IF UPDATE. Para probar una acción INSERT o UPDATE para más de una columna,
especifique una cláusula UPDATE(columna) separada a continuación de la primera.

Nota La cláusula IF UPDATE (columna) funciona de forma idéntica a una instrucción IF, IF…
ELSE o WHILE, y puede utilizar el bloque BEGIN…END. Para obtener más información,
consulte Lenguaje de control de flujo.

UPDATE(columna) puede utilizarse en cualquier parte dentro del cuerpo del desencadenador.

columna

Es el nombre de la columna que se va a probar para una acción INSERT o UPDATE. Esta
columna puede ser de cualquier tipo de datos admitido por SQL Server. Para obtener más
información, consulte Tipos de datos.

Material de estudio Página: 215 de 249


Visual Basic 6.0 y SQLServer 7.0

IF (COLUMNS_UPDATED())

Prueba, sólo en un desencadenador INSERT o UPDATE, si la columna o columnas


mencionadas se insertan o se actualizan. COLUMNS_UPDATED devuelve un patrón de bits
varbinary que indica qué columnas de la tabla se insertaron o se actualizaron.

COLUMNS_UPDATED puede utilizarse en cualquier parte dentro del cuerpo del


desencadenador.

operadorNivelBit

Es el operador de bits que se utilizará en las comparaciones.

máscaraBitsActualizada

Es la máscara de bits de enteros de las columnas realmente actualizadas o insertadas. Por


ejemplo, la tabla t1 contiene las columnas C1, C2, C3, C4 y C5. Para comprobar si las
columnas C2, C3 y C4 se han actualizado (con un desencadenador UPDATE en la tabla t1),
especifique un valor de 14. Para comprobar si sólo se ha actualizado la columna C2,
especifique un valor de 2.

operadorComparación

Es el operador de comparación. Utilice el signo igual (=) para comprobar si todas las
columnas especificadas en máscaraBitsActualizada se han actualizado. Utilice el símbolo
mayor que (>) para comprobar si alguna de las columnas especificadas en
máscaraBitsActualizada se han actualizado.

máscaraBitsColumna

Es la máscara de bits de enteros de las columnas que hay que comprobar para ver si se han
actualizado o insertado.

Observaciones
A menudo se utilizan desencadenadores para exigir las reglas del negocio y la integridad de los
datos. SQL Server proporciona integridad referencial declarativa (DRI, Declarative Referential
Integrity) a través de las instrucciones de creación de tabla (ALTER TABLE y CREATE TABLE);
sin embargo, DRI no proporciona integridad referencial entre bases de datos. Para exigir la
integridad referencial (reglas acerca de la relación entre la clave principal y la clave externa de las
tablas), utilice las restricciones de clave principal y externa (las palabras clave PRIMARY KEY y
FOREIGN KEY de ALTER TABLE y CREATE TABLE). Si existen restricciones en la tabla del
desencadenador, se comprobarán antes de la ejecución del desencadenador. Si se infringe
alguna de las restricciones PRIMARY KEY o FOREIGN KEY, el desencadenador no se ejecuta
(no se activa).

Nota El que SQL Server interprete una cadena vacía (NULL) como un espacio simple o como una
verdadera cadena vacía se controla mediante el valor de sp_dbcmptlevel. Si el nivel de
compatibilidad es menor o igual que 65, SQL Server interpreta las cadenas vacías como espacios
individuales. Si el nivel de compatibilidad es igual a 70, SQL Server interpreta las cadenas vacías
como tales. Para obtener más información, consulte sp_dbcmptlevel.

Limitaciones de los desencadenadores


CREATE TRIGGER debe ser la primera instrucción en el proceso por lotes y sólo se puede
aplicar a una tabla.
Un desencadenador se crea solamente en la base de datos actual; sin embargo, un
desencadenador puede hacer referencia a objetos que están fuera de la base de datos actual.

Material de estudio Página: 216 de 249


Visual Basic 6.0 y SQLServer 7.0

Si se especifica el nombre del propietario del desencadenador (para cualificar el


desencadenador), cualifique el nombre de la tabla de la misma forma.
La misma acción del desencadenador puede definirse para más de una acción del usuario (por
ejemplo, INSERT y UPDATE) en la misma instrucción CREATE TRIGGER.
En un desencadenador se puede especificar cualquier instrucción SET. La opción SET elegida
permanece en efecto durante la ejecución del desencadenador y, después, vuelve a su
configuración anterior.
Cuando se activa un desencadenador, los resultados se devuelven a la aplicación que llama,
exactamente igual que con los procedimientos almacenados. Para impedir que los resultados
tengan que devolverse a la aplicación debido a la activación de un desencadenador, no incluya
las instrucciones SELECT que devuelven resultados o las instrucciones que realizan una
asignación variable en un desencadenador. Un desencadenador que incluya instrucciones
SELECT que devuelven resultados al usuario o instrucciones que realizan asignaciones de
variables requiere un tratamiento especial; estos resultados devueltos tendrían que escribirse en
cada aplicación en la que se permiten modificaciones a la tabla del desencadenador. Si deben
ocurrir asignaciones de variable en un desencadenador, utilice una instrucción SET NOCOUNT al
principio del desencadenador para eliminar la devolución de cualquier conjunto de resultados.
En una vista no se puede crear un desencadenador.
Un desencadenador DELETE no captura una instrucción TRUNCATE TABLE. Aunque una
instrucción TRUNCATE TABLE es, de hecho, un desencadenador DELETE sin una cláusula
WHERE (quita todas las filas), no se registra y, por tanto, no puede ejecutar un desencadenador.
Dado que el permiso de la instrucción TRUNCATE TABLE es, de forma predeterminada, el del
propietario de la tabla y no se puede transferir, sólo el propietario de la tabla debe preocuparse de
colocar sin darse cuenta una instrucción TRUNCATE TABLE en el desencadenador DELETE.
La instrucción WRITETEXT, ya se registre o no, no activa un desencadenador.

Las siguientes instrucciones Transact-SQL no están permitidas en un desencadenador:

ALTER DATABASE ALTER PROCEDURE ALTER TABLE


ALTER TRIGGER ALTER VIEW CREATE DATABASE
CREATE DEFAULT CREATE INDEX CREATE PROCEDURE
CREATE RULE CREATE SCHEMA CREATE TABLE
CREATE TRIGGER CREATE VIEW DENY
DISK INIT DISK RESIZE DROP DATABASE
DROP DEFAULT DROP INDEX DROP PROCEDURE
DROP RULE DROP TABLE DROP TRIGGER
DROP VIEW GRANT LOAD DATABASE
LOAD LOG RESTORE DATABASE RESTORE LOG
REVOKE RECONFIGURE
TRUNCATE TABLE UPDATE STATISTICS

Nota Debido a que SQL Server no admite desencadenadores definidos por el usuario en tablas
del sistema, se recomienda que no se creen desencadenadores definidos por el usuario en tablas
del sistema.

Desencadenadores múltiples
SQL Server permite que se creen varios desencadenadores por cada evento de modificación
(DELETE, INSERT o UPDATE). Por ejemplo, si se ejecuta CREATE TRIGGER FOR UPDATE
para una tabla que ya tiene un desencadenador UPDATE, se creará un desencadenador de
actualización adicional. En las versiones anteriores, sólo se permitía un desencadenador por cada
evento de modificación (INSERT, UPDATE, DELETE) en cada tabla.

Nota El comportamiento predeterminado de CREATE TRIGGER (con un nivel de compatibilidad


de 70) es agregar desencadenadores adicionales a los ya existentes si los nombres de

Material de estudio Página: 217 de 249


Visual Basic 6.0 y SQLServer 7.0

desencadenadores son distintos. Si el nombre de los desencadenadores es el mismo, SQL


Server devuelve un mensaje de error. Sin embargo, si el nivel de compatibilidad es igual o menor
que 65, cualquier desencadenador creado con la instrucción CREATE TRIGGER substituirá a los
desencadenadores existentes del mismo tipo, incluso si los nombres de los desencadenadores
son distintos. Para obtener más información, consulte sp_dbcmptlevel.

Desencadenadores recursivos
SQL Server permite también la invocación recursiva de desencadenadores cuando el valor
recursive triggers está habilitado en sp_dboption.
Los desencadenadores recursivos permiten dos tipos de recursión:
• Recursión indirecta
• Recursión directa
Con la recursión indirecta, una aplicación actualiza la tabla T1, que activa el desencadenador TR1
para actualizar la tabla T2. En esta situación, el desencadenador T2 activa y actualiza la tabla T1.
Con la recursión directa, la aplicación actualiza la tabla T1, que activa el desencadenador TR1
para actualizar la tabla T1. Debido a que la tabla T1 ya se ha actualizado, el desencadenador TR1
se activa de nuevo, y así sucesivamente.
Este ejemplo utiliza ambas recursiones de desencadenador, directa e indirecta. Suponga que en
la tabla T1 se han definido dos desencadenadores de actualización, TR1 y TR2. El
desencadenador TR1 actualiza la tabla T1 recursivamente. Una instrucción UPDATE ejecuta cada
TR1 y TR2 una vez. Además, la ejecución de TR1 desencadena la ejecución de TR1
(recursivamente) y TR2. Las tablas inserted y deleted de un desencadenador dado contienen
filas que corresponden sólo a la instrucción UPDATE que invocó al desencadenador.

Nota El comportamiento anterior sólo se produce si el valor recursive triggers de sp_dboption


está habilitado. No hay un orden definido en el que se ejecuten los distintos desencadenadores
definidos de un evento dado. Cada desencadenador debe ser independiente.

Si alguno de los desencadenadores realiza una instrucción ROLLBACK TRANSACTION, no se


ejecuta ningún desencadenador posterior, independientemente del nivel de anidamiento.
Desencadenadores anidados
Los desencadenadores pueden anidarse hasta 32 niveles. Si un desencadenador cambia una
tabla en la que hay otro desencadenador, el segundo se activa y puede, entonces, llamar a un
tercero, y así sucesivamente. Si algún desencadenador de la cadena causa un bucle infinito, el
nivel de anidamiento se habrá sobrepasado, con lo que se cancela el desencadenador. Para
deshabilitar los desencadenadores anidados, establezca la opción nested triggers de
sp_configure en 0 (desactivada). La configuración predeterminada permite desencadenadores
anidados. Si los desencadenadores anidados están desactivados, los desencadenadores
recursivos también se deshabilitan, independientemente del valor de recursive triggers de
sp_dboption.
Resolución diferida de nombres
SQL Server permite que los procedimientos almacenados, desencadenadores y procesos por
lotes de Transact-SQL hagan referencia a tablas que no existen en el momento de la compilación.
Esta capacidad se denomina resolución diferida de nombres. Sin embargo, si los procedimientos
almacenados, desencadenadores y procesos por lotes de Transact-SQL hacen referencia a una
tabla definida en el procedimiento almacenado o desencadenador, se emitirá una advertencia en
el momento de la creación sólo si el valor de nivel de compatibilidad (que se establece al ejecutar
sp_dbcmptlevel) es igual a 65. Si se utiliza un proceso por lotes, la advertencia se emite en el
momento de la compilación. Si la tabla a la que se hace referencia no existe, en el momento de la
ejecución se devolverá un mensaje de error. Para obtener más información, consulte Resolución
diferida de nombres y compilación.

Material de estudio Página: 218 de 249


Visual Basic 6.0 y SQLServer 7.0

Permisos
De forma predeterminada, el permiso CREATE TRIGGER es del propietario de la tabla en que se
ha definido el desencadenador o de los miembros de las funciones fijas de base de datos
db_owner y db_ddladmin, y no se puede transferir.
Ejemplos

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
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
B. Utilizar un desencadenador con un mensaje de correo electrónico de aviso
Este ejemplo envía un mensaje de correo electrónico a una persona especificada (MaryM)
cuando cambia la tabla titles.
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, DELETE
AS
EXEC master..xp_sendmail 'MaryM',
'Don''t forget to print a report for the distributors.'
GO
C. Utilizar un desencadenador de regla de negocio entre las tablas employee y jobs
Debido a que las restricciones CHECK pueden hacer referencia sólo a las columnas en que se
han definido las restricciones de nivel de columna o de nivel de tabla, cualquier restricción de
tablas cruzadas (en este caso, reglas del negocio) debe definirse como desencadenadores.
Este ejemplo crea un desencadenador que, cuando se inserta o se cambia un nivel de trabajo de
empleado, comprueba que el nivel especificado del trabajo del empleado (job_lvls) en el que se
basan los salarios se encuentra en el intervalo definido para el trabajo. Para obtener el intervalo
adecuado, debe hacerse referencia a la tabla jobs.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'reminder' AND type = 'TR')
DROP TRIGGER reminder
GO
CREATE TRIGGER employee_insupd

Material de estudio Página: 219 de 249


Visual Basic 6.0 y SQLServer 7.0

ON employee
FOR INSERT, UPDATE
AS
/* Get the range of level for this job type from the jobs table. */
DECLARE @min_lvl tinyint,
@max_lvl tinyint,
@emp_lvl tinyint,
@job_id smallint
SELECT @min_lvl = min_lvl,
@max_lvl = max_lvl,
@emp_lvl = i.job_lvl,
@job_id = i.job_id
FROM employee e INNER JOIN inserted i ON e.emp_id = i.emp_id
JOIN jobs j ON j.job_id = i.job_id
IF (@job_id = 1) and (@emp_lvl <> 10)
BEGIN
RAISERROR ('Job id 1 expects the default level of 10.', 16, 1)
ROLLBACK TRANSACTION
END
ELSE
IF NOT (@emp_lvl BETWEEN @min_lvl AND @max_lvl)
BEGIN
RAISERROR ('The level for job_id:%d should be between %d and %d.',
16, 1, @job_id, @min_lvl, @max_lvl)
ROLLBACK TRANSACTION
END
D. Utilizar la resolución diferida de nombres
El ejemplo siguiente crea dos desencadenadores para ilustrar la resolución diferida de nombres.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'trig1' AND type = 'TR')
DROP TRIGGER trig1
GO
-- Creating a trigger on a nonexistent table.
CREATE TRIGGER trig1
on authors
FOR INSERT, UPDATE, DELETE
AS
SELECT a.au_lname, a.au_fname, x.info
FROM authors a INNER JOIN does_not_exist x
ON a.au_id = x.au_id
GO
-- Here is the statement to actually see the text of the trigger.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'TR' and o.name = 'trig1'
-- Creating a trigger on an existing table, but with a nonexistent
-- column.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'trig2' AND type = 'TR')
DROP TRIGGER trig2
GO
CREATE TRIGGER trig2

Material de estudio Página: 220 de 249


Visual Basic 6.0 y SQLServer 7.0

ON authors
FOR INSERT, UPDATE
AS
DECLARE @fax varchar(12)
SELECT @fax = phone
FROM authors
GO
-- Here is the statement to actually see the text of the trigger.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'TR' and o.name = 'trig2'
E. Utilizar COLUMNS_UPDATED
En este ejemplo se crean dos tablas. Una tabla employeeData y una tabla auditEmployeeData.
La tabla employeeData, que contiene información confidencial de los sueldos de los empleados,
puede ser modificada por los miembros del departamento de recursos humanos. Si se cambia el
número de seguridad social del empleado, el sueldo anual o el número de cuenta bancaria, se
genera un registro de auditoría y se inserta en la tabla de auditoría auditEmployeeData.
Con la función COLUMNS_UPDATED(), es posible comprobar rápidamente cualquier cambio en
estas columnas que contienen información confidencial de los empleados.
USE pubs
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'employeeData')
DROP TABLE employeeData
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'auditEmployeeData')
DROP TABLE auditEmployeeData
GO
CREATE TABLE employeeData (
emp_id int NOT NULL,
emp_bankAccountNumber char (10) NOT NULL,
emp_salary int NOT NULL,
emp_SSN char (11) NOT NULL,
emp_lname nchar (32) NOT NULL,
emp_fname nchar (32) NOT NULL,
emp_manager int NOT NULL
)
GO
CREATE TABLE auditEmployeeData (
audit_log_id uniqueidentifier DEFAULT NEWID(),
audit_log_type char (3) NOT NULL,
audit_emp_id int NOT NULL,
audit_emp_bankAccountNumber char (10) NULL,
audit_emp_salary int NULL,
audit_emp_SSN char (11) NULL,
audit_user sysname DEFAULT SUSER_SNAME(),
audit_changed datetime DEFAULT GETDATE()
)
GO
CREATE TRIGGER updEmployeeData
ON employeeData
FOR update AS
-- Check whether columns 2, 3 or 4 has been updated. If any or all of
-- columns 2, 3 or 4 have been changed, create an audit record.
-- The bitmask is: power(2,(2-1))+power(2,(3-1))+power(2,(4-1)) = 14

Material de estudio Página: 221 de 249


Visual Basic 6.0 y SQLServer 7.0

-- To check if all columns 2, 3, and 4 are updated, use = 14 in place of


-- >0 (below).
IF (COLUMNS_UPDATED() & 14) > 0
-- Use IF (COLUMNS_UPDATED() & 14) = 14 to see if all of columns 2, 3,
-- and 4 are updated.
BEGIN
-- Audit OLD record.
INSERT INTO auditEmployeeData
(audit_log_type,
audit_emp_id,
audit_emp_bankAccountNumber,
audit_emp_salary,
audit_emp_SSN)
SELECT 'OLD',
del.emp_id,
del.emp_bankAccountNumber,
del.emp_salary,
del.emp_SSN
FROM deleted del
-- Audit NEW record.
INSERT INTO auditEmployeeData
(audit_log_type,
audit_emp_id,
audit_emp_bankAccountNumber,
audit_emp_salary,
audit_emp_SSN)
SELECT 'NEW',
ins.emp_id,
ins.emp_bankAccountNumber,
ins.emp_salary,
ins.emp_SSN
FROM inserted ins
END
GO
--Inserting a new employee does not cause the UPDATE trigger to fire.
INSERT INTO employeeData
VALUES ( 101, 'USA-987-01', 23000, 'R-M53550M', N'Mendel', N'Roland', 32)
GO
-- Updating the employee record for employee number 101 to change the
-- salary to 51000 causes the UPDATE trigger to fire and an audit trail
-- to be produced.
UPDATE employeeData
SET emp_salary = 51000
WHERE emp_id = 101
GO
SELECT * FROM auditEmployeeData
GO
--Updating the employee record for employee number 101 to change both the bank account
number and social security number (SSN) causes the UPDATE trigger to fire and an audit trail to
be produced.
UPDATE employeeData
SET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'
WHERE emp_id = 101
GO
SELECT * FROM auditEmployeeData
GO

Material de estudio Página: 222 de 249


Visual Basic 6.0 y SQLServer 7.0

Anexos

I.1 SQL (Lenguaje Estructurado de Consultas “ Structured Query Language”)

A
ntes de exponer los siguientes incisos de SQL desarrollaremos una idea
global del funcionamiento de SQL, ilustrando sus características y
funciones más importantes.

SQL esta basado en el modelo relacional que organiza los datos en una base
como una colección de tablas.

• Cada tabla tiene un nombre que la identifica unívocamente.


• Cada tabla tiene una o más columnas dispuestas en un orden
específico de izquierda a derecha.
• Cada tabla tiene cero o más filas, conteniendo cada una un único
valor en cada columna. Las filas están desordenadas.
• Todos los valores de una columna determinada tienen el mismo
tipo de datos, y éstos están extraídos de un conjunto de valores
legales llamado el dominio de la columna.

Las tablas están relacionadas unas con otras por los datos que contienen. El
modelo de datos relacional utiliza claves primarias y foráneas para
representar estas relaciones entre las tablas.

• Una clave primaria es una columna o combinación de columnas dentro


de una tabla(s) cuyo(s) valor(es) identifica(n) unívocamente a cada fila
de la tabla.

• Una clave foránea es una columna o combinación de columnas en una


tabla, cuyo(s) valor(es) es(son) un valor de la clave primaria .

• Una combinación de claves primarias/foráneas crea una relación


padre/hijo entre las tablas que las contienen.

Todas las sentencias en SQL comienzan con un verbo, una palabra clave que
describe lo que la sentencia hace (CREATE, INSERT, DELETE, COMMIT), la
sentencia continúa con una o más cláusulas (Ver fig. 4.1). Una cláusula puede
especificar los datos sobre los que debe actuar la sentencia, o proporcionar
más detalles acerca de lo que ésta hace, también comienza con una palabra
clave (WHERE, FROM, INTO, HAVING, etc.), algunas son opcionales y otras son
necesarias. La estructura y contenido varían de una cláusula a otra.

v e rb o c lá u s u la

D E LE T E F R O M n o m b re _ d e _ t a b la
p a la b ra s
c la v e
W H E R E n o m b re _ c o lu m n a < c o n d ic ió n > < e x p re s ió n >

Material de estudio Página: 223 de 249


Visual Basic 6.0 y SQLServer 7.0

Fig. 4.1 Estructura de una Sentencia SQL.

El estándar SQL ANSI/ISO (American National Standards Institute/International


Standards Organization) especifica las palabras clave que se utilizan como
verbos y cláusulas de sentencias. De acuerdo al estándar, estas palabras
clave no pueden ser utilizadas para designar objetos de la base, tales como
tablas, columnas y usuarios. Los objetos de una base de datos basada en SQL
se identifican asignándoles nombres únicos, utilizándose en las sentencias
para identificar el objeto en la base sobre la que la sentencia debe actuar. El
estándar ANSI/ISO especifica palabras permisibles para identificar tablas,
columnas y usuarios; algunas implementaciones soportan objetos como
procedimientos almacenados, relaciones clave primaria/foránea y formularios
de entrada de datos, entre otros.

El estándar ANSI/ISO especifica varios tipos de datos que pueden ser


almacenados y manipulados por el lenguaje SQL y la mayoría de los productos
los soporta, además de ofrecer un conjunto más extenso que éste.

4.1 HISTORIA Y PERSPECTIVAS DE SQL.

Una de las principales tareas de un sistema computacional es almacenar y


gestionar datos, por tal motivo, programas especializados en computadoras
conocidos como sistemas de gestión de bases de datos comenzaron a
aparecer a finales de los sesenta y comienzo de los setenta. Anteriormente un
sistema de gestión de base datos o DBMS (Sistema Manejador de Base de
Datos, “Database Management System”), ayudaba a los usuarios a organizar y
estructurar sus datos, y permitía al sistema computacional jugar un papel más
activo en la gestión de los datos. Aunque los sistemas de bases de datos se
desarrollaron inicialmente en mainframes, su popularidad se ha extendido a
minicomputadoras, computadoras personales y estaciones de trabajo.

Durante los últimos años se ha popularizado un tipo específico de DBMS,


llamado sistema de gestión de base de datos relacional (RDBMS). Las bases de
datos relacionales organizan los datos en una forma tabular sencilla y
proporcionan muchas ventajas sobre los tipos anteriores de bases de datos.
SQL (Lenguaje Estructurado de Consultas “ Structured Query Language”) es
un lenguaje relacional utilizado para trabajar con bases de datos relacionales.

BREVE HISTORIA DE SQL

Material de estudio Página: 224 de 249


Visual Basic 6.0 y SQLServer 7.0

La historia del lenguaje SQL está íntimamente relacionada con el desarrollo de


las bases de datos relacionales. La Tabla 4.1 muestra algunos de los
acontecimientos en sus veinte años de historia.

El concepto de base de datos relacional fue desarrollado originalmente por el


Dr. E. F. Ted Codd, quien publicó un artículo titulado «Un modelo relacional de
datos para grandes bancos de datos compartidos» que esquematizaba una
teoría matemática de como los datos podrían ser almacenados y manipulados
utilizando una estructura tabular.

Fecha Acontecimiento
1970 Codd define el modelo de base de datos relacional.
1974 Comienza el proyecto System/R de IBM.
1974 Primer artículo que describe el lenguaje SEQUEL.
1978 Test de clientes del System/R.
1979 Oracle introduce el primer RDBMS comercial.
1981 Relational Technology introduce Ingres.
1981 IBM anuncia SQL/DS.
1982 ANSI forma el comité de estándares SQL.
1983 IBM anuncia DB2.
1986 Se ratifica el estándar ANSI SQL.
1986 Sybase introduce RDBMS para procesamiento de
1987 transacciones.
Se ratifica el estándar ISO SQL
1988 Ashton-Tate y Microsoft anuncian SQL Server para OS/2
1988 IBM anuncia la versión 2 de DB2
1989 Primera entrega de servidores de bases de datos SQL para
OS/2
Tabla 4.1 Acontecimientos en el desarrollo de SQL.

ACEPTACIÓN COMERCIAL

La publicación del estándar ANSI/ISO para SQL en 1986, dio carácter oficial a
SQL como estándar. La tabla 4.2 muestra algunos de los sistemas de gestión
de base de datos en SQL más populares sobre diferentes tipos de sistemas de
computadoras.

Al inicio de los noventa, SQL estaba claramente establecido como el lenguaje


estándar de base de datos. Los vendedores de base de datos que no
soportaban SQL se preocuparon de hacerlo sobre todo por que cualquier
nuevo producto de base de datos requería a SQL como reclamo para ser
tomado en serio; SQL se convirtió en el estándar oficial para las bases de
datos relacionales.

DBMS Sistemas informáticos

Material de estudio Página: 225 de 249


Visual Basic 6.0 y SQLServer 7.0

DB2 Mainframes IBM bajo MVS.


SQL/DS Mainframes IBM bajo VM y DOS/VSE.
Rdb/VMS Mainframes VAX/VMS de Digital.
Oracle Mainframes, minicomputadoras y PC’s.
Ingres Mainframes y PC’s.
Sybase Mainframes y LANs.
Informix-SQL Mainframes y PC’s basados en UNIX.
Unify Mainframes basados en UNIX.
OS/2 Extended Sistemas PS/2 de IBM bajo OS/2.
Edition
SQL Server PC LANs basados en OS/2.
SQLBase PC LANs basados en DOS y OS/2.
DBASE IV PC’s y PC LANs.
Tabla 4.2 Principales sistemas de gestión de base de datos basados en SQL.

Uno de los desarrollos más importantes en la aceptación del mercado de SQL


es la creación de los estándares SQL. Las referencias al «estándar SQL»
significa generalmente el estándar oficial adoptado por la ANSI e ISO.

La mayoría de los desarrolladores de software están de acuerdo en que un


estándar para SQL es esencial para el cómputo cliente/servidor. Sin embargo,
no menos de ocho proyectos se están llevando a cabo para crear un estándar
SQL. Sólo el ANSI es responsable de tres estándares ya sean publicados o en
proceso. Otros esfuerzos involucran a consorcios de la industria, tales como
SAG (el grupo de acceso a SQL), X/Open y a compañías como IBM, Microsoft y
Borland. Si además consideramos que cualquier Base de Datos “habla su
propio dialecto de SQL” y tiene su propio conjunto de extensiones de este
lenguaje, no es fácil la tarea para su estandarización .

Las razones para la proliferación de estándares de SQL son numerosas; una de


ellas es que los estándares están diseñados solamente para servir como guías,
esto deja mucho lugar para la interpretación cuando un proveedor toma una
especificación del lenguaje y la pone en práctica en software. Sin embargo, la
mayoría de las veces los proveedores intentan hacer mucho más y el problema
es que aunque cada proveedor tome decisiones excelentes, éstas son
diferentes acerca de como extender el estándar de SQL.

A falta de un estándar aceptado, los proveedores de bases de datos están


realizando sus propios trabajos de estandarización. A continuación
mencionamos los más significativos para la creación de estándares.

• SQL’89 de ANSI. El estándar SQL del ANSI ratificado en 1989 fue el


primer nivel de estandarización de SQL.

• SQL’92 de ANSI. Una extensión al estándar de 1989 que se convirtió


en un estándar importante en los siguientes años, conforme los
proveedores de bases de datos y herramientas hicieron modificaciones para
tener compatibilidad con él.

• SQL’93 de ANSI. Un esfuerzo para expandir sustancialmente el


lenguaje, proporciona más estructura y estándares para tener acceso a
bases de datos orientadas a objetos.

Material de estudio Página: 226 de 249


Visual Basic 6.0 y SQLServer 7.0

• SAG (Grupo de acceso a SQL) y X/Open. SAG es un consorcio de


proveedores de bases de datos y herramientas. X/Open es un consorcio de
la industria dedicado a publicar y reforzar el uso de estándares para
sistemas abiertos. Estas dos agrupaciones están trabajando conjuntamente
para establecer un estándar de SQL y un API basados en el SQL’89 de ANSI,
y en los últimos avances en el ámbito cliente/servidor.

• IDAPI (Interface Integrada para la Programación de Aplicaciones


de Bases de Datos). IDAPI está basada en el trabajo de SAG y de X/Open,
refleja el intento de Borland por definir un API para SQL.

• DRDA (Acceso Distribuido a Bases de Datos Relacionales). El


estándar emergente de IBM para acceso a bases de datos a través de todas
sus plataformas, incluye otra incursión en SQL.

La creciente popularidad de la conexión de computadoras por red durante los


últimos años ha tenido un fuerte impacto en la gestión de base de datos y ha
dado a SQL una mayor relevancia. Conforme las redes pasan a ser más
comunes, las aplicaciones que han corrido tradicionalmente en una
minicomputadora o mainframe central se están transfiriendo a redes de área
local con estaciones de trabajo de sobremesa y servidores. En estas redes
SQL juega un papel crucial como vínculo entre una aplicación que corre en una
estación de trabajo y el DBMS que gestiona los datos compartidos en el
servidor, en los siguientes incisos mostramos como actua el DBMS en tres
arquitecturas.

ARQUITECTURA CENTRALIZADA

La arquitectura de base de datos tradicional utilizada por DB2, SQL/DS y las


bases de datos sobre minicomputadoras tales como Oracle e Ingres se
muestra en la figura 4.2. En esta arquitectura el DBMS y los datos físicos
residen en un sistema mainframe o minicomputadora central, junto con el
programa de aplicación que acepta entradas desde la terminal de usuario y
muestra los datos en la pantalla del usuario.

Supongamos que el usuario teclea una consulta que requiere una búsqueda
secuencial en la base de datos; por ejemplo, hallar la cantidad media de
mercancías de todos los pedidos; el DBMS recibe la consulta, explora la base
de datos para acceder a cada uno de los registros de datos del disco, calcula
el promedio y muestra el resultado en la pantalla de la terminal.

Tanto el procesamiento de la aplicación como el procesamiento de la base de


datos se producen en la computadora central, y como el sistema es
compartido por muchos usuarios, cada usuario experimenta una degradación
del rendimiento cuando el sistema tiene una carga fuerte.

T e r m in a l S is t e m a C e n t r a l

C om andos

A p li c a c i ó n DBM S B ase de
D a to s

Material de estudio R e s u lta d o s


Página: 227 de 249
Visual Basic 6.0 y SQLServer 7.0

Fig. 4.2. Gestión de Base Datos en una arquitectura centralizada.

ARQUITECTURA DE SERVIDOR DE ARCHIVOS

La introducción de las computadoras personales y de las redes de área local


condujo al desarrollo de la arquitectura servidora de archivos, mostrada en la
figura 4.3. En esta arquitectura, una aplicación que corre en un computadora
personal puede acceder de forma transparente a datos localizados en un
servidor de archivos que almacena los archivos compartidos. Cuando una
aplicación en PC solicita datos de un archivo compartido, el software de red
recupera automáticamente el bloque solicitado del archivo en el servidor.
Varias bases de datos PC populares, entre las que se incluye Dbase, R:BASE y
Paradox, soportan esta estrategia servidora de archivos, donde cada
computadora personal ejecuta su propia copia del software DBMS.

Para consultas típicas esta arquitectura proporciona un rendimiento excelente,


ya que cada usuario dispone de la potencia completa de un computadora
personal ejecutando su propia copia del DBMS. Sin embargo, consideremos
una consulta que requiere una exploración secuencial de la base de datos, el
DBMS solicita repentinamente bloques de datos de la base de datos, la cual
está localizada físicamente a través de la red en el servidor, eventualmente
todos los bloques del archivo están solicitados y enviados a través de la red.
Obviamente esta arquitectura produce un fuerte tráfico de red y un bajo
rendimiento para consultas de este tipo.

PC
S e r v id o r d e
A r c h iv o s

A p lic a c i ó n D BM S
S o ft w a r e d e R e d B .D . y A r c h iv o s
C o m p a r tid o s

P e tic io n e s d e
PC PC E /S a D is c o
B lo q u e s d e D is c o

Fig. 4.3.
Gestión de base de datos en una arquitectura Servidor de Archivos.

ARQUITECTURA CLIENTE /SERVIDOR

Material de estudio Página: 228 de 249


Visual Basic 6.0 y SQLServer 7.0

La figura 4.4 muestra la emergente arquitectura cliente/servidor para gestión


de base de datos. En esta arquitectura, las computadoras personales están
combinadas en una red de área local junto con un servidor de base de datos
que almacena las bases de datos compartidas. Las funciones del DBMS están
divididas en dos partes: los « frontales » (front-ends) de base de datos, tales
como herramientas de consulta interactiva, escritores de informe y programas
de aplicación, que se ejecutan en la computadora personal y la máquina de «
soporte » (back-end) de la base de datos que almacena y gestiona los datos
se ejecutan en el servidor. SQL se ha convertido en el lenguaje de base de
datos estándar para comunicación entre las herramientas frontales y la
máquina de soporte en esta arquitectura.

Consideremos una vez más la consulta secuencial. En la arquitectura


cliente/servidor, la consulta viaja a través de la red hasta el servidor de base
de datos como una petición SQL, la máquina de base de datos en el servidor
procesa la petición y explora la base de datos, que también reside en el
servidor. Cuando calcula el resultado, la máquina de base de datos envía de
regreso a través de la red una única contestación a la petición y la aplicación
frontal la muestra en pantalla de la PC.

La arquitectura cliente/servidor reduce el tráfico de red y divide la carga de la


base de datos. Las funciones de intensiva relación con el usuario, tales como
el manejo de la entrada y la visualización de los datos, se concentran en la PC.
Las funciones intensivas en proceso de datos, tales como la entrada/salida de
archivos y el procesamiento de consultas, se concentran en el servidor de
datos. Lo que es más importante, el lenguaje SQL proporciona una interfaz
bien definida entre los sistemas frontales y de soporte, comunicando las
peticiones de acceso a la base de datos de una manera eficiente.

La arquitectura cliente/servidor ha recibido gran atención con la introducción


de redes de PC basadas en OS/2. SQL Server, el Servidor Oracle para SQLBase
de Gupta Technologies utilizan esta estrategia.

PC
S e r v id o r d e
B .D .

A p li c a c ió n
D BM S B ase de
D a to s

P e tic io n e s S Q L
PC PC
D a to s

Fig. 4.4.
Gestión de B.D. en una arquitectura Cliente/Servidor.

SQL es un vehículo natural para implementar aplicaciones utilizando una


arquitectura cliente/servidor distribuida. En este papel, sirve como enlace
entre los sistemas informáticos «frontales» (front-end) optimizados para
interactuar con el usuario y los sistemas «de apoyo» (back-end) especializados
para gestión de bases de datos, permitiendo que cada sistema rinda lo mejor
posible. También permite que las computadoras personales funcionen como
frontales de bases de datos mayores dispuestas en minicomputadoras y

Material de estudio Página: 229 de 249


Visual Basic 6.0 y SQLServer 7.0

mainframes, proporcionando acceso a datos corporativos desde aplicaciones


informáticas personales.

SQL Y EL PROCESAMIENTO DE TRANSACCIONES

SQL y las bases de datos relacionales habían tenido históricamente muy poco
impacto en las aplicaciones de procesamiento de transacciones en línea
(OLTP). Al hacer énfasis en las consultas, las bases de datos relacionales se
confinaron, además, al soporte de decisiones y aplicaciones en línea de bajo
volúmen, en las cuales su rendimiento más lento era una desventaja. Para
aplicaciones OLTP, donde cientos de usuarios necesitan acceso en línea a los
datos y tiempos de respuesta por debajo del segundo, el Information
Management System (IMS) no relacional de IBM predominaba como DBMS.

En 1986 un nuevo vendedor DBMS, Sybase, introdujo una nueva base de datos
basada en SQL diseñada especialmente para aplicaciones OLTP. El DBMS
Sybase corría en minicomputadoras VAX/VMS y en estaciones de trabajo Sun,
y se centraba en obtener un rendimiento en línea máximo. Oracle Corporation
y Relational Technology siguieron en breve con anuncios de que también ellos
ofrecerían versiones OLTP de sus populares sistemas de base de datos Oracle
e Ingres. En el mercado UNIX, Informix anunció una versión OLTP de su DBMS,
llamada Informix-Turbo.

En abril de 1988 IBM supo subirse al tren del OLTP relacional con DB2 Versión
2, cuyos programas de prueba mostraban que la nueva versión operaba por
encima de 250 transacciones por segundo en mainframes; IBM proclamó que
el rendimiento de DB2 era ahora adecuado para casi todas las aplicaciones
OLTP excepto las más exigentes, y animó a los clientes a considerarla como
una serie alternativa a IMS. Los bancos de prueba de OLTP se han convertido
ahora en una herramienta estándar de ventas para base de datos relacionales,
a pesar de serias cuestiones acerca de lo adecuado de esos programas para
medir efectivamente el rendimiento de aplicaciones reales.

La conveniencia de SQL para OLTP continúa mejorando, debido a los avances


en la tecnología relacional y a la mayor potencia del hardware que conducen a
tasas de transacciones cada vez más altas. Los clientes parecen considerar
ahora seriamente a DB2 y a las bases de datos relacionales para su utilización
en aplicaciones OLTP.

SQL EN COMPUTADORAS PERSONALES

SQL tuvo poco impacto en las computadoras personales hasta finales de los
ochenta, para entonces, ya éran comunes las PC potentes que soportaban
decenas o centenares de megabytes de almacenamiento en disco. Los
usuarios se conectaban, además, mediante redes de área local y deseaban
compartir bases de datos. En resumen, las PC comenzaron a necesitar las
características que SQL y las bases de datos relacionales podían
proporcionarles.

Las primeras bases de datos basadas en SQL para computadoras personales


fueron versiones de los productos populares para minicomputadoras que

Material de estudio Página: 230 de 249


Visual Basic 6.0 y SQLServer 7.0

difícilmente se ajustaban a las computadoras personales. Professional Oracle,


anunciado en 1984, requería 2 Mb de memoria en un IBM PC, y Oracle
Macintosh, anunciado en 1988, tenía exigencias análogas; una versión PC de
Ingres anunciada en 1987, entraba (aunque muy justamente) dentro del límite
de 64O KB de MS-DOS; Informix-SQL para MS-DOS fue anunciado en 1986,
proporcionando una versión PC de la popular base de datos UNIX. También
en 1986, Gupta Technologies, una empresa fundada por un ex-diretor de
Oracle, anunció SQLBase, una base de datos para redes de área local PC.
SQLBase estuvo entre los primeros productos PC en ofertar una arquitectura
cliente/servidor, un avance de los anuncios de bases de datos OS/2 por llegar.

SERVIDORES DE BASE DE DATOS BASADOS EN SQL

A finales de 1989 aparecieron una gran cantidad de anuncios de servidores de


bases de datos bajo OS/2 y cuatro de los productos emergieron como líderes
en el mercado de servidores de bases de datos como :

• OS/2 Extended Edition. Aunque su versión servidora aún no estaba


comercializada, todos esperaban que el gestor de base de datos OS/2 de
IBM jugara un papel importante en el mercado de servicios os/2.

• SQL Server de Microsoft. Respaldado por dos de los tres principales


desarrolladores de software para PC, este servidor aparecía como el jugador
independiente más fuerte. Tenía la ventaja de una buena tecnología
(procedente de Sybase), publicidad excelente y una distribución
establecida.

• Oracle para OS/2 de Oracle. La versión OS/2 del DBMS relacional


independiente más importante reforzaba la buena conexión con las bases
de datos Oracle sobre minicomputadoras y mainframes, con la potencia de
la fuerza de ventas directas de Oracle.

• SQL Base de Gupta. El primer vendedor con una base de datos en PC


LAN fue el más pequeño de los cuatro y un contendiente oscuro, pero el
servidor era real, tenía buenas herramientas frontales gráficas, estaba
comercializándose (lo que no era necesariamente cierto de los otros tres) y
funcionaba.

Existían además, productos servidores de bases de datos de Novell (NetWare


SQL), XDB System (XDB Server) y de otras compañías más pequeñas.

La arquitectura cliente/servidor también estimuló el desarrollo de


herramientas de bases de datos frontales que podían funcionar con los nuevos
servidores, quizá el producto frontal más significativo fue Dbase IV, que
Ashton-Tate anunció funcionaría como frontal de SQL Server y de OS/2
Extended Edition. Paradox y DataEasy otras dos bases de datos en PC,
también anunciaron frontales para tres o cuatro de los principales servidores.
Cada vendedor de servidor también ofertó sus propios productos frontales,
incluyendo herramientas de desarrollo de aplicaciones, consultas orientadas a
ventanas y facilidades de entradas de datos, herramientas de inspección de la
base de datos y otras.

Material de estudio Página: 231 de 249


Visual Basic 6.0 y SQLServer 7.0

El modelo cliente/servidor de OS/2 también significó un nuevo incentivo para


las bases de datos basadas en MS-DOS. Aunque los servidores requerían
típicamente la potencia del sistema OS/2, un PC basado en MS-DOS era
adecuado como sistema frontal para muchas aplicaciones, tales como entrada
de datos, elaboración de informes y consultas interactivas.

Conforme los años ochenta finalizaban, el papel de los servidores de base de


datos basados en SQL y OS/2 se convertía en uno de los temas más novedosos
en la prensa informática. Sin embargo, el tamaño último del mercado, la
aceptación por parte de los clientes de los sistemas y el relativo éxito de los
fabricantes, siguen siendo cuestiones abiertas a resolver en los noventa.

4.1.1 CONCEPTOS Y CONSULTAS

SQL se divide en cuatro grandes categorías de servicios, los cuales son :

I. Lenguaje de definición de Datos (DDL: Data Definition Language).


Consiste en comandos para definir objetos en la base como tablas, vistas,
índices e integridad de datos; mediante estos comandos, el DBMS verifica
que las acciones que el usuario aplica a los objetos se realicen
correctamente.

II. Lenguaje de manipulación de datos (DML: Data Manipulation Language).


Son comandos que le permiten al usuario seleccionar, actualizar, insertar o
borrar información en la Base de Datos. Este acceso a los datos y funciones
de manipulación es la razón principal de usar un DBMS.

III. Lenguaje de control de Datos (DCL: Data Control Language).


Consiste en comandos que controlan la ejecución de otros comandos.
Existen comandos para el manejo de concurrencia, seguridad y consistencia
en la Base; por ejemplo, existen comandos que controlan la ejecución de un
transacción y restauración de datos si ésta falla.

IV. Program Language Constructs. Son comandos que no pueden ser


usados en un modo interactivo con SQL, éstos sólo pueden ser usados
desde un lenguaje de programación externo al del DBMS. Su propósito es
facilitar la interface entre SQL y los lenguajes de programación, como “C”.

La tabla 4.3 muestra los cuatro servicios que ofrece SQL, así como algunos
comandos de cada uno de estos grupos.

SERVICIO COMANDOS RELACIONADOS


DDL CREATE, DROP, ALTER TABLE
DML DELETE, INSERT, SELECT, UPDATE
DCL COMMIT, ROLLBACK, GRANT, REVOKE, LOCK
Program Lenguage TABLE
BEGIN, DECLARE SECTION, EXECUTE, DECLARE
Constructs CURSOR, OPEN, CLOSE, FETCH
TABLA 4.3 Ejemplos de comandos de servicios de SQL.

Material de estudio Página: 232 de 249


Visual Basic 6.0 y SQLServer 7.0

ARQUITECTURAS DE BASES DE DATOS

Las figuras 4.5, 4.6 Y 4.7 muestran tres arquitecturas para manejar en forma
remota bases de datos; tales como: proceso por cliente (process-per-client),
multihilos e híbrido.

• La arquitectura de proceso por cliente proporciona un máximo de


protección de los procesos, dando a cada base de datos cliente, su propio
espacio de dirección para procesos. La base de datos corre en uno o más
procesos formados por separado. La ventaja de esta arquitectura es que
protege a un usuario de los otros y también protege al administrador de la
base de datos de los usuarios. Además, el proceso puede ser fácilmente
cambiado a otro procesador o una máquina multiprocesador SNMP
(Protocolo para la administración de red simple, “Simple Network
Management Protocol”), ya que la arquitectura depende del sistema
operativo local para los servicios de multitarea. La desventaja de proceso
por cliente es que utilizan más memoria y recursos del CPU que los
esquemas alternativos e incluso puede ser lento ya que los procesos se
intercambian y usan IPC. Sin embargo, estos problemas pueden ser
superados fácilmente con el uso de monitor de procesamiento de
transacciones (TP monitor) que maneje una ronda de procesos reusables.

Proceso
Servidor

Proceso
Base de Datos

Proceso

Procesos en Servidor
Clientes Dedicado

Fig. 4.5. Arquitectura de Proceso por Cliente.

• La arquitectura multihilos ofrece la mejor ejecución corriendo todos los


usuarios conectados, las aplicaciones y la base de datos en el mismo
espacio de direcciones. Esta arquitectura proporciona su propio
programador de tiempos que conserva memoria y capacidad de trabajo del
CPU pues no requiere de intercambios frecuentes de contexto.

Material de estudio Página: 233 de 249


Visual Basic 6.0 y SQLServer 7.0

Servidor

Base de Datos

Procesos
Multihilos

Clientes

Fig. 4.6. Arquitectura Multihilos.

Además, las implemetaciones en el servidor tienden a ser más portables


entre diferentes plataformas ya que no requiere de muchos servicios del SO
local. La desventaja es que un mal comportamiento de las aplicaciones del
usuario puede tirar todo el servidor de la base de datos y sus tareas.
Incluso, los programas de usuario que tienen una duración larga puede
consumir todos los recursos del servidor. Finalmente la programación previa
de tareas ofrecida por el servidor tiende a ser inferior que la del SO.

• La arquitectura híbrida consiste de tres componentes: 1) red multihilos


atenta a escuchar que participe en la conexión inicial de tarea al asignar el
cliente al despachador; 2) despachadores son tareas que ponen mensajes
en una cola de mensajes internos y entonces toma la respuesta y la envía
de regreso al cliente; y 3) El servidor de procesos reusables y compartidos
que remueve los trabajos para liberarlos de la cola, los ejecuta y coloca la
respuesta sobre una cola de salida. La ventaja de esta arquitectura es que
ofrece un ambiente protegido para correr las tareas de usuario sin asignar
un proceso permanente a cada usuario. Las desventajas son colas latentes.
Esta arquitectura es en apariencia buena, su carga de balance no es tan
buena como en un monitor TP; de hecho, las colas pueden estar en forma
de monitores TP teniendo sus propios algoritmos de programación de
tareas. El primer servidor de base de datos que implementa esta
arquitectura es Oracle.

Material de estudio Página: 234 de 249


Visual Basic 6.0 y SQLServer 7.0

Servidor
Proceso Proceso

Base de
Proceso Proceso Datos

Cola
de
Solicitud
Proceso Respuesta Proceso

Pool Pool de
Programa Despachador Proceso en
Escucha Compartido Servidor
Clientes Compartido

Fig. 4.7. Arquitectura Híbrida.

4.1.2 INTEGRIDAD Y TRANSACCIONES

INTEGRIDAD DE DATOS

El término integridad de datos se refiere a mantener la consistencia y


validación de los datos almacenados en una base, el contenido de ésta puede
perderse de muchas formas al momento de realizar modificaciones. Ante esto,
SQL cuenta con características que ayudan al DBMS en la tarea de preservar
la integridad de los datos con el objeto de restringir los valores creados o
insertados por actualizaciones en la base, como son:

• Datos requeridos: Impide la existencia de valores nulos en campos


donde sólo se permite un valor de dato válido.

• Comprobación de validez: Sólo permite insertar valores que se


encuentren definidos en el rango especificado para el campo.

• Integridad de entidad: Verifica la unicidad para claves primarias.

• Integridad referencial: Comprueba la relación que para cada llave


foránea exista una llave primaria.

• Consistencia: Comprobación de que un conjunto de sentencias tengan


efecto en su totalidad en la base de datos y en caso de falla (sea por
Software o por Hardware) ninguna de éstas sea realizada, a estos controles
se les denomina transacciones, que son tema de este inciso.

• Reglas comerciales: La actualización de datos pueden estar


restringidas por reglas establecidas por las empresas. Las transacciones
que se realizan en el mundo real están representadas por las
actualizaciones a las bases de datos. El DBMS puede comprobar cada nuevo
dato introducido, asegurándose que sus valores no violan las reglas

Material de estudio Página: 235 de 249


Visual Basic 6.0 y SQLServer 7.0

comerciales, estos procesos pueden ser implantados en la base a través de


los eventos llamados disparadores que se explicarán más adelante.

TRANSACCIONES

SQL posibilita que la secuencia de actualizaciones a una base de datos pueda


ser proposiciones “todo o nada” mediante sus características de
procesamiento de transacciones.

Una transacción es un bloque secuencial de trabajo formado por una o más


sentencias SQL relacionadas e interdependientes.

El DBMS basado en SQL comprueba que la secuencia de sentencias entera se


efectúe asegurando la integridad de la base de datos. “O todas las
sentencias son ejecutadas con éxito, o ninguna de las sentencias es
ejecutada”. El manejador tiene este compromiso incluso si el programa de
aplicación aborta o se produce un fallo hardware a mitad de la transacción.

A efecto de soportar las transacciones de base de datos, SQL utiliza las


sentencias COMMIT y ROLLBACK ( Figura 4.8).

COMMIT: Señala el final con éxito de una transacción; informa al DBMS que
todas las sentencias que forman la transacción han sido ejecutadas y la base
de datos es autoconsistente.

ROLLBACK: Señala el final sin éxito de una transacción, informando que un


usuario no desea completar ésta, ante esto, el DBMS debe deshacer los
cambios realizados en la base a fin de restaurar a la base de datos a su estado
previo al inicio de la transacción.

B .D .
c o n s is te n t e
U PD ATE U PD A TE U P D A TE
T ra n s a c c ió n C O M M IT
C O M M IT C O M M IT C O M M IT

B .D .
c o n s is te n t e

IN S E R T IN S E R T IN S E R T IN S E R T

T ra n s a c c ió n D ELETE
(F a llo d e
D E LE TE E l p ro g ra m a
H a rd W a re ) a b o rta
C O M M IT
R OLLBAC K E l p ro g ra m a
acaba
B .D .
c o n s is te n t e

Fig. 4.8. Transacciones en una base de datos utilizando sentencias


COMMIT y ROLLBACK

Material de estudio Página: 236 de 249


Visual Basic 6.0 y SQLServer 7.0

EL MODELO DE TRANSACCIÓN ANSI/ISO.

El modelo de transacción SQL (que está basado en DB2), está definido bajo el
estándar ANSI/ISO, así como la función de COMMIT y ROLLBACK. El estándar
especifica que una transacción SQL comienza automáticamente con la primera
sentencia SQL y continúa en forma secuencial con las sentencias SQL
subsiguientes hasta finalizar de uno de los cuatro siguientes modos:

Para SQL programado Para SQL interactivo


COMMIT finaliza la transacción con éxito haciendo La terminación de un programa con éxito también
los cambios en la base permanentes. Se inicia finaliza la transacción correctamente; sin embargo,
inmediatamente una nueva transacción después puesto que el programa está finalizado no hay
de esa sentencia COMMIT. ninguna transacción que comenzar.

ROLLBACK aborta la transacción, deshaciendo las La terminación anormal de un programa también


modificaciones hechas a la base. Se inicia aborta la transacción; pero puesto que el programa
inmediatamente una nueva transacción después está finalizado no hay ninguna transacción que
de la sentencia ROLLBACK. comenzar

4.1.3 VISTAS

Una vista es una tabla virtual generada por una consulta a partir de una o
varias tablas, en la vista, SQL permite el acceso y modificación de los datos
como si fuera una tabla real.

Una vista no existe en la base de datos, es la definición de la vista la que se


almacena permanentemente en la base, al efectuar una consulta los datos
visibles son el resultado de esta, ver figura 4.9

S e n te n c ia S Q L c o n
re fe r e n c ia a u n a v is t a

L o s r e s u lta d o s s o n D e f in ic ió n d e la v is t a
p r e s e n t a d o s a l u s u a r io . a lm a c e n a d a e n la B . D .

T r a d u c c ió n d e la p e t ic ió n e n la
S e lle v a a c a b o la
c o n s u lt a c o n r e s p e c t o a la s
p e t ic ió n e q u iv a le n t e .
t a b la s f u e n t e s d e la v is t a .

Material de estudio Página: 237 de 249


Visual Basic 6.0 y SQLServer 7.0

Fig. 4.9 Desarrollo de una Vista en SQL.

Al usar las vistas se obtiene los siguientes beneficios:

• Seguridad al mostrar solo los datos autorizados al usuario.


• Simplicidad de consultas multitabla, presentadas como consultas de una
sola tabla.
• La estructurada de la BD no se altera ante las consultas
• Integridad de datos. Comprobación de las restricciones de integridad de
los datos introducidos a través de la vista.

Al crear una vista, se debe considerar que el DBMS debe traducir las
consultas, con respectos a las tablas fuentes relacionadas. Para consultas
complejas multitabla, la vista se convierte en una combinación complicada y
puede tardar mucho tiempo en completarse. Si el usuario trata de actualizar la
información en la vista, el DBMS debe traducir la petición de actualización a
las tablas relacionadas en la vista, dado lo complejo de este proceso este tipo
de vista son creadas de sólo lectura.

El estándar SQL ANSI/ISO, especifica las vistas que pueden ser actualizadas,
en base a las consultas que las define, las cuales deben cumplir con las
siguientes condiciones:

• Las filas duplicadas no deben de ser suprimidas.


• Sólo una tabla fuente relacionada en la vista puede ser actualizadas
siempre que el usuario tenga los privilegios requeridos.
• Cada elemento de selección, debe de ser una referencia de columna
simple, la lista de selección no puede contener expresiones, columnas
calculadas o funciones de columna
• No se puede definir una subconsulta en la cláusula WHERE.
• La consulta no debe incluir GROUP BY o HAVING
Estas restricciones se pueden resumir en el siguiente concepto:

“Para que una vista sea actualizable el DBMS debe ser capaz de relacionar
cualquier fila de la vista con la fila fuente. Análogamente, el DBMS debe ser
capaz de relacionar cada columna individual a actualizar con su columna
fuente.”

Si la vista satisface esta comprobación es posible definir operaciones INSERT,


DELETE y UPDATE, y tener efecto sobre los datos fuente.

Tipos de Vistas:

• Horizontales: Muestran sólo las filas seleccionadas sobre una tabla.

• Verticales: Permiten accesar sólo a ciertas columnas seleccionadas de


una tabla, cada fila de la tabla fuente está representada en la vista.

• Con subconjuntos Fila/Columna: Los datos visibles son un


subconjunto de fila/columna de una tabla, contiene las columnas
designadas y las filas que satisfacen una condición de búsqueda.

Material de estudio Página: 238 de 249


Visual Basic 6.0 y SQLServer 7.0

• Agrupadas: Agrupación de filas relacionadas, generando una fila de


resultados de consulta por cada grupo y sumarizando los datos de ese
grupo, en estas vistas se requiere mucho tiempo de procesamiento a
efecto de mantener la tabla virtual, no se puede actualizar debido, a que no
hay modo de trasladar la petición de actualización de la vista a las filas de
la tabla fuente, este tipo de vistas son de sólo lectura.

• Compuestas: Extracción de datos de dos o más tablas diferentes, en la


que cada fila es la combinación de una fila de cada tabla fuente, en estas
vistas el tiempo de procesamiento es considerable, si la consulta llega a ser
demasiado compleja, la vista se vuelve de sólo lectura.

Se pretende que todas las vistas lleguen a ser actualizadas en un tiempo


mínimo de proceso, pero esto aún se encuentra en proceso de investigación.

4.1.4 SEGURIDAD

La seguridad de la información almacenada en la base de datos es


especialmente importante en un DBMS basado en SQL. La implementación de
un esquema de seguridad y el reforzamiento de las restricciones de seguridad
son responsabilidad del Software del DBMS. El lenguaje SQL define un
panorama general para la seguridad de la Base de Datos, y la sentencias SQL
son utilizadas para especificar restricciones de seguridad, el cual se basa en
tres conceptos principales:

• Los usuarios son los principales demandantes de la información almacenada


en la Base de Datos. Cada vez que el DBMS accesa a la base de datos, para
recuperar, insertar, suprimir o actualizar datos, lo hace a cuenta de algún
usuario, por lo que el DBMS permitirá o prohibirá la acción dependiendo de
qué usuario esteé efectuando la petición.

• Los objetos de la base de datos son los elementos a los cuales se puede
aplicar la protección de seguridad. La seguridad se aplica generalmente a
tablas y vistas, pero otros objetos tales como formularios, programas de
aplicación y bases de datos enteras también pueden ser protegidos.

• Los privilegios son las acciones que un usuario tiene permitido efectuar
para un determinado objeto de la base de datos, por ejemplo, un usuario
puede tener permiso para recuperar o insertar datos en una tabla
determinada, pero se le puede negar el permiso de borrar o actualizar
datos. A cada usuario se le pueden dar diferentes permisos para acceder a
la base de datos.

Para establecer un esquema de seguridad en una base de datos, es utilizada


la sentencia SQL, GRANT y REVOKE para negar el acceso, como lo muestra el
siguiente ejemplo:

Material de estudio Página: 239 de 249


Visual Basic 6.0 y SQLServer 7.0

G R A N T S E L E C T , IN S E R T ID E N T IF IC A D O R D E
O N L IB R O S L P E R M IS O S D E : U S U A R IO
TO JOS E I
B
B ase de C O N SU LTAR
R JO S E
O D a to s
s e n te n c ia S Q L S
E IN S E R T A R
D ATO S

Fig. 4.10 Acceso a Usuarios a la Base de Datos.

La sentencia GRANT especifica una combinación de un identificador de usuario


(ID-usuario José), un objeto (La tabla Libros) y privilegios concedidos para
recuperar e insertar datos. De forma análoga, se pueden negar los accesos
permitidos si se cambia la palabra GRANT por REVOKE en el ejemplo anterior.

A cada usuario de la base de datos basada en SQL se le asigna un ID-usuario,


que es un nombre breve que lo identifica dentro del DBMS. Todas las
sentencias SQL ejecutadas por el DBMS se llevan a cabo a cuenta de un ID-
usuario específico, el DBMS, entonces, determina si el ID-usuario se le han
concedido privilegios para la sentencia que ha solicitado. El estándar SQL
ANSI/ISO utiliza el término ID-autorización que, técnicamente es más
adecuado, la razón de que se utilice este término, es que algunos DBMS
utilizan el ID-usuario que es asignado para ingresar al sistema.

Los ID-usuarios están asociados con programas o grupos de programas, más


que con personas.

En ciertas bases de datos con frecuencia existen grupos de usuarios con


necesidades similares. Bajo el esquema de seguridad de SQL ANSI/ISO, se
pueden manejar grupos de usuarios con similares necesidades de dos formas
diferentes:

1 Se puede asignar un ID-usuario único a todas las personas del grupo, esto
simplifica la administración de la base de datos, ya que los privilegios de
acceso a datos se asignan al único ID-usuario del grupo, pero la desventaja
consiste en que las personas que comparten el ID-usuario no podrán
distinguirse en las visualizaciones del operador del DBMS, ni en los informes
del DBMS.

2 Se puede asignar un ID-usuario diferente a cada persona del grupo, dando


la ventaja de asignar diferentes privilegios de acceso a los datos a cada
usuario y distinguirlos en los informes producidos por el DBMS. Sin
embargo, esto hace que la administración de la seguridad de la base de
datos sea tediosa y propensa a errores.

Por lo tanto, el esquema de seguridad que se elija, dependerá particularmente


de los compromisos de cada base de datos y aplicaciones para lo que hayan
sido creadas.

Las protecciones de seguridad en el estándar SQL ANSI/ISO se aplican a dos


objetos específicos, tablas y vistas. Así cada tabla y vista en la base de datos
puede ser individualmente protegida. El acceso a una tabla o vista puede ser

Material de estudio Página: 240 de 249


Visual Basic 6.0 y SQLServer 7.0

permitido para ciertos ID-usuarios y prohibido para otros. El conjunto de


acciones que un usuario puede efectuar sobre un objeto en la base de datos
se denomina: privilegios que el usuario tiene sobre éste.

El estándar SQL ANSI/ISO especifica cuatro privilegios sobre los objetos:

1Recuperación de datos
2Inserción de datos
3Supresión de datos
4Actualización de datos. Posibilita la restricción de columnas específicas,
permitiendo actualizaciones y desautorizando a cualquier otra
columna.

Estos cuatro privilegios son soportados por casi todos los productos SQL
comerciales, sin embargo, la mayoría soporta más de lo que el estándar
ANSI/ISO ha definido.

Otro privilegio que es importante mencionar es el de propiedad y éste es


otorgado al usuario al instante que crea un objeto (tabla o vista) en la base de
datos. Quien crea un objeto en la base de datos se convierte en su propietario
y recibe totales privilegios sobre éste, como son: recuperación, inserción,
supresión y actualización de datos. Sin embargo, hay que tomar en cuenta que
para crear una vista, hay que contar con los privilegios de recuperación de
datos y sí se tienen los demás privilegios el DBMS los concederá.

Al crear un usurario un objeto, éste es el único que puede otorgar privilegios a


otros usuarios para autorizar el acceso a este objeto. Por lo que los privilegios
otorgados no podrán ser transmitidos por quien(es) lo(s) haya(n) recibido. De
este modo, el propietario de un objeto mantiene un control muy estricto sobre
quien tiene permiso para autorizar el objeto y sobre qué formas de acceso se
permiten. Sin embargo, la mayoría de los productos SQL, cuentan con
opciones de transmisión de privilegios en cascada, dando mayor flexibilidad
del control del objeto al propietario.

4.1.5 TRIGGERS “DISPARADORES”

Antes de iniciar el tema de disparadores, es necesario mencionar algunos


conceptos.

El estándar SQL ANSI/ISO utiliza la sentencia CREATE TABLE para especificar


restricciones de unicidad en columnas o combinaciones de columnas. Sin
embargo, los valores NULL presentan un problema cuando aparecen en la
clave primaria de una tabla o en una columna que está especificada en una
restricción de unicidad.

Por ejemplo, supongamos que se intentase insertar una fila con una clave
primaria que fuera NULL (o parcialmente NULL, si la clave primaria está
compuesta por más de una columna), debido al valor NULL, el DBMS no puede
decidir concluyentemente si la clave primaria está o no duplicada con
respecto a otra que ya existe. La respuesta debe ser “quizás”, dependiendo
del valor “real” del dato que falta (NULL).

Material de estudio Página: 241 de 249


Visual Basic 6.0 y SQLServer 7.0

Por esta razón, SQL requiere que toda columna que forma parte de una clave
primaria y toda columna designada en una restricción de unicidad debe ser
declarada NOT NULL.

SQL también cuenta con la restricción de integridad referencial, la cual es una


parte esencial del modelo relacional desde que fue propuesto por el Dr. Codd,
donde se asegura la integridad de las relaciones padre/hijo, creadas mediante
claves foráneas y claves primarias.

Los siguientes puntos resúmen los problemas de actualización a la base de


datos que pueden corromper la integridad referencial:

• Inserción o actualización de una fila “hijo”: Cuando se inserta o


actualiza una fila en la tabla hijo, su valor de clave foránea debe coincidir
con uno de los valores de la clave primaria en la tabla padre.

• Supresión o actualización de una fila padre: El DBMS detecta error


si se intenta borrar o actualizar una fila de la tabla “padre” a la cual se está
haciendo referencia por otra fila de la tabla “hijo”.

Aunque el estándar SQL ANSI/ISO no proporciona en su totalidad la solución de


los puntos anteriores, existen algunos DBMS como DB2, SQL Windows y
SyBASE que incluyen el manejo de integridad referencial más completo.

Citando algunos ejemplos tenemos las siguientes cláusulas:

• RESTRICT: Impide suprimir una fila de la tabla padre si la fila tiene


alguna fila hijo.

• CASCADE: Si una fila padre es suprimida, también son suprimidas todas


las filas hijo.

• SET NULL: Si una fila padre es suprimida, los valores de la clave


foránea en todas las filas hijo deben ser actualizadas al valor NULL.

El concepto de disparador se puede definir como: “Para cualquier evento que


provoca un cambio en el contenido de una tabla, se puede especificar una
acción asociada al DBMS que debe efectuar”.

Las sentencias que pueden disparar una acción son:

• INSERT
• DELETE
• UPDATE

La acción disparada por estas cláusulas son especificadas mediante una


secuencia de sentencias SQL, como lo muestra el siguiente ejemplo:

CREATE TRIGGER NUEVO PEDIDO

ON PEDIDOS
FOR INSERT
AS UPDATE REPVENTAS
SET ventas = ventas + Inserted.importe

Material de estudio Página: 242 de 249


Visual Basic 6.0 y SQLServer 7.0

FROM Repventas , Inserted


WHERE Repventas.num_empl = Inserted.rep

UPDATE Productos
SET existencias = existencias - Inserted.cant
FROM Productos , Inserted
WHERE Productos.id_dir = Inserted.fab
AND Productos.id_producto = Inserted.producto

Otras extensiones no mostradas en el ejemplo incluyen sentencias


IF/THEN/ELSE, iteraciones, llamadas de procedimiento, e incluso sentencias
PRINT que visualizan mensajes de usuario.

Los disparadores proporcionan un modo alternativo de implementar las


restricciones de integridad referencial, proporcionadas por claves foráneas y
primarias. De hecho los defensores de esta característica, señalan que el
mecanismo disparador es mucho más flexible que la integridad referencial
proporcionada por algunos DBMS e incluso por el estándar SQL ANSI/ISO.

La principal ventaja de los disparadores, es que las reglas comerciales pueden


almacenarse en las bases de datos y ser forzadas consistentemente con cada
actualización que tengan. Esto puede reducir substancialmente la complejidad
de los programas de aplicación que acceden a la base de datos. Sin embargo,
algunas desventajas son:

• Complejidad de la Base de Datos: Cuando las reglas se trasladan al


interior de la base, prepararla, pasa a ser una tarea más compleja. Los
usuarios que razonablemente podían esperar crear pequeñas aplicaciones
propias con SQL, encontrarán que la lógica del programa de los
disparadores hace la tarea mucho más difícil.

• Reglas Ocultas: Con las reglas ocultas dentro de la base de datos,


programas que parecen efectuar sencillas actualizaciones, pueden de
hecho, generar una enorme actividad en la base. El programador ya no
controla totalmente lo que sucede en la base de datos.

Los disparadores están ausentes del estándar SQL ANSI/ISO, aunque algunos
vendedores de DBMS han proclamado públicamente planes para añadir las
características de los disparadores a las versiones futuras de sus productos, la
importancia futura es un poco nebulosa y solamente el tiempo dirá si se
convierten en parte importante del entorno SQL.

Material de estudio Página: 243 de 249


Visual Basic 6.0 y SQLServer 7.0

Conclusiones

La arquitectura computacional C/S es la primera solución en tecnología informática que satisface


las demandas actuales de costo-rendimiento, ofreciendo la optimización de las tareas existentes y
agregando nuevas funcionalidades. Es por eso que se observa una clara tendencia ha
implementar este modelo. Siendo sus ventajas, que la capacidad de cómputo está determinada
por todos los equipos interconectados con que se cuenta, agregación de nuevas funcionalidades
y una considerable reducción de tráfico en la red, ya que las operaciones de procesamiento se
jerarquizan y la red da prioridad a las necesidades del usuario, transmitiéndole información
realmente útil. Esto constituye un estimulo al uso de sistemas abiertos dado que tanto clientes
como servidores operan en diferentes plataformas de hardware y software, lo cual permite
comprar productos de diferentes proveedores sin interferir en el desempeño de las demás
aplicaciones y equipos instalados.

Las cualidades que ofrece esta arquitectura son interesantes y muy convincentes, pero esto no
significa que sea perfecta, sobre todo cuando lo que se persigue es la integración plena de
ambientes heterogéneos, por lo cual se enfrenta a :

• Las diferentes capas de software de interoperabilidad (middleware) pueden afectar en la


duplicidad de tareas.
• Muchas aplicaciones no son capaces de separar tareas por lo que el comportamiento en
la red será el de una arquitectura tradicional.
• Se requiere de una evaluación y planeación completas de la arquitectura C/S para
minimizar el tráfico y evitar la saturación del medio de comunicación. Aspecto que una
aplicación C/S bien diseñada si prevé.
• Como la administración de este ambiente es más complicada, los procesos y
herramientas al conectar equipo pueden complicar ampliamente las labores de administración
y control.
• El personal que se requiere para dar soporte y administrar el ambiente seguramente
tendrá que incrementarse. Primero porque al ser un medio abierto se requiere más personal.
Segundo porque al tratarse de medios abiertos se requieren más especialistas con
conocimientos en diversas tecnologías. Además los costos de mantenimiento también se
elevan, pues cada versión de una aplicación C/S se deberá probar en diferentes plataformas.

Todos estos obstáculos se pueden contrarrestar y quizá las grandes ventajas que ofrece un
ambiente abierto sean de mayor peso para emigrar a esta arquitectura.

Es importante recordar que la Tecnología C/S siempre tiene que ver con redes, lo contrario sería
falso, es decir no todas las redes trabajan bajo la arquitectura C/S. Esta pequeña pero importante
diferencia abre una brecha enorme en el tipo de productos o servicios que el usuario puede
adquirir para aprovechar su equipo. El conocer el verdadero significado del concepto es de
trascendental importancia para quien desea tener una solución productiva y debe cuidar que
quien lo vende, o le asesora, realmente le ofrezca una arquitectura C/S.

Material de estudio Página: 244 de 249


Visual Basic 6.0 y SQLServer 7.0

I.2 Nomenclatura de Objetos

Prefijos de Controles
Tipo de Control Prefijo Tipo de Control Prefijo Tipo de Control
3D Panel pnl_ Horizontal scroll bar hsb_ Picture clip
ADO Data ado_ Image img_ ProgressBar
Animated button ani_ Image combo imgcbo_ Remote Data Control
Check box chk_ ImageList ils_ RichTextBox
Combo box, drop-down list box cbo_ Label lbl_ Shape
Command button cmd_ Lightweight check box lwchk_ Slider
Common dialog dlg_ Lightweight combo box lwcbo_ Spin
Communications com_ Lightweight command button lwcmd_ StatusBar
Control (usado para objetos ctr_ Lightweight frame lwfra_ SysInfo
genéricos)
Data dat_ Lightweight horizontal scroll bar lwhsb_ TabStrip
Data-bound combo box dbcbo_ Lightweight list box lwlst_ Text box
Data-bound grid dbgrd_ Lightweight option button lwopt_ Timer
Data-bound list box dblst_ Lightweight text box lwtxt_ Toolbar
Data combo dbc_ Lightweight vertical scroll bar lwvsb_ TreeView
Data grid dgd_ Line lin_ UpDown
Data list dbl_ List box lst_ Vertical scroll bar
Data repeater drp_ ListView lvw_ Graph
Date picker dtp_ MAPI message mpm_ Grid
Directory list box dir_ MAPI session mps_ Hierarchical flexgrid
Drive list box drv_ MCI mci_ OLE container
File list box fil_ Menu mnu_ Option button
Flat scroll bar fsb_ Month view mvw_ Picture box
Form frm_ MS Chart mch_ Remote Data Objects
Frame fra_ MS Flex grid mfg_ Data Acces Objects
Gauge gau_ MS Tab mst_ ActiveX Data Objects

Material de estudio Página: 245 de 249


Visual Basic 6.0 y SQLServer 7.0

Prefijos para Menús


Secuencia de Menú Ejemplo de Menú
Archivo mnu_Archivo
Archivo Abrir mnu_ArchivoAbrir
Archivo envíar correo mnu_ArchivoCorreo
Archivo envíar fax mnu_ArchivoFax
Formato carcater mnu_FormatoCaracter
Ayuda mnu_Ayuda

Nombres de Prefijos para otros Controles


Para otros controles no listados, se deberán estandarizar utilizando sólo letras minúsculas y el
guión bajo. Procurando sólo utilizar tres letras en los casos que el nombre sea descriptivo.

Material de estudio Página: 246 de 249


Visual Basic 6.0 y SQLServer 7.0

I.3 Convenciones de nombres de variables para Visual Basic

Los nombres de variables estarán determinados por el ámbito de la variable y el tipo.


1. Ambito de la variable.

Ambito Prefijo
Global g
Modular m
Local l
Parámetro p

2. Tipos de datos.

Tipo de dato Prefijo Bytes Rango Ejemplo


Boolean bln 2 True o False blnExiste
Byte byt 1 0 – 255 bytColor
Collection object col - - colForma
-922,337,203,685,477.5808 a
Currency cur 8 curPago
922,337,203,685,477.5807
Date (Time) dtm 8 01/01/100 a 31/12/9999. dtmNacimiento
Para valores negativos:
-1.79769313486232E308 a
Double (Precisión -4.94065645841247E-324
dbl 8 dblArea
de punto flotante) Para valores positivos:
4.94065645841247E-324 a
1.79769313486232E308
Sin punto decimal
+/-79,228,162,514,264,337,593,543,950,335
Decimal dec 14 decPIB
El valor más pequeño es:
+/-0.0000000000000000000000000001
Error err - - errNumero
Integer int 2 -32,768 a 32,767 intCantidad
Long (Integer) lng 4 -2,147,483,648 a 2,147,483,647 lngDistancia
Object obj 4 Cualquier referencia a un objeto objActual
Para valores negativos:
Single (Precisión -3.402823E38 a -1.401298E-45
sng 4 sngPromedio
de punto flotante) Para valores positivos:
1.401298E-45 to 3.402823E38
10 +
String (Longitud longitud
str strApellido
variable) de la 0 a 2 billones
cadena
longitud
String (Longitud
str de la strApellido
fija)
cadena 1 a 65,400
Tipo definido por - Dependiendo del tipo de dato asignado
udt udtEmpleado
el usuario
Variant vnt 16 Dependiendo del tipo de dato asignado vntSuma

Material de estudio Página: 247 de 249


Visual Basic 6.0 y SQLServer 7.0

3. Forzar que Visual Basic verifique la declaración de Variables


Declarar todas las variables reduce el tiempo de programación y los errores causados por
incompatibilidad de tipos.
VB permite utilizar variables sin que previamente hallan sido declaradas. Para forzar que VB
detecte las variables que no hallan sido declaradas realice lo siguiente.
i. Seleccione la opción del menú : Tools\Options...
ii. Se despliega un dialogo con distintas pestañas.
iii. Seleccione la pestaña de : Editor
iv. Marque la casilla de “Require Variable Declaration”
Esto forzará a que VB detecte las variables que no hallan sido declaradas en toda la aplicación.

4. Creación de nombres de Variables


El nombre de una variable debe ser descriptivo, para formar el nombre siga los siguientes pasos:
i. Primera letra : Determine el ámbito de la variable (global, modular o
local).
ii. Siguientes letras minúsculas : Determine el tipo de la variable.
iii. Primera letra mayúscula : Inicio del nombre de la variable.
iv. Siguientes letras minúsculas : Complemente el nombre de la variable.

Ejemplo : ldtmNacimento Donde


l = Ambito de lavariable local.
dtm = Tipo datetime.
Nacimiento = Nombre de la variable.

Ejemplo : gstrLogin Donde


g = Ambito de la variable global
str = Tipo string (cadena)
Login = Nombre de la variable.
Notas: Los tipos definidos por el usuario deberán ajustarse a las nomenclaturas antes
mencionadas.

5. Definición de constantes

i. El nombre debe comenzar con el prefijo: CTE_


ii. El nombre estará en mayúsculas.
iii. El nombre deberá ser descriptivo y podrá contener guión bajo “_”.
iv. Ejemplo: CTE_ARREGLO_INDICEMAXIMO = 32532

6. Definición de arreglos
i.El nombre debe comenzar con el ambito de la variable: g,m,l o p
ii.Prefijo de la variable: arr
iii.Aplicar la nomenclatura de tipos de datos para el arreglo.
iv. Nombre de la variable del arreglo (primera letra con mayúscula)
v. Ejemplo: marrblnPreguntas ;
m = Ambito de la variable modular.
arr = Arreglo.
bln = Tipo del arreglo boleano
Preguntas = Nombre de la variable.
Los tipos de datos definidos como arreglos requieren 20 bytes de memoria más 4 bytes por
cada dimensión del arreglo, más los bytes ocupados por el tipo de dato mismo.

7. Nomenclatura de parámetros.

Material de estudio Página: 248 de 249


Visual Basic 6.0 y SQLServer 7.0

Los parámetros deberán iniciar con el prefijo p y la composición del nombre de la variable
deberá ajustarse a la nomenclatura de tipos de datos.

Material de estudio Página: 249 de 249

También podría gustarte