Procedimiento Almacenado Inf 257

42
PROCEDIMIENTO ALMACENADO INF 257 Un procedimiento almacenado (stored procedure) es un programa (o procedimiento) el cual es almacenado físicamente en una base de datos. Generalmente son escritos en un lenguaje de bases de datos propietario como PL/SQL para Oracle database o PL/PgSQL para PostgreSQL. La ventaja de un procedimiento almacenado es que al ser ejecutado, en respuesta a una petición de usuario, es ejecutado directamente en el motor de bases de datos, el cual usualmente corre en un servidor separado. Como tal, posee acceso directo a los datos que necesita manipular y solo necesita enviar sus resultados de regreso al usuario, deshaciéndose de la sobrecarga resultante de comunicar grandes cantidades de datos salientes y entrantes. Usos típicos para procedimientos almacenados incluyen la validación de datos siendo integrados a la estructura de base de datos (los procedimientos almacenados utilizados para este propósito a menudo son llamados detonadores), o encapsular un proceso grande y complejo. El último ejemplo generalmente ejecutará más rápido como un procedimiento almacenado que de haber sido implementado como, por ejemplo, un programa corriendo en el sistema cliente y comunicándose con la base de datos mediante el envío de consultas SQL y recibiendo sus resultados. Los procedimientos pueden ser ventajosos: Cuando una base de datos es manipulada desde muchos programas externos. Al incluir la lógica de la aplicación en la base de datos utilizando procedimientos almacenados, la necesidad de embeber la misma lógica en todos los programas que acceden a los datos es reducida. Esto puede simplificar la creación y, particularmente, el mantenimiento de los programas involucrados. Podemos ver un claro ejemplo de estos procedimientos cuando requerimos realizar una misma operación en un servidor dentro de algunas o todas las bases de datos y a la vez dentro de todas o algunas de las tablas de las bases de datos del mismo. Para ello podemos utilizar a los Procedimientos almacenados auto creables que es una forma de generar ciclos redundantes a través de los procedimientos almacenados.

Transcript of Procedimiento Almacenado Inf 257

Page 1: Procedimiento Almacenado Inf 257

PROCEDIMIENTO ALMACENADO INF 257

Un procedimiento almacenado (stored procedure) es un programa (o procedimiento) el cual es almacenado físicamente en una base de datos. Generalmente son escritos en un lenguaje de bases de datos propietario como PL/SQL para Oracle database o PL/PgSQL para PostgreSQL. La ventaja de un procedimiento almacenado es que al ser ejecutado, en respuesta a una petición de usuario, es ejecutado directamente en el motor de bases de datos, el cual usualmente corre en un servidor separado. Como tal, posee acceso directo a los datos que necesita manipular y solo necesita enviar sus resultados de regreso al usuario, deshaciéndose de la sobrecarga resultante de comunicar grandes cantidades de datos salientes y entrantes.

Usos típicos para procedimientos almacenados incluyen la validación de datos siendo integrados a la estructura de base de datos (los procedimientos almacenados utilizados para este propósito a menudo son llamados detonadores), o encapsular un proceso grande y complejo. El último ejemplo generalmente ejecutará más rápido como un procedimiento almacenado que de haber sido implementado como, por ejemplo, un programa corriendo en el sistema cliente y comunicándose con la base de datos mediante el envío de consultas SQL y recibiendo sus resultados.

Los procedimientos pueden ser ventajosos: Cuando una base de datos es manipulada desde muchos programas externos. Al incluir la lógica de la aplicación en la base de datos utilizando procedimientos almacenados, la necesidad de embeber la misma lógica en todos los programas que acceden a los datos es reducida. Esto puede simplificar la creación y, particularmente, el mantenimiento de los programas involucrados.

Podemos ver un claro ejemplo de estos procedimientos cuando requerimos realizar una misma operación en un servidor dentro de algunas o todas las bases de datos y a la vez dentro de todas o algunas de las tablas de las bases de datos del mismo. Para ello podemos utilizar a los Procedimientos almacenados auto creables que es una forma de generar ciclos redundantes a través de los procedimientos almacenados.

Obtenido de "http://es.wikipedia.org/wiki/Procedimientos_almacenados"

Categorías: Wikipedia:Fusionar | Objetos de la base de datos relacional

Generando Procedimientos Almacenados de manera automática

 

Fecha: 05/Ago/2005 (04-08-05)Autor: Martin Luchessi

 

Page 2: Procedimiento Almacenado Inf 257

         Hola, mi nombre es Martín Luchessi. Soy de Rosario, Argentina y es la primera vez que escribo (o al menos, intento escribir) un artículo sobre informática, asi que por favor, ténganme paciencia. :P

         La idea de este artículo es explicar, al menos desde mi experiencia, el uso de las vistas de sistema y funciones de SQL Server, para realizar un script que genere código SQL para crear un procedimiento almacenado (desde ahora en adelante, PA) que actualice, modifique y elimine registros de una tabla dada de acuerdo a la clave de la misma.

         Si bien con SQL Server 2000 podemos generar 3 PAs que hagan las 3 consultas por separado, la idea es que este script genere UN solo PA y que realice la acción correspondiente de acuerdo a un parámetro del PA.

         Este script generará un código que se escribirá en el panel de resultados de SQL Server, el cual nosotros copiaremos luego para correrlo en una nueva consulta.

         Es decir, la idea es que el código generado sea algo asi:

 

CREATE PROCEDURE <NOMBRE_DEL_PA>

(

            @p_parametro1             TIPO_DATO,

            @p_parametro2             TIPO_DATO,

            …

            @p_tipo_accion             CHAR(1)

)

 

AS

 

            Si @tipo_accion = ‘A’ –-acción ACTUALIZAR O INSERTAR

                        si no existe un registro en la tabla indicada para la clave de la misma

                                   Ejecuto una consulta INSERT sobre la tabla

                       

                        si existe el registro

Page 3: Procedimiento Almacenado Inf 257

                       

                                   Ejecuto una consulta UPDATE sobre la tabla

           

            END

            IF @tipo_accion = “E” –acción ELIMINAR

                       

                        Borro los registros de la tabla.

           

            Devuelvo cantidad de registros actualizados por la consulta

 

 

         Vale la pena aclarar, que al momento de borrar registros, el script no controla (al menos esta versión no lo hace) que existan tablas relacionadas con la tabla de la cual se desea borrar registros. Es decir, si quiero borrar una persona y esta tiene números de teléfonos relacionados, si existe una restricción de clave foránea armada para la tabla de personas, con aquella que guarda los números de teléfonos, el motor de base de datos generará una excepción y no permitirá efectuar la consulta. De la misma manera, tampoco controla que, al momento de insertar un nuevo registro en la tabla, se esté ingresando datos que no existan en tablas relacionadas con ésta.

        

         Bueno, basta ya de explicaciones y pongámonos manos a la obra.

 

DECLARACIÓN DE LAS VARIABLES DE ENTRADA.

 

         En primer lugar, necesitaremos 2 variables importantes para este script. Una que contendrá el nombre de la tabla sobre la que generaremos el PA y otra  que contendrá el nombre del PA. Ésta variable en realidad puede ser obviada, ya que podemos dejar que el script se encargue de nombrar el PA. En mi caso yo elegí que si esta variable viene vacía el PA se llame “PA_ABM_NOMBRE_TABLA”, pero es algo que fácilmente pueden cambiar si no les gusta.  Ambas variables fueron declaradas como SYSNAME, ya que éste es el tipo de datos suministrado por el sistema y definido por el usuario que es funcionalmente equivalente a nvarchar(128) y que se utiliza para hacer referencia a nombres de objetos de bases de datos.

Page 4: Procedimiento Almacenado Inf 257

 

         A continuación escribimos dos líneas que nos permitirán asignarle valor a estas variables. Los valores van escritos entre comillas simples por ser SYSNAME un tipo de dato de texto.

 

 

DECLARE @P_NOMBRE_TABLA   SYSNAME

DECLARE @P_NOMBRE_PA                     SYSNAME

 

set @P_NOMBRE_TABLA = 'aquí va el nombre de la tabla'

set @P_NOMBRE_PA = 'aquí va el nombre del PA si quieren asignarle uno'

 

 

         Esta sección es la única parte del código que tendremos que modificar, cuando queramos generar un PA para una tabla.

 

 

DECLARACIÓN DE VARIABLES AUXILIARES

 

            Las siguientes son variables auxiliares que nos ayudarán a mantener el texto que deberá escribir el script en el panel de resultados del Analizador de Consultas de SQL Server 2000.

 

 

DECLARE @SQL_CABECERA       VARCHAR(8000)

DECLARE @dato                                    VARCHAR(8000)

DECLARE @SQL_WHERE                        VARCHAR(8000)

DECLARE @SQL_UPDATE                       VARCHAR(8000)

Page 5: Procedimiento Almacenado Inf 257

DECLARE @SQL_INSERT                        VARCHAR(8000)

DECLARE @SQL_VALUES                       VARCHAR(8000)

DECLARE @SQL_DELETE                        VARCHAR(8000)

 

        

         La variable @SQL_CABECERA la utilizaremos para guardar la cabecera del PA.  Es decir, toda la sección que comprende la verificación de que el PA exista en la base de datos, la eliminación y posterior creación del PA con sus parámetros.

         Las restantes variables declaradas arriba se utilizarán para armar cada consulta.

         Ahora bién. ¿Cómo sabemos que tabla hay que actualizar y bajo qué condición? ¿Cómo sabemos cuales columnas son clave de la tabla y cual no? ¿Qué tipo de dato tiene cada columna de la tabla? Todos estos datos son necesarios para actualizar una tabla, o mejor dicho, sus datos.

         Para esto, vamos a necesitar, una variable de tipo TABLE, que me permita dejar registrado todas las características de la tabla sobre la que se quiere operar. Y además, el órden en que se encuentran las columnas, para luego poder respetar los índices de la tabla.

 

DECLARE @tabla                       TABLE(orden smallint, columna SYSNAME, pk BIT, parametro varchar(25),                             tipo_dato varchar(25), largo smallint, decimales smallint)

 

 

         La columna columna, contendrá el nombre de las columnas de la tabla.

         La columna PK, nos indicará si la columna de la tabla es Primary Key o no.

         La columna parámetro, nos servirá para saber a que parámetro del PA corresponde esta columna.

         La columna tipo_dato, largo y decimales dejarán registrado que tipo de dato tiene la columna de la tabla, el largo del tipo de dato y la precisión del mismo.

         También necesitaremos declarar variables para las columnas, para utilizarlas a la hora de recorrer la VARIABLE @tabla.

 

Page 6: Procedimiento Almacenado Inf 257

DECLARE @orden                      SMALLINT

DECLARE @largo                       SMALLINT

DECLARE @decimales    SMALLINT

DECLARE @pk               BIT

DECLARE @parametro   VARCHAR(25)

DECLARE @columna                  SYSNAME

 

 

         Por último,esta variable @update, sirve como bandera para controlar que si la tabla es una tabla TODO-CLAVE, es decir, que todas las columnas de la tabla son clave primaria, no será necesario hacer un update de la misma. Por lo tanto, tomará valor 0 (cero) cuando no sea necesario  y 1 (uno) cuando si lo sea.

 

DECLARE @update                    BIT

 

VALIDANDO LA EXISTENCIA DE LA TABLA

 

            Antes de empezar a generar el código, sería interesante que el script controle que la tabla sobre la cual se quiere generar el PA exista.

         Si el nombre de la tabla está vacío, sería interesante imprimir un cartel insitando al programador, o usuario del script , a que escriba un nombre de una tabla, sino el script no tendría sentido.

 

            IF LEN(@p_nombre_tabla)=0

            begin

                        PRINT 'ESTAS PENSANDO EN LO QUE HACES? Y EL NOMBRE DE LA                                  TABLA? '

                        PRINT 'ADIVINO NO SOY!'

                        RETURN

Page 7: Procedimiento Almacenado Inf 257

            end

 

         Del mismo modo, un nombre de tabla inválido tendría el mismo efecto y podemos generar un mensaje de error de la base de datos, haciendo una consulta sobre la tabla inexistente, para obviarnos el poner un mensaje nosotros,.

 

            IF OBJECT_ID(@p_nombre_tabla) IS NULL

            begin

                        --PRINT 'LA TABLA <' + @p_nombre_tabla + '> NO EXISTE COMO                                   UN OBJETO'

                        SET @p_nombre_tabla='SELECT 1 FROM ' +  @p_nombre_tabla

                        exec(@p_nombre_tabla)

                        return

            end

        

         La función Object_ID(objeto) devolverá null si la tabla no se encuentra en la base de datos y el ID de la tabla, en caso contrario.

        

RECOLECTANDO DATOS SOBRE LA TABLA

           

Para armar este script vamos a necesitar distinguir las distintas partes del PA que queremos que arme. Para mi entender, el PA consta de 4 partes:

 

·         CABECERA

·         CONSULTA INSERT

·         CONSTULTA UPDATE

·         CONSULTA DELETE

 

Page 8: Procedimiento Almacenado Inf 257

En la cabecera, cómo dije anteriormente, vamos a escribir la creación del PA, con sus parámetros y los tipos de datos de los mismos. Además, vamos a agregarle valores por defecto a estos, para asi lograr que se puedan obviar ciertos parámetros cuando se quiera ejecutar el PA desde alguna aplicación. Por ejemplo, cuando se quiera hacer un DELETE los únicos parámetros que tendremos que pasarle serían aquellos que son clave de la tabla y el parámetro “@p_accion = ‘E’”.

En la consulta INSERT,  no tendremos demasiados problemas. Sólo necesitamos los nombres de las columnas y sus valores.

En cambio en las consultas UPDATE y DELETE necesitaremos armar el WHERE de la consulta, y es aquí donde viene el pequeño problema ya que necesitaremos saber cuáles columnas son PRIMARY KEY y cuales no.

Aquí haremos uso de la variable @Tabla que hemos declarado al comienzo de nuestro script para poder guardar toda la información que necesitemos sobre la tabla que estamos trabajando y así no hacer una consulta a las tablas de sistema cada vez que lo requiramos.

Para buscar información sobre las tablas haremos uso de las VISTAS DE ESQUEMA DE INFORMACIÓN de SQL Server 2000.

Estas vistas proporcionan una vista interna e independiente de las tablas del sistema de los metadatos de SQL Server. Las vistas de esquema de información permiten que las aplicaciones funcionen correctamente aunque se hayan realizado cambios significativos en las tablas del sistema. Las vistas de esquema de información que contiene SQL Server cumplen la definición del estándar SQL-92 para INFORMATION_SCHEMA.

Estas vistas se definen en un esquema especial llamado INFORMATION_SCHEMA, contenido en cada base de datos. Cada vista de INFORMATION_SCHEMA contiene metadatos para todos los objetos de datos almacenados en esa base de datos en particular. Esta tabla describe las relaciones existentes entre los nombres de SQL Server y los nombres estándar de SQL-92.

 

Vamos a utilizar las siguientes vistas:

 

·         COLUMNS

 

Contiene una fila por cada columna a la que puede tener acceso el usuario actual en la base de datos actual.

 

·         TABLE_CONSTRAINTS

Page 9: Procedimiento Almacenado Inf 257

 

Contiene una fila por cada restricción de tabla de la base de datos actual. Esta vista de esquema de información devuelve información acerca de los objetos sobre los que el usuario actual tiene permisos.

 

·         KEY_COLUMN_USAGE

 

Contiene una fila por cada columna, de la base de datos actual, que está restringida como clave. Esta vista de esquema de información devuelve información acerca de los objetos sobre los que el usuario actual tiene permisos.

 

De la vista COLUMNS nos interesa buscar el nombre de cada columna de la tabla (COLUMN_NAME), el tipo de dato de cada columna (DATA_TYPE), el tamaño máximo de caracteres (CHARACTER_MAXIMUM_LENGTH) en caso de tipos de dato de texto, o la precisión (NUMERIC_PRESICION) en caso de tipos de datos numéricos (en caso de datos con decimales, necesitaremos saber cuántos decimales tiene con (NUMERIC_SCALE)), y el número identificador de columna (ORDINAL_POSITION).

Las vistas KEY_COLUMN_USAGE y TABLE_CONSTRAINTS las vamos a usar para ver que columnas de la tabla son PRIMARY KEY haciendo una consulta y relacionando columnas entre las vistas.

         Así, cada dato que seleccionemos de estas vistas, lo insertaremos en la variable @tabla, de la siguiente manera:

 

  insert into @tabla

select

            COLS.ORDINAL_POSITION,

            COLS.COLUMN_NAME,

            convert(bit,(

select  count(*)

                        from

                                   INFORMATION_SCHEMA.TABLE_CONSTRAINTS as CONST

 

1

2

3

 

 

 

Page 10: Procedimiento Almacenado Inf 257

                        JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE as COL ON

                                   CONST.TABLE_SCHEMA = COL.TABLE_SCHEMA AND

                                   CONST.TABLE_NAME = COL.TABLE_NAME AND

                                   CONST.CONSTRAINT_NAME = COL.CONSTRAINT_NAME

                        where

                                   CONST.CONSTRAINT_TYPE        = 'PRIMARY KEY'                       AND

                                   CONST.CONSTRAINT_SCHEMA   = 'dbo'                         AND

                                   COL.TABLE_NAME                     = COLS.TABLE_NAME    AND

                                   COL.COLUMN_NAME                  = COLS.COLUMN_NAME

)),

            '@p_' + COLS.COLUMN_NAME,

            UPPER(COLS.DATA_TYPE),

            ISNULL(COLS.CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION),

            isnull(cols.numeric_scale,0)         

from

            INFORMATION_SCHEMA. COLUMNS  COLS  WITH (NOLOCK)

where

            COLS.TABLE_NAME = @P_NOMBRE_TABLA

order by

            cols.ordinal_position

 

 

 

 

 

 

 

 

 

 

 

4

5

6

 

 

 

7

 

8

 

Page 11: Procedimiento Almacenado Inf 257

 

         Como podemos observar, en las líneas 1 y 2, estamos usando las columnas ORDINAL_POSITION y COLUMN_NAME para guardarlas en las columnas “orden” y  “columna” de la tabla @tabla.

En la línea 3 nos vamos a detener un poco. Más arriba en este artículo, habíamos dicho que necesitábamos saber qué columnas de la tabla eran clave primaria para poder luego armar el WHERE de las consultas UPDATE y DELETE. Aquí se está realizando una subconsulta para contar todas las columnas cuyo tipo de constraint sea “PRIMARY KEY” de la tabla @P_NOMBRE_TABLA, relacionando las vistas TABLE_CONSTRAINTS y KEY_COLUMN_USAGE por medio de sus columnas TABLE_SCHEMA, CONSTRAINT_NAME y TABLE_NAME, para ver cuales son las restricciones de @P_NOMBRE_TABLA. Como sólo nos interesa la restricción PRIMARY KEY, filtramos por la columna CONSTRAINT_TYPE de la vista TABLA_CONSTRAINTS.

 

 A continuación, convertimos el valor que devuelve la subconsulta a Bit, asi podremos guardar en la columna PK de @tabla , un 1 si el COUNT es > 0, y 0 en caso contrario.

         En el renglón marcado con el número 4 estamos guardando el valor para la columna @parametro de la variable @tabla, ya con el agregado del prefijo “@p_”, que nos indicará cuál es el parámetro del PA que le corresponde a cada columna.

         En la linea 5, vamos a guardar el tipo de dato de la columna, y en las líneas 6 y 7 obtendremos el largo del tipo de dato y la precisión. Si CHARACTER_MAXIMUM_LENGHT es NULL entonces guardermos NUMERIC_PRESICION, ya que estaríamos en presencia de un tipo de dato numérico. Si NUMERIC_SCALE es NULL entonces guardaremos 0 ya que estaríamos en presencia de datos enteros, texto. Para los tipos de dato DATETIME no nos interesa tener mucho detalle en este caso.

         En las líneas 7 y 8 solamente le indicamos a la consulta en que tabla queremos que busque información y ordenamos por ORDINAL_POSITION para que busque en el orden de las columnas de la tabla.

         Veamos todo esto en un ejemplo práctico.

 

Ejemplo: PA sobre la tabla PERSONAS.

 

Supongamos una tabla PERSONAS con los siguientes atributos.

 

Page 12: Procedimiento Almacenado Inf 257

 

         Si hacemos una consulta sobre la variable @tabla, luego de recabar los datos, daría un resultado como este:

 

orden 

columna                                                                                            

pk  

parametro tipo_dato                

largo 

Decimales

1 Cod_persona 1 @p_Cod_persona

INT 10 0

2 Nombre 0 @p_Nombre

VARCHAR

50 0

3 Apellido 0 @p_Apellido

VARCHAR

50 0

4 Tipo_doc 0 @p_Tipo_doc

SMALLINT

5 0

5 Nro_doc 0 @p_Nro_doc

VARCHAR

20 0

6 Fec_nacimiento 0 @p_Fec_nacimiento

DATETIME

23 3

 

         Cómo podemos observar, la columna Cod_persona, tiene un 1 en PK, es decir que es clave primaria. El parámetro que le corresponderá en el PA se llamará @p_Cod_persona, es de tipo INT con un largo de 10 y 0 decimales, lo cual es correcto.

Ahora, vamos a acomodar la columna tipo_dato de @tabla para que contenga el podamos tener el tamaño máximo de caracteres, o la presición del tipo de dato entre paréntesis ya que cuando tengamos que cuando tengamos que declarar los parámetros del PA los vamos a necesitar.

Page 13: Procedimiento Almacenado Inf 257

Para esto hacemos un cursor que recorra la tabla y actualice la columna según si tiene decimales o no, pero sólo para aquellas columnas que lo requieran.

 

DECLARE C_COLUMNAS CURSOR LOCAL  FOR

            SELECT

                        orden,

                        largo,

                        decimales

            FROM

                        @tabla

            WHERE

                        tipo_dato IN ('VARCHAR','CHAR','NVARCHAR','NCHAR','DECIMAL','NUMERIC')

OPEN C_COLUMNAS

 

FETCH NEXT FROM C_COLUMNAS INTO

            @orden,

            @largo,

            @decimales

WHILE @@FETCH_STATUS = 0

BEGIN

            IF @decimales = 0

                        UPDATE

                                   @tabla

                        SET tipo_dato = tipo_dato + '(' + CONVERT(VARCHAR, @largo) + ')'

                        WHERE

Page 14: Procedimiento Almacenado Inf 257

                                   orden = @orden

            ELSE

                        UPDATE

                                   @tabla

                        SET tipo_dato = tipo_dato + '(' + CONVERT(VARCHAR, @largo) + ',' + CONVERT(VARCHAR,@decimales) + ')'

                        WHERE

                                   orden = @orden

FETCH NEXT FROM C_COLUMNAS INTO

            @orden,

            @largo,

            @decimales

END

 

CLOSE C_COLUMNAS

DEALLOCATE C_COLUMNAS

 

Ahora si, si hiciéramos, otra vez, una consulta sobre @tabla nos quedaría:

orden 

columna           pk  

parametro

tipo_dato                

largo 

Decimales

1 Cod_persona 1 @p_Cod_persona

INT 10 0

2 Nombre 0 @p_Nombre

VARCHAR(50)

50 0

3 Apellido 0 @p_Apellido

VARCHAR(50)

50 0

4 Tipo_doc 0 @p_Tipo_ SMALLIN 5 0

Page 15: Procedimiento Almacenado Inf 257

doc T

5 Nro_doc 0 @p_Nro_doc

VARCHAR(20)

20 0

6 Fec_nacimiento 0 @p_Fec_nacimiento

DATETIME

23 3

 

         Una vez recolectado todos los datos y acomodados a nuestro gusto, estamos listos para armar las partes del PA.

 

LA CABECERA

 

Siguiendo con el ejemplo de la tabla PERSONAS, la cabecera del PA debería quedar algo asi:

 

IF EXISTS (SELECT name FROM  sysobjects WHERE  name = N'PA_ABM_PERSONAS'  AND type = 'P')

DROP PROCEDURE PA_ABM_PERSONAS

GO

CREATE PROCEDURE PA_ABM_PERSONAS

(

            @p_Cod_persona                      INT,

            @p_Nombre                  VARCHAR(50)= NULL ,

            @p_Apellido                  VARCHAR(50)= NULL ,

            @p_Tipo_doc                 SMALLINT= NULL ,

            @p_Nro_doc                  VARCHAR(20)= NULL ,

            @p_Fec_nacimiento                   DATETIME= NULL,

            @p_accion         CHAR(1) --A = ACTUALIZA (INSERT/UPDATE) , E = ELIMINA

Page 16: Procedimiento Almacenado Inf 257

)

AS

 

La primera parte de la cabecera, cómo dijimos al principio, nos servirá para eliminar el PA de la base de datos en caso de que este ya exista, y luego lo volveremos a crear.

Como podemos notar, en la segunda parte, hay columnas que tienen valores por defecto y otras que no. Este se debe, por supuesto, a que las columnas clave tienen que ser obligatorias a la hora de ejecutar las consultas. También vemos que los tipo de dato de texto tienen que ir declarados con su tamaño máximo de caracteres, al igual que los datos decimales.

 

EL CUERPO

           

            El cuerpo que queremos armar del PA debería quedar asi:

           

IF (@p_accion = 'A')

BEGIN -- SI LA ACCION ES ACTUALIZAR

            IF NOT EXISTS (

                        SELECT 1

                        FROM

                                   PERSONAS

                        WHERE

                        Cod_persona     =          @p_Cod_persona

                                   )

            INSERT INTO PERSONAS

            (

                        Cod_persona,

Page 17: Procedimiento Almacenado Inf 257

                        Nombre,

                        Apellido,

                        Tipo_doc,

                        Nro_doc,

                        Fec_nacimiento

            )

            VALUES

            (

                        @p_Cod_persona,

                        @p_Nombre,

                        @p_Apellido,

                        @p_Tipo_doc,

                        @p_Nro_doc,

                        @p_Fec_nacimiento

            )

            ELSE --SI EXISTE HAGO UPDATE

                       

            UPDATE PERSONAS

            SET

                        Nombre            =          @p_Nombre,

                        Apellido            =          @p_Apellido,

                        Tipo_doc           =          @p_Tipo_doc,

                        Nro_doc                        =          @p_Nro_doc,

                        Fec_nacimiento  =          @p_Fec_nacimiento

            WHERE

Page 18: Procedimiento Almacenado Inf 257

                        Cod_persona     =          @p_Cod_persona

END --TERMINA DE ACTUALIZAR

ELSE IF @p_accion = 'E'

           

            DELETE PERSONAS

            WHERE

                        Cod_persona     =          @p_Cod_persona

                       

RETURN @@ROWCOUNT

GO

 

         Para lograr que el script escriba esto en el panel de resultados, debemos usar el método PRINT en cada línea que queramos escribir o en las variables de texto que declaramos al comienzo de esta historia.

        

ESCRIBIENDO EL PROCEDIMIENTO ALMACENADO EN PANTALLA

 

         Para comenzar a escribir el PA, debemos, en principio, inicializar las variables.

 

/*         INCIALIZO LAS VARIABLES DEL TEXTO  */

 

IF @P_NOMBRE_PA = ''

            SET @P_NOMBRE_PA = 'PA_ABM_'+ @P_NOMBRE_TABLA

 

SET @SQL_WHERE = '    WHERE

'

Page 19: Procedimiento Almacenado Inf 257

SET @SQL_INSERT = '   INSERT INTO ' + @P_NOMBRE_TABLA + '

            (

'

SET @SQL_VALUES = '   VALUES

            (

'

SET @SQL_UPDATE = ' UPDATE ' + @P_NOMBRE_TABLA + '

            SET

'

SET @SQL_DELETE = '   DELETE ' + @P_NOMBRE_TABLA + '

'

           

SET @SQL_CABECERA = 'IF EXISTS (SELECT name FROM   sysobjects WHERE  name = N''' +             @P_NOMBRE_PA + '''  AND         type = ''P'')'+CHAR(13) +

            'DROP PROCEDURE ' + @P_NOMBRE_PA + CHAR(13) +

            'GO' + CHAR(13) + CHAR(13) + + CHAR(13) + CHAR(13) +

            'CREATE PROCEDURE '+ @P_NOMBRE_PA + CHAR(13) + '(' + CHAR(13)

 

         La variable @P_NOMBRE_PA la inicializamos con el nombre de la tabla más el prefijo “PA_ABM_”, sólo en caso de que no se haya ingresado un valor al correr el script.

         Una vez inicializadas las variables que vamos a utilizar, comenzamos a armar la información que estas van a contener para luego imprimirla en pantalla.

         Lo que vamos a hacer es usar un cursor para  recorrer la variable @tabla, y vamos a obtener los valores de las columnas “columna”, “parámetro” y “pk”. Además en la variable auxiliar @dato, vamos a armar la declaración de parámetros de la cabecera.

 

Page 20: Procedimiento Almacenado Inf 257

DECLARE C_TABLA CURSOR LOCAL FOR

            SELECT

                        '           ' +parametro + '                       ' + tipo_dato +

                        CASE pk

                                   WHEN 0 THEN '= NULL ,'

                                   ELSE ',' END + CHAR(13),

                        columna,

                        parametro,

                        pk

            FROM

                        @tabla

            ORDER BY orden

 

OPEN C_TABLA

 

FETCH NEXT FROM C_TABLA INTO

            @dato,

            @columna,

            @parametro,    

            @pk

           

 

         Por cada registro, si la columna “pk” es igual a 1, es decir, si es clave primaria vamos a armar el WHERE. Caso contrario armamos las columnas a actualizar en la consulta UPDATE. Además, como  podemos ver, vamos hacer uso de la bander @update, asignándole el valor 1 para indicar que hay , al menos una columna que no es clave, por lo tanto se tendrá que escribir la cláusula UPDATE.

         Luego armamos los valores para las variables @SQL_INSERT y @SQL_VALUES.

Page 21: Procedimiento Almacenado Inf 257

         Una vez que se terminó de recorrer todo el cursor, lo cerramos y liberamos la memoria.

 

 WHILE @@FETCH_STATUS = 0

BEGIN

 

            -- SI LA COLUMNA ES CLAVE ARMO EL WHERE

            IF (@pk = 1)

                        SET @SQL_WHERE = @SQL_WHERE + '              ' + @columna + '           =             ' +                                                       @parametro + ' AND ' + CHAR(13)

            ELSE IF (@pk = 0)

                        SELECT @SQL_UPDATE = @SQL_UPDATE + '                  ' + @columna + '            =          ' + @parametro + ',' + CHAR(13)           ,

                        @update=1

 

            SET @SQL_INSERT = @SQL_INSERT + '             ' + @columna + ',' + CHAR(13)

            SET @SQL_VALUES = @SQL_VALUES  + '                       ' + @parametro +',' + CHAR(13)                    

            set @SQL_CABECERA = @SQL_CABECERA + @dato

 

FETCH NEXT FROM C_TABLA INTO

            @dato,

            @columna,

            @parametro,    

            @pk

END

 

 

 

1

 

2

 

 

3

 

 

 

 

 

 

 

 

 

 

 

 

Page 22: Procedimiento Almacenado Inf 257

 

CLOSE C_TABLA

DEALLOCATE C_TABLA

 

 

 

 

         Finalmente, tenemos que limpiar las variables que hemos utilizado, de las impurezas que nos dejó el concatenar los valores de la tabla. Esto depende de la cantidad de espacios y bajadas de línea que se han concatenado.

 

SET @SQL_WHERE = LEFT(@SQL_WHERE,LEN(@SQL_WHERE) -6)

SET @SQL_INSERT = LEFT(@SQL_INSERT,LEN(@SQL_INSERT)-2) + '

)'

SET @SQL_VALUES = LEFT(@SQL_VALUES,LEN(@SQL_VALUES)-2) + '

)'

SET @SQL_UPDATE = LEFT(@SQL_UPDATE,LEN(@SQL_UPDATE)-2)

 

IMPRIMIENDO LAS VARIABLES

 

            ¡Bueno! Por fin hemos llegado al final del script. Luego de dar tantas vueltas, vamos a ver los resultados, que, por lo menos en mi caso, fueron más que beneficiosos.

         Ahora lo único que resta es imprimir las variables en el panel de resultados.

 

PRINT   @SQL_CABECERA + '    @p_accion         CHAR(1) --A = ACTUALIZA (INSERT/UPDATE) , E = ELIMINA

)

AS

 

 

Page 23: Procedimiento Almacenado Inf 257

'

PRINT   'IF (@p_accion = ''A'')'

PRINT   'BEGIN -- SI LA ACCION ES ACTUALIZAR'

PRINT   '           IF NOT EXISTS ( '

PRINT   '                       SELECT 1 '

PRINT   '                       FROM '

PRINT   '                                   ' + @P_NOMBRE_TABLA

PRINT ' ' + @SQL_WHERE + '

                                   )'

 

PRINT @SQL_INSERT

PRINT @SQL_VALUES

 

IF @update=1

BEGIN

            PRINT ' ELSE --SI EXISTE HAGO UPDATE

                        '

            PRINT @SQL_UPDATE

            PRINT @SQL_WHERE

END

 

PRINT 'END --TERMINA DE ACTUALIZAR'

PRINT 'ELSE IF @p_accion = ''E''

            '

PRINT @SQL_DELETE

Page 24: Procedimiento Almacenado Inf 257

PRINT @SQL_WHERE

PRINT '            

RETURN @@ROWCOUNT '

PRINT 'GO

'

 

 

GO

 

         La disposición de espacios y bajadas de líneas se pueden ir acomodando a lo largo del armado de las variables y de la impresión final.

         Una vez que tengamos todo el script escrito en el Analizador de Consultas, resta elegir sobre que base de datos lo vamos a correr, setear la variable @P_NOMBRE_TABLA y correr el script. En el panel de resultados nos va a aparecer todo el texto del PA, lo copiamos y lo pegamos en una nueva consulta y lo corremos.

        

         Espero que les haya servido este artículo. Yo se que a mi me sirvió mucho el script para ahorrar tiempo en escribir este tipo de PA constantemente. Les adjunto el script completo , el cual pueden abrir con el Analizador de Consultas para usarlo.

 

         Agradezco a Franco Raspo, Matias Toro y Andrés Faya, quienes me motivaron y ayudaron para armar este artículo.

         Cualquier sugerencia que quieran hacer, modificaciones y/o correcciones (espero que las hagan) las pueden enviar a [email protected].

         Sobre las vistas de SQL pueden encontrar más información en:

http://siquelnet.etraducciones.com/default.aspx?Tema=MSSQL&Seccion=SQL&Articulo=005.xml

o en los libros en pantalla de SQL Server 2000.

 

         Hasta la próxima.

Page 25: Procedimiento Almacenado Inf 257

 

Procedimientos Almacenados Ir arriba Un Procedimiento Almacenado es un programa autocontrolado escrito en lenguaje del DBMS, son almacenados como parte de la Base de Datos y sus metadatos. 

Una vez creado un procedimiento almacenado, se puede invocar directamente desde una aplicaci o sustituir el nombre de una tabla o vista, por el nombre de procedimiento en clᵳulas SELECT. Los procedimientos almacenados pueden recibir par᭥tros de entrada y retornar valores a la aplicaci

 

Las ventajas de usar los procedimientos almacenados incluyen:

o Diseodular. o Aplicaciones que

acceden la misma Base de Datos pueden compartir los procedimientos almacenados, eliminando el co doble y reduciendo el tamae las aplicaciones.

o El f l mantenimiento. ᣩo Cuando un

procedimiento se actualiza, los cambios se reflejan automᴩcamente en todas las aplicaciones, sin la necesidad de recompilar y relinkear. Las aplicaciones son compiladas suna vez para cada cliente.

o Los procedimientos almacenados son ejecutados por el servidor, no por el cliente lo que reduce el tr ᦩ co en la red y mejora el performance o desempeespecialmente para el acceso del cliente remoto.

o Estᮠ almacenados en los servidores y asegurados por las medidas tomadas en la instalacilo que impide que los usuarios normales puedan modificarlos e incluso desconocen su existencia. Este es un elemento de gran valor en lo que a seguridad respecta.

Como se puede apreciar los Sistemas de Bases de Datos ofrecen a desarrolladores, administradores y usuarios una gama muy completa de herramientas que permiten garantizar la integridad, consistencia, confidencialidad y en general seguridad de la informacilmacenada y con un elemento muy importante a favor: Las las de co que se requieren por parte del implementador son muy pocas, en ocasiones solo basta con una sencilla sentencia para obligar al DBMS a controlar y mantener las restricciones necesarias.Cómo crear un procedimiento almacenado (SQL Server Management Studio)

Nuevo: 5 de diciembre de 2005

En este tema se describe cómo crear un procedimiento almacenado de Transact-

SQL mediante el Explorador de objetos de SQL Server Management Studio y se

Page 26: Procedimiento Almacenado Inf 257

ofrece un ejemplo en el que se crea un procedimiento almacenado simple en la base

de datos AdventureWorks .

Para crear un procedimiento almacenado

1. En el Explorador de objetos, conéctese a una instancia de SQL Server 2005

Database Engine (Motor de base de datos de SQL Server 2005) y expándala.

2. Expanda Bases de datos, la base de datos a la que pertenece el

procedimiento almacenado y, por último, Programación.

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

continuación, haga clic en Nuevo procedimiento almacenado.

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

plantilla.

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

la columna Valor contiene valores recomendados para los parámetros.

Acepte los valores o reemplácelos con nuevos valores y, a continuación, haga

clic en Aceptar.

6. En el editor de consultas, reemplace la instrucción SELECT por las

instrucciones para el procedimiento.

7. Para probar la sintaxis, en el menú Consulta, haga clic en Analizar.

8. Para crear el procedimiento almacenado, en el menú Consulta, haga clic en

Ejecutar.

9. Para guardar la secuencia de comandos, en el menú Archivo, haga clic en

Guardar. Acepte el nombre de archivo o reemplácelo por un nombre nuevo y,

a continuación, haga clic en Guardar.

Nota de seguridad:

Valide toda entrada de usuario. No concatene ninguna entrada de usuario antes de que se valide. No ejecute nunca un comando creado a partir de una entrada de usuario no validada. Para obtener más información, vea Inyección de código SQL.

Para crear un ejemplo de procedimiento almacenado

1. En el Explorador de objetos, conéctese a una instancia de SQL Server 2005

Database Engine (Motor de base de datos de SQL Server 2005) y expándala.

Page 27: Procedimiento Almacenado Inf 257

2. Expanda Bases de datos, la base de datos AdventureWorks y, por último,

Programación.

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

continuación, haga clic en Nuevo procedimiento almacenado.

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

plantilla.

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

especifique los siguientes valores para los parámetros mostrados.

Parámetro Valor

Author Su nombre.

Create Date La fecha de hoy.

Description Devuelve datos de empleado.

Procedure_name HumanResources.uspGetEmployees

@Param1 @LastName

@Datatype_For_Param1 nvarchar(50)

Default_Value_For_Param1 NULL

@Param2 @FirstName

@Datatype_For_Param2 nvarchar(50)

Default_Value_For_Param2 NULL

6. Haga clic en Aceptar.

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

instrucción:

Copiar código

SELECT FirstName, LastName, JobTitle, Department FROM

HumanResources.vEmployeeDepartment WHERE FirstName =

@FirstName AND LastName = @LastName;

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

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

anterior y corrija lo que sea necesario.

Page 28: Procedimiento Almacenado Inf 257

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

Ejecutar.

10.Para guardar la secuencia de comandos, en el menú Archivo, haga clic en

Guardar. Especifique un nuevo nombre de archivo y haga clic en Guardar.

11.Para ejecutar el procedimiento almacenado, en la barra de herramientas,

haga clic en Nueva consulta.

12.En la ventana de consultas, especifique las siguientes instrucciones:

Procedimientos almacenados del sistema (Transact-SQL)

En SQL Server 2005, muchas actividades administrativas e informativas se pueden

realizar mediante los procedimientos almacenados del sistema. Los procedimientos

almacenados del sistema se agrupan en las categorías que aparecen en la siguiente

tabla.

En esta sección

Categoría Descripción

Procedimientos almacenados de Active Directory

Se utilizan para registrar instancias de SQL Server y bases de datos de SQL Server en Active Directory de Microsoft Windows 2000.

Procedimientos almacenados del catálogo

Se utilizan para implementar las funciones del diccionario de datos ODBC y aislar las aplicaciones ODBC de los cambios en las tablas subyacentes del sistema.

Procedimientos almacenados de cursor

Se utilizan para implementar la funcionalidad de variable de cursor.

Procedimientos almacenados del motor de base de datos

Se utilizan para el mantenimiento general del SQL Server Database Engine (Motor de base de datos de SQL Server).

Procedimientos almacenados de Correo electrónico de base de datos y SQL Mail

Se utilizan para realizar operaciones de correo electrónico desde una instancia de SQL Server.

Procedimientos almacenados de planes de mantenimiento de bases de datos

Se utilizan para configurar las tareas de mantenimiento fundamentales necesarias para administrar el rendimiento de las bases de datos.

Procedimientos almacenados de consultas distribuidas

Se utilizan para implementar y administrar consultas distribuidas.

Page 29: Procedimiento Almacenado Inf 257

Procedimientos almacenados de la búsqueda de texto

Se utilizan para implementar y consultar índices de texto.

Procedimientos almacenados del trasvase de registros

Se utilizan para establecer, modificar y supervisar las configuraciones de los trasvases de registros.

Procedimientos almacenados de automatización

Permiten utilizar objetos de automatización estándar en un lote estándar de Transact-SQL.

Procedimientos almacenados de Notification Services

Se utilizan para administrar SQL Server 2005 Notification Services.

Procedimientos almacenados de réplica

Se utilizan para administrar la réplica.

Procedimientos almacenados de seguridad

Se utilizan para administrar la seguridad.

Procedimientos almacenados del Analizador de SQL Server

Son utilizados por el Analizador de SQL Server para supervisar el rendimiento y la actividad.

Procedimientos almacenados del Agente SQL Server

Son utilizados por el Agente SQL Server para administrar actividades programadas y controladas por eventos.

Procedimientos almacenados de tareas Web

Se utilizan para crear páginas Web.

Procedimientos almacenados de XML

Se utilizan para la administración del texto XML.

Procedimientos almacenados extendidos generales

Proporcionan una interfaz de una instancia de SQL Server a los programas externos para diversas actividades de mantenimiento.

Nota:

A menos que se documente específicamente lo contrario, todos los procedimientos almacenados del sistema devuelven el valor 0. Esto indica que son correctos. Para indicar un error, se devuelve un valor distinto de cero.

Procedimientos almacenados del sistema de la API

Los usuarios que ejecutan el Analizador de SQL Server con aplicaciones ADO, OLE

DB y ODBC pueden observar que dichas aplicaciones utilizan procedimientos

almacenados del sistema que no se tratan en la Referencia de Transact-SQL. Estos

procedimientos almacenados son utilizados por el proveedor OLE DB de Microsoft

SQL Native Client y el controlador ODBC de SQL Native Client a fin de implementar

la funcionalidad de una API de base de datos. Estos procedimientos almacenados

simplemente son el mecanismo que el proveedor o el controlador utiliza para

Page 30: Procedimiento Almacenado Inf 257

comunicar las solicitudes del usuario a una instancia de SQL Server. Están

destinados al uso interno del proveedor o el controlador. No se permite llamarlos

explícitamente desde una aplicación basada en SQL Server.

La funcionalidad completa de estos procedimientos almacenados está disponible

para las aplicaciones basadas en SQL Server a través de las funciones de la API

que admiten. Por ejemplo, la funcionalidad de cursor del procedimiento almacenado

del sistema sp_cursor está disponible para las aplicaciones OLE DB a través de las

propiedades y métodos de cursor de la API de OLE DB y para las aplicaciones

ODBC a través de los atributos y funciones de cursor de ODBC.

Los siguientes procedimientos almacenados del sistema son compatibles con la funcionalidad

de cursor de ADO, OLE DB y ODBC:

sp_cursor sp_cursorclose sp_cursorexecute

sp_cursorfetch sp_cursoropen sp_cursoroption

sp_cursorprepare sp_cursorunprepare  

Los siguientes procedimientos almacenados del sistema son compatibles con el modelo de

preparación o ejecución para la ejecución de instrucciones Transact-SQL en ADO, OLE DB y

ODBC:

sp_execute sp_prepare sp_unprepare

Los procedimientos almacenados sp_createorphan y sp_droporphans se utilizan

para el procesamiento de tipos de datos ntext, text e image de ODBC.

SQL Server utiliza el procedimiento almacenado sp_reset_connection para permitir

las llamadas a procedimientos almacenados remotos en una transacción. Este

procedimiento almacenado también hace que se activen los eventos Audit Login y

Audit Logout cuando se reutiliza una conexión de un grupo de conexiones.

Los procedimientos almacenados del sistema de las siguientes tablas sólo se utilizan

en una instancia de SQL Server o a través de las API cliente y no están destinados

al uso general. Están sujetos a cambios y su compatibilidad no está garantizada.

Los siguientes procedimientos almacenados están documentados en los Libros en pantalla de

SQL Server:

Page 31: Procedimiento Almacenado Inf 257

sp_catalogs sp_column_privileges

sp_column_privileges_ex sp_columns

sp_columns_ex sp_databases

sp_datatype_info sp_fkeys

sp_foreignkeys sp_indexes

sp_pkeys sp_primarykeys

sp_server_info sp_special_columns

sp_sproc_columns sp_statistics

sp_table_privileges sp_table_privileges_ex

sp_tables sp_tables_ex

Los siguientes procedimientos almacenados no están documentados:

sp_assemblies_rowset sp_assemblies_rowset_rmt

sp_assemblies_rowset2 sp_assembly_dependencies_rowset

sp_assembly_dependencies_rowset_rmt

sp_assembly_dependencies_rowset2

sp_bcp_dbcmptlevel sp_catalogs_rowset

sp_catalogs_rowset;2 sp_catalogs_rowset;5

sp_catalogs_rowset_rmt sp_catalogs_rowset2

sp_check_constbytable_rowset sp_check_constbytable_rowset;2

sp_check_constbytable_rowset2 sp_check_constraints_rowset

sp_check_constraints_rowset;2 sp_check_constraints_rowset2

sp_column_privileges_rowset sp_column_privileges_rowset;2

sp_column_privileges_rowset;5 sp_column_privileges_rowset_rmt

sp_column_privileges_rowset2 sp_columns_90

sp_columns_90_rowset sp_columns_90_rowset_rmt

sp_columns_90_rowset2 sp_columns_ex_90

sp_columns_rowset sp_columns_rowset;2

sp_columns_rowset;5 sp_columns_rowset_rmt

Page 32: Procedimiento Almacenado Inf 257

sp_columns_rowset2 sp_constr_col_usage_rowset

sp_datatype_info_90 sp_ddopen;1

sp_ddopen;10 sp_ddopen;11

sp_ddopen;12 sp_ddopen;13

sp_ddopen;2 sp_ddopen;3

sp_ddopen;4 sp_ddopen;5

sp_ddopen;6 sp_ddopen;7

sp_ddopen;8 sp_ddopen;9

sp_foreign_keys_rowset sp_foreign_keys_rowset;2

sp_foreign_keys_rowset;3 sp_foreign_keys_rowset;5

sp_foreign_keys_rowset_rmt sp_foreign_keys_rowset2

sp_foreign_keys_rowset3 sp_indexes_90_rowset

sp_indexes_90_rowset_rmt sp_indexes_90_rowset2

sp_indexes_rowset sp_indexes_rowset;2

sp_indexes_rowset;5 sp_indexes_rowset_rmt

sp_indexes_rowset2 sp_linkedservers_rowset

sp_linkedservers_rowset;2 sp_linkedservers_rowset2

sp_oledb_database sp_oledb_defdb

sp_oledb_deflang sp_oledb_language

sp_oledb_ro_usrname sp_primary_keys_rowset

sp_primary_keys_rowset;2 sp_primary_keys_rowset;3

sp_primary_keys_rowset;5 sp_primary_keys_rowset_rmt

sp_primary_keys_rowset2 sp_procedure_params_90_rowset

sp_procedure_params_90_rowset2 sp_procedure_params_rowset

sp_procedure_params_rowset;2 sp_procedure_params_rowset2

sp_procedures_rowset sp_procedures_rowset;2

sp_procedures_rowset2 sp_provider_types_90_rowset

sp_provider_types_rowset sp_schemata_rowset

sp_schemata_rowset;3 sp_special_columns_90

Page 33: Procedimiento Almacenado Inf 257

sp_sproc_columns_90 sp_statistics_rowset

sp_statistics_rowset;2 sp_statistics_rowset2

sp_stored_procedures sp_table_constraints_rowset

sp_table_constraints_rowset;2 sp_table_constraints_rowset2

sp_table_privileges_rowset sp_table_privileges_rowset;2

sp_table_privileges_rowset;5 sp_table_privileges_rowset_rmt

sp_table_privileges_rowset2 sp_table_statistics_rowset

sp_table_statistics_rowset;2 sp_table_statistics2_rowset

sp_tablecollations sp_tablecollations_90

sp_tables_info_90_rowset sp_tables_info_90_rowset_64

sp_tables_info_90_rowset2 sp_tables_info_90_rowset2_64

sp_tables_info_rowset sp_tables_info_rowset;2

sp_tables_info_rowset_64 sp_tables_info_rowset_64;2

sp_tables_info_rowset2 sp_tables_info_rowset2_64

sp_tables_rowset;2 sp_tables_rowset;5

sp_tables_rowset_rmt sp_tables_rowset2

sp_usertypes_rowset sp_usertypes_rowset_rmt

sp_usertypes_rowset2 sp_views_rowset

sp_views_rowset2 sp_xml_schema_rowset

sp_xml_schema_rowset2

Vea también

Referencia

CREATE PROCEDURE (Transact-SQL)

Otros recursos

Procedimientos almacenados (motor de base de datos)

Running Stored Procedures (OLE DB)

Running Stored Procedures

Ayuda e información

Obtener ayuda sobre SQL Server 2005