Manual
Manual
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
Introducción
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.
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.
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.
Explorad
Formulari or
o De
proyecto
Ventana
de
Propieda
des
Ventana Código
de
depuraci
ón
(Debugg
er)
Ventana de
Posición
del
formulario
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.)
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:
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.
Botón Descripción
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:
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.
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.
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.
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.
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.
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.
Para declarar una variable se utiliza la sentencia Dim, dando un nombre a la variable.
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:
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
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.
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).
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
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).
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.
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 :
Visual Basic acepta una variedad de formatos de fechas y horas en forma literal. Estos son todos
los valores válidos de fecha/hora
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.
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.
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.
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.
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.
String * tamaño
También, para quitar los espacios en un string se utilizan las funciones Trim y Rtrim
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
Const Pl = 3.14159265
Global Const Juegos = 2
Const Fec-Ent = #2-5-94#
Const Codigo = "Enigma"
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
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
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
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
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
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:
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
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
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
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.
Operador: /
Se utiliza para dividir dos números y obtener un resultado de signo flotante.
Sintaxis
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
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
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: ^
Sintaxis
resultado = número ^ exponente
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.
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
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:
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:
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.
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:
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.
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
End lf
Ejemplo:
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
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”)
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
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).
Do While condición
declaraciones
Loop
Ejemplo:
Sub Command1_Click ( )
End Sub
Sub Command1_Click ( )
End Sub
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
Do Until condición Do
declaración declaración
Loop Loop Until condición
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
Ejemplo:
Sub Command1_Ciick ( )
Dim I, Msg, NL, Rep
End Sub
Ejemplo
Sub Form_Click()
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
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.
• Event procedures. Son procedimientos Sub, que responden a los eventos de los
controles.
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:
El arglist es una lista de nombres de argumentos, separados por comas (,) si hay más de uno. La
sintaxis de un argumento es:
Ejemplo
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
Muevelmagen 50
Function
Por ejemplo, se puede escribir esta función para calcular el IVA de una cantidad:
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
End Sub
Foo(intX)
End Sub
Sin embargo, este código no proporciona todos los argumentos como opcionales:
Dim strNombre As String
Dim varDirección As Variant
List1.AddItem strNombre
List2.AddItem varDirección
End Sub
Esto resulta especialmente útil si sus procedimientos tienen varios argumentos opcionales
que no siempre necesita especificar.
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 [ ].
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.
Ejemplos de arreglos:
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 .
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,
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( )
ReDim Arregio(Y + 1)
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:
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.
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
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.
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.
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.
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 –
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.
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
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
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
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.
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.
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
Descripció
Propiedades n breve de
(Properties Window) la
propiedad
• 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:
Para continuar con el ejemplo, añadir un segundo Command Button (Botón de comando) y
colocar la siguiente propiedad:
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.
• 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.
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
Sub Command2_Click()
End
End Sub
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
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
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
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.
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).
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"
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.
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
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]
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.
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.
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 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.
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.
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).
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
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.
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
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.
El primer paso es crear un objeto FileSystemObject para poder trabajar con él. Se puede realizar
ésto de dos formas:
Nota El primer método trabaja bajo VB, mientras que el segundo trabaja en VB y VBScript.
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.
Para accesar un existente drive, file, or folder, use el apropriado método "get" del objeto
FileSystemObject:
• GetDrive
• GetFolder
• GetFile
Por ejemplo:
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:
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 '
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.
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.
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.
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 (\\):
Ejemplo
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:
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):
Una vez que el archivo de texto ha sido creado, usted podrá adicionar datos de acuerdo con lo
siguiente:
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.
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.
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
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.
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
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
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".
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
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
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
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
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
Dir_Dir.Path = “d:\temp”
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.
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.
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:
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
¿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.
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"
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")
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.
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.
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.
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.
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.
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
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.
• Microcomputadoras:
Existe una gran base instalada en ellas
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.
• Incremento de desempeño.
• Incremento de la confiabilidad y disponibilidad.
• Modularidad y control local.
• Costos reducidos y un alto grado de confiabilidad.
INFRAESTRUCTURA
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
MANEJO DE INFORMACION
PROCESAMIENTO
SERVICIOS
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
MODELO COOPERATIVO
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
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.
DESCRIPCION FUNCIONAL
FRONT-END BACK-END
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.
En tanto que:
Software de
CLIENTE SERVIDOR
Comunicación
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 :
Acceso Dase de
Presentación Presentación Función Remoto de Datos
Distribuida Remota Distribuida Datos Distribuida
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
EL CLIENTE
EL SERVIDOR
SOFTWARE DE COMUNICACIÓN
LA RED
BONDADES Y DESVENTAJAS
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.
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.
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.
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.
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.
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.
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.
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:
Las aplicaciones y herramientas usan dos componentes para tener acceso a SQL Server:
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.
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-
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.
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:
• 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.
• Valores NULL
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
• 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 desencadenadores
• 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.
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.
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 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.
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 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.
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
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.
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.
• 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.
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)
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é.
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 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).
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
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)
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.
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.
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:
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.
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.
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.
É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.
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.
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.
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
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.
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.
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.
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
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.
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 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.
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:
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.
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.
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.
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 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 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.
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.
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.
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
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.
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.
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.
• 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.
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.
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
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.
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
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:
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
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):
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
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):
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.
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
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
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
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
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.
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.
Nota Cada vez que se cree una base de datos de usuario, debe hacerse una copia de seguridad
de la base de datos master.
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:
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.
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,
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
USE master
GO
CREATE DATABASE Products
ON
( NAME = prods_dat,
FILENAME = 'c:\mssql7\data\prods.mdf',
SIZE = 4,
MAXSIZE = 10,
FILEGROWTH = 1 )
GO
USE master
GO
CREATE DATABASE Products2
ON
( NAME = prods2_dat,
FILENAME = 'c:\mssql7\data\prods2.mdf' )
GO
MAXSIZE = 25MB,
FILEGROWTH = 5MB )
GO
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
sp_detach_db Archive
GO
CREATE DATABASE Archive
ON PRIMARY (FILENAME = 'c:\mssql7\data\archdat1.mdf')
FOR ATTACH
GO
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
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.
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.
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.
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
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.
SQL Server utiliza las propiedades IDENTITY y ROWGUIDCOL para implementar columnas de
identificadores.
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:
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.
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:
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.
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.
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.
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.
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.
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.
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.
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.
En cada tabla sólo se puede crear una columna de identificadores y una columna de
identificadores exclusivos globales.
Cuando utilice la propiedad IDENTITY para definir una columna de identificadores, tenga en
cuenta lo siguiente:
• 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.
• 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.
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..
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.
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.
Permisos
De forma predeterminada, todos los usuarios tienen permisos para ejecutar SET ANSI_NULLS.
Por ejemplo
use pubs
set ansi_nulls off
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.
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.
USE pubs
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
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
USE Ejemplo
go
BEGIN TRANSACTION
COMMIT TRANSACTION
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
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.
*/
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
/* 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).
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
SET XACT_ABORT ON
BEGIN TRANSACTION
COMMIT TRANSACTION
go
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.
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.
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.
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:
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.
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:
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'
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.
Ejemplos
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:
title ytd_sales
------------------------------------------------------------ -----------
Fifty Years in Buckingham Palace Kitchens 15096
(1 row(s) affected)
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])
• 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
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).
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
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.
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.
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
1.5.5.2 GOTO
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.
1.5.5.4 RETURN
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.
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.
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
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.
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.
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.
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:
• 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.
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
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.
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
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.
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
tener cuidado todavía al utilizar la información de estado que devuelven los 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
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
• 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
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'
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)
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.
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
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.
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
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.
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.
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
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).
}
|
{FOR { [INSERT] [,] [UPDATE] }
[WITH APPEND]
[NOT FOR REPLICATION]
AS
{ IF UPDATE (columna)
[{AND | OR} UPDATE (columna)]
[...n]
| IF (COLUMNS_UPDATED() {operadorNivelBit} máscaraBitsActualizada)
{ operadorComparación} máscaraBitsColumna [...n]
}
instrucciónSQL [...n]
}
}
Argumentos
nombreDesencadenador
tabla
WITH ENCRYPTION
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
AS
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.
SELECT *
FROM deleted
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.
IF (COLUMNS_UPDATED())
operadorNivelBit
máscaraBitsActualizada
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.
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.
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.
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
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
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
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
Anexos
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.
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.
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 >
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.
ARQUITECTURA CENTRALIZADA
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.
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
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.
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 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.
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.
La tabla 4.3 muestra los cuatro servicios que ofrece SQL, así como algunos
comandos de cada uno de estos grupos.
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.
Proceso
Servidor
Proceso
Base de Datos
Proceso
Procesos en Servidor
Clientes Dedicado
Servidor
Base de Datos
Procesos
Multihilos
Clientes
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
INTEGRIDAD DE DATOS
TRANSACCIONES
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.
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
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:
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.
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 .
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:
“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.”
Tipos de Vistas:
4.1.4 SEGURIDAD
• 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.
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
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.
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.
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).
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.
• INSERT
• DELETE
• UPDATE
ON PEDIDOS
FOR INSERT
AS UPDATE REPVENTAS
SET ventas = ventas + Inserted.importe
UPDATE Productos
SET existencias = existencias - Inserted.cant
FROM Productos , Inserted
WHERE Productos.id_dir = Inserted.fab
AND Productos.id_producto = Inserted.producto
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.
Conclusiones
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 :
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.
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
Ambito Prefijo
Global g
Modular m
Local l
Parámetro p
2. Tipos de datos.
5. Definición de constantes
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.
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.