Está en la página 1de 33

PROCEDIMIENTO ALMACENADO INF 257 Un procedimiento almacenado (stored procedure) es un programa (o procedimiento) el cual es almacenado fsicamente 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 peticin 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, deshacindose de la sobrecarga resultante de comunicar grandes cantidades de datos salientes y entrantes. Usos tpicos para procedimientos almacenados incluyen la validacin de datos siendo integrados a la estructura de base de datos (los procedimientos almacenados utilizados para este propsito a menudo son llamados detonadores), o encapsular un proceso grande y complejo. El ltimo ejemplo generalmente ejecutar ms rpido como un procedimiento almacenado que de haber sido implementado como, por ejemplo, un programa corriendo en el sistema cliente y comunicndose con la base de datos mediante el envo 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 lgica de la aplicacin en la base de datos utilizando procedimientos almacenados, la necesidad de embeber la misma lgica en todos los programas que acceden a los datos es reducida. Esto puede simplificar la creacin y, particularmente, el mantenimiento de los programas involucrados. Podemos ver un claro ejemplo de estos procedimientos cuando requerimos realizar una misma operacin 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 travs de los procedimientos almacenados. Obtenido de "http://es.wikipedia.org/wiki/Procedimientos_almacenados" Categoras: Wikipedia:Fusionar | Objetos de la base de datos relacional Generando Procedimientos Almacenados de manera automtica

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

Hola, mi nombre es Martn Luchessi. Soy de Rosario, Argentina y es la primera vez que escribo (o al menos, intento escribir) un artculo sobre informtica, asi que por favor, tnganme paciencia. :P La idea de este artculo 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 cdigo 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 accin correspondiente de acuerdo a un parmetro del PA. Este script generar un cdigo 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 cdigo generado sea algo asi:

CREATE PROCEDURE <NOMBRE_DEL_PA> ( @p_parametro1 @p_parametro2 @p_tipo_accion ) CHAR(1) TIPO_DATO, TIPO_DATO,

AS

Si @tipo_accion = A -accin 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

Ejecuto una consulta UPDATE sobre la tabla

END IF @tipo_accion = E accin 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 versin 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 nmeros de telfonos relacionados, si existe una restriccin de clave fornea armada para la tabla de personas, con aquella que guarda los nmeros de telfonos, el motor de base de datos generar una excepcin 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 pongmonos manos a la obra.

DECLARACIN 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 vaca el PA se llame PA_ABM_NOMBRE_TABLA, pero es algo que fcilmente 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.

A continuacin escribimos dos lneas que nos permitirn 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 seccin es la nica parte del cdigo que tendremos que modificar, cuando queramos generar un PA para una tabla.

DECLARACIN DE VARIABLES AUXILIARES

Las siguientes son variables auxiliares que nos ayudarn 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 DECLARE @dato DECLARE @SQL_WHERE DECLARE @SQL_UPDATE

VARCHAR(8000) VARCHAR(8000) VARCHAR(8000) VARCHAR(8000)

DECLARE @SQL_INSERT DECLARE @SQL_VALUES DECLARE @SQL_DELETE

VARCHAR(8000) VARCHAR(8000) VARCHAR(8000)

La variable @SQL_CABECERA la utilizaremos para guardar la cabecera del PA. Es decir, toda la seccin que comprende la verificacin de que el PA exista en la base de datos, la eliminacin y posterior creacin del PA con sus parmetros. Las restantes variables declaradas arriba se utilizarn para armar cada consulta. Ahora bin. Cmo sabemos que tabla hay que actualizar y bajo qu condicin? Cmo 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 caractersticas de la tabla sobre la que se quiere operar. Y adems, 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 parmetro, nos servir para saber a que parmetro del PA corresponde esta columna. La columna tipo_dato, largo y decimales dejarn registrado que tipo de dato tiene la columna de la tabla, el largo del tipo de dato y la precisin del mismo. Tambin necesitaremos declarar variables para las columnas, para utilizarlas a la hora de recorrer la VARIABLE @tabla.

DECLARE @orden DECLARE @largo DECLARE @decimales DECLARE @pk

SMALLINT SMALLINT SMALLINT 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 cdigo, sera interesante que el script controle que la tabla sobre la cual se quiere generar el PA exista. Si el nombre de la tabla est vaco, sera interesante imprimir un cartel insitando al programador, o usuario del script , a que escriba un nombre de una tabla, sino el script no tendra 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

end

Del mismo modo, un nombre de tabla invlido tendra 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 COMO --PRINT 'LA TABLA <' + @p_nombre_tabla + '> NO EXISTE UN OBJETO'

SET @p_nombre_tabla='SELECT 1 FROM ' + @p_nombre_tabla exec(@p_nombre_tabla) return end

La funcin 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

En la cabecera, cmo dije anteriormente, vamos a escribir la creacin del PA, con sus parmetros y los tipos de datos de los mismos. Adems, vamos a agregarle valores por defecto a estos, para asi lograr que se puedan obviar ciertos parmetros cuando se quiera ejecutar el PA desde alguna aplicacin. Por ejemplo, cuando se quiera hacer un DELETE los nicos parmetros que tendremos que pasarle seran aquellos que son clave de la tabla y el parmetro @p_accion = E. En la consulta INSERT, no tendremos demasiados problemas. Slo 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 pequeo problema ya que necesitaremos saber cules 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 informacin 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 informacin sobre las tablas haremos uso de las VISTAS DE ESQUEMA DE INFORMACIN 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 informacin permiten que las aplicaciones funcionen correctamente aunque se hayan realizado cambios significativos en las tablas del sistema. Las vistas de esquema de informacin que contiene SQL Server cumplen la definicin del estndar 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 estndar 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

Contiene una fila por cada restriccin de tabla de la base de datos actual. Esta vista de esquema de informacin devuelve informacin 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 informacin devuelve informacin 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 tamao mximo de caracteres (CHARACTER_MAXIMUM_LENGTH) en caso de tipos de dato de texto, o la precisin (NUMERIC_PRESICION) en caso de tipos de datos numricos (en caso de datos con decimales, necesitaremos saber cuntos decimales tiene con (NUMERIC_SCALE)), y el nmero 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, 1 COLS.COLUMN_NAME, 2 convert(bit,( 3 select count(*) from INFORMATION_SCHEMA.TABLE_CONSTRAINTS as CONST

4 COL ON 5

JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE as CONST.TABLE_SCHEMA = COL.TABLE_SCHEMA

AND CONST.TABLE_NAME = COL.TABLE_NAME AND CONST.CONSTRAINT_NAME = COL.CONSTRAINT_NAME

7 KEY' 8 AND

where CONST.CONSTRAINT_TYPE AND = 'PRIMARY

CONST.CONSTRAINT_SCHEMA = 'dbo' COL.TABLE_NAME =

Como podemos observar, en las lneas 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 lnea 3 nos vamos a detener un poco. Ms arriba en este artculo, habamos dicho que necesitbamos 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 slo nos interesa la restriccin PRIMARY KEY, filtramos por la columna CONSTRAINT_TYPE de la vista TABLA_CONSTRAINTS.

A continuacin, 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 rengln marcado con el nmero 4 estamos guardando el valor para la columna @parametro de la variable @tabla, ya con el agregado del prefijo @p_, que nos indicar cul es el parmetro 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 lneas 6 y 7 obtendremos el largo del tipo de dato y la precisin. Si CHARACTER_MAXIMUM_LENGHT es NULL entonces guardermos NUMERIC_PRESICION, ya que estaramos en presencia de un tipo de dato numrico. Si NUMERIC_SCALE es NULL entonces guardaremos 0 ya que estaramos en presencia de datos enteros, texto. Para los tipos de dato DATETIME no nos interesa tener mucho detalle en este caso. En las lneas 7 y 8 solamente le indicamos a la consulta en que tabla queremos que busque informacin y ordenamos por ORDINAL_POSITION para que busque en el orden de las columnas de la tabla. Veamos todo esto en un ejemplo prctico.

Ejemplo: PA sobre la tabla PERSONAS.

Supongamos una tabla PERSONAS con los siguientes atributos.

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

ord columna en 1 2 3 4 5 6 Cod_persona Nombre Apellido Tipo_doc Nro_doc Fec_nacimiento

pk parametro tipo_dato

larg Decima o les 10 0 0 0 0 0 3

1 0 0 0 0 0

@p_Cod_pe INT rsona

@p_Nombre VARCHAR 50 @p_Apellido VARCHAR 50 @p_Tipo_do SMALLINT 5 c @p_Nro_do VARCHAR 20 c @p_Fec_na DATETIME 23 cimiento

Cmo podemos observar, la columna Cod_persona, tiene un 1 en PK, es decir que es clave primaria. El parmetro 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 tamao mximo de caracteres, o la presicin del tipo de dato entre parntesis ya que cuando tengamos que cuando tengamos que declarar los parmetros del PA los vamos a necesitar. Para esto hacemos un cursor que recorra la tabla y actualice la columna segn si tiene decimales o no, pero slo 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 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 hiciramos, otra vez, una consulta sobre @tabla nos quedara: ord columna en 1 2 3 4 5 6 Cod_persona Nombre Apellido Tipo_doc Nro_doc Fec_nacimiento pk parametro tipo_dato larg Decima o les 10 0 0 0 0 0 3

1 0 0 0 0 0

@p_Cod_pe INT rsona

@p_NombreVARCHAR( 50 50) @p_ApellidoVARCHAR( 50 50) @p_Tipo_doSMALLINT 5 c @p_Nro_do VARCHAR( 20 c 20) @p_Fec_na DATETIME 23 cimiento

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 debera 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 @p_Nombre @p_Apellido @p_Tipo_doc @p_Nro_doc @p_Fec_nacimiento @p_accion ELIMINA ) AS INT, VARCHAR(50)= NULL , VARCHAR(50)= NULL , SMALLINT= NULL , VARCHAR(20)= NULL , DATETIME= NULL,

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

La primera parte de la cabecera, cmo 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. Tambin vemos que los tipo de dato de texto tienen que ir declarados con su tamao mximo de caracteres, al igual que los datos decimales.

EL CUERPO

El cuerpo que queremos armar del PA debera quedar asi:

IF (@p_accion = 'A') BEGIN -- SI LA ACCION ES ACTUALIZAR IF NOT EXISTS ( SELECT 1 FROM PERSONAS WHERE Cod_persona ) INSERT INTO PERSONAS ( Cod_persona, Nombre, Apellido, Tipo_doc, Nro_doc, Fec_nacimiento ) VALUES ( @p_Cod_persona, = @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 Apellido Tipo_doc Nro_doc Fec_nacimiento = WHERE Cod_persona = @p_Cod_persona = = = @p_Nombre, @p_Apellido, @p_Tipo_doc, = @p_Nro_doc,

@p_Fec_nacimiento

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 mtodo PRINT en cada lnea 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

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 ms el prefijo PA_ABM_, slo 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 informacin 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, parmetro y pk. Adems en la variable auxiliar @dato, vamos a armar la declaracin de parmetros de la cabecera.

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. Adems, como podemos ver, vamos hacer uso de la bander @update, asignndole el valor 1 para indicar que hay , al menos una columna que no es clave, por lo tanto se tendr que escribir la clusula UPDATE. Luego armamos los valores para las variables @SQL_INSERT y @SQL_VALUES. 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) 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 + ' + CHAR(13) SET @SQL_VALUES = @SQL_VALUES + ' @parametro +',' + CHAR(13)

' + @columna + ',' '+

set @SQL_CABECERA = @SQL_CABECERA + @dato

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 lnea 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 ms que beneficiosos. Ahora lo nico que resta es imprimir las variables en el panel de resultados.

PRINT @SQL_CABECERA + ' @p_accion (INSERT/UPDATE) , E = ELIMINA ) AS

CHAR(1) --A = ACTUALIZA

' PRINT 'IF (@p_accion = ''A'')' PRINT 'BEGIN -- SI LA ACCION ES ACTUALIZAR' PRINT ' PRINT ' PRINT ' PRINT ' PRINT ' ' + @SQL_WHERE + ' )' IF NOT EXISTS ( ' SELECT 1 ' FROM ' ' + @P_NOMBRE_TABLA

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 PRINT @SQL_WHERE PRINT ' RETURN @@ROWCOUNT ' PRINT 'GO '

GO

La disposicin de espacios y bajadas de lneas se pueden ir acomodando a lo largo del armado de las variables y de la impresin 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 artculo. 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 Andrs Faya, quienes me motivaron y ayudaron para armar este artculo. Cualquier sugerencia que quieran hacer, modificaciones y/o correcciones (espero que las hagan) las pueden enviar a martinluchessi@yahoo.com.ar. Sobre las vistas de SQL pueden encontrar ms informacin 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 prxima.

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 partros de Las ventajas de usar los procedimientos almacenados incluyen:
o o

o o

Dise odular. Aplicaciones que acceden la misma Base de Datos pueden compartir los procedimientos almacenados, eliminando el c o doble y reduciendo el tama e las aplicaciones. El fl mantenimiento. Cuando un

entrada y retornar valores a la aplicaci


o

procedimiento se actualiza, los cambios se reflejan automcamente en todas las aplicaciones, sin la necesidad de recompilar y relinkear. Las aplicaciones son compiladas s una vez para cada cliente. 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 desempe especialmente para el acceso del cliente remoto.

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 informaci lmacenada y con un elemento muy importante a favor: Las l a as de c o 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. Cmo crear un procedimiento almacenado (SQL Server Management Studio) Nuevo: 5 de diciembre de 2005 En este tema se describe cmo crear un procedimiento almacenado de TransactSQL mediante el Explorador de objetos de SQL Server Management Studio y se 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, conctese a una instancia de SQL Server 2005 Database Engine (Motor de base de datos de SQL Server 2005) y expndala. 2. Expanda Bases de datos, la base de datos a la que pertenece el procedimiento almacenado y, por ltimo, Programacin. 3. Haga clic con el botn secundario en Procedimientos almacenados y, a continuacin, haga clic en Nuevo procedimiento almacenado. 4. En el men Consulta, haga clic en Especificar valores para parmetros de plantilla.

5. En el cuadro de dilogo Especificar valores para parmetros de plantilla , la columna Valor contiene valores recomendados para los parmetros. Acepte los valores o reemplcelos con nuevos valores y, a continuacin, haga clic en Aceptar. 6. En el editor de consultas, reemplace la instruccin 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 reemplcelo por un nombre nuevo y, a continuacin, 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 ms informacin, vea Inyeccin de cdigo SQL. Para crear un ejemplo de procedimiento almacenado 1. En el Explorador de objetos, conctese a una instancia de SQL Server 2005 Database Engine (Motor de base de datos de SQL Server 2005) y expndala. 2. Expanda Bases de datos, la base de datos AdventureWorks y, por ltimo, Programacin. 3. Haga clic con el botn secundario en Procedimientos almacenados y, a continuacin, haga clic en Nuevo procedimiento almacenado. 4. En el men Consulta, haga clic en Especificar valores para parmetros de plantilla. 5. En el cuadro de dilogo Especificar valores para parmetros de plantilla , especifique los siguientes valores para los parmetros mostrados.

Parmetro Author

Valor Su nombre.

Create Date Description Procedure_name @Param1 @Datatype_For_Param1 Default_Value_For_Param1 @Param2 @Datatype_For_Param2 Default_Value_For_Param2 6. Haga clic en Aceptar.

La fecha de hoy. Devuelve datos de empleado. HumanResources.uspGetEmployees @LastName nvarchar(50) NULL @FirstName nvarchar(50) NULL

7. En el editor de consultas, reemplace la instruccin SELECT por la siguiente instruccin: Copiar cdigo 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 informacin anterior y corrija lo que sea necesario. 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 categoras que aparecen en la siguiente tabla. En esta seccin Categora Procedimientos almacenados de Active Directory Procedimientos almacenados del catlogo Descripcin Se utilizan para registrar instancias de SQL Server y bases de datos de SQL Server en Active Directory de Microsoft Windows 2000. 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. Se utilizan para implementar la funcionalidad de variable de cursor. Se utilizan para el mantenimiento general del SQL Server Database Engine (Motor de base de datos de SQL Server). Se utilizan para realizar operaciones de correo electrnico desde una instancia de SQL Server.

Procedimientos almacenados de cursor Procedimientos almacenados del motor de base de datos Procedimientos almacenados de Correo electrnico de base de datos y SQL Mail

Procedimientos almacenados Se utilizan para configurar las tareas de de planes de mantenimiento de mantenimiento fundamentales necesarias para bases de datos administrar el rendimiento de las bases de datos. Procedimientos almacenados de consultas distribuidas Procedimientos almacenados de la bsqueda de texto Procedimientos almacenados del trasvase de registros Procedimientos almacenados de automatizacin Procedimientos almacenados de Notification Services Procedimientos almacenados de rplica Procedimientos almacenados de seguridad Procedimientos almacenados Se utilizan para implementar y administrar consultas distribuidas. Se utilizan para implementar y consultar ndices de texto. Se utilizan para establecer, modificar y supervisar las configuraciones de los trasvases de registros. Permiten utilizar objetos de automatizacin estndar en un lote estndar de Transact-SQL. Se utilizan para administrar SQL Server 2005 Notification Services. Se utilizan para administrar la rplica. Se utilizan para administrar la seguridad. Son utilizados por el Analizador de SQL Server para

del Analizador de SQL Server Procedimientos almacenados del Agente SQL Server Procedimientos almacenados de tareas Web Procedimientos almacenados de XML Procedimientos almacenados extendidos generales

supervisar el rendimiento y la actividad. Son utilizados por el Agente SQL Server para administrar actividades programadas y controladas por eventos. Se utilizan para crear pginas Web. Se utilizan para la administracin del texto XML. Proporcionan una interfaz de una instancia de SQL Server a los programas externos para diversas actividades de mantenimiento.

Nota: A menos que se documente especficamente 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 comunicar las solicitudes del usuario a una instancia de SQL Server. Estn destinados al uso interno del proveedor o el controlador. No se permite llamarlos explcitamente desde una aplicacin basada en SQL Server. La funcionalidad completa de estos procedimientos almacenados est disponible para las aplicaciones basadas en SQL Server a travs 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 travs de las propiedades y mtodos de cursor de la API de OLE DB y para las aplicaciones ODBC a travs 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_cursorfetch sp_cursorprepare

sp_cursorclose sp_cursoropen sp_cursorunprepare

sp_cursorexecute sp_cursoroption

Los siguientes procedimientos almacenados del sistema son compatibles con el modelo de preparacin o ejecucin para la ejecucin 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 transaccin. Este procedimiento almacenado tambin hace que se activen los eventos Audit Login y Audit Logout cuando se reutiliza una conexin de un grupo de conexiones. Los procedimientos almacenados del sistema de las siguientes tablas slo se utilizan en una instancia de SQL Server o a travs de las API cliente y no estn destinados al uso general. Estn sujetos a cambios y su compatibilidad no est garantizada. Los siguientes procedimientos almacenados estn documentados en los Libros en pantalla de SQL Server: sp_catalogs sp_column_privileges_ex sp_columns_ex sp_datatype_info sp_foreignkeys sp_pkeys sp_server_info sp_sproc_columns sp_table_privileges sp_tables sp_column_privileges sp_columns sp_databases sp_fkeys sp_indexes sp_primarykeys sp_special_columns sp_statistics sp_table_privileges_ex sp_tables_ex

Los siguientes procedimientos almacenados no estn documentados: sp_assemblies_rowset sp_assemblies_rowset2 sp_assemblies_rowset_rmt sp_assembly_dependencies_rowset

sp_assembly_dependencies_rowset_rm sp_assembly_dependencies_rowset2 t sp_bcp_dbcmptlevel sp_catalogs_rowset;2 sp_catalogs_rowset_rmt sp_check_constbytable_rowset sp_check_constbytable_rowset2 sp_check_constraints_rowset;2 sp_column_privileges_rowset sp_column_privileges_rowset;5 sp_column_privileges_rowset2 sp_columns_90_rowset sp_columns_90_rowset2 sp_columns_rowset sp_columns_rowset;5 sp_columns_rowset2 sp_datatype_info_90 sp_ddopen;10 sp_ddopen;12 sp_ddopen;2 sp_ddopen;4 sp_ddopen;6 sp_ddopen;8 sp_foreign_keys_rowset sp_foreign_keys_rowset;3 sp_foreign_keys_rowset_rmt sp_catalogs_rowset sp_catalogs_rowset;5 sp_catalogs_rowset2 sp_check_constbytable_rowset;2 sp_check_constraints_rowset sp_check_constraints_rowset2 sp_column_privileges_rowset;2 sp_column_privileges_rowset_rmt sp_columns_90 sp_columns_90_rowset_rmt sp_columns_ex_90 sp_columns_rowset;2 sp_columns_rowset_rmt sp_constr_col_usage_rowset sp_ddopen;1 sp_ddopen;11 sp_ddopen;13 sp_ddopen;3 sp_ddopen;5 sp_ddopen;7 sp_ddopen;9 sp_foreign_keys_rowset;2 sp_foreign_keys_rowset;5 sp_foreign_keys_rowset2

sp_foreign_keys_rowset3 sp_indexes_90_rowset_rmt sp_indexes_rowset sp_indexes_rowset;5 sp_indexes_rowset2 sp_linkedservers_rowset;2 sp_oledb_database sp_oledb_deflang sp_oledb_ro_usrname sp_primary_keys_rowset;2 sp_primary_keys_rowset;5 sp_primary_keys_rowset2 sp_procedure_params_90_rowset2 sp_procedure_params_rowset;2 sp_procedures_rowset sp_procedures_rowset2 sp_provider_types_rowset sp_schemata_rowset;3 sp_sproc_columns_90 sp_statistics_rowset;2 sp_stored_procedures sp_table_constraints_rowset;2 sp_table_privileges_rowset sp_table_privileges_rowset;5 sp_table_privileges_rowset2 sp_table_statistics_rowset;2 sp_tablecollations sp_tables_info_90_rowset sp_tables_info_90_rowset2

sp_indexes_90_rowset sp_indexes_90_rowset2 sp_indexes_rowset;2 sp_indexes_rowset_rmt sp_linkedservers_rowset sp_linkedservers_rowset2 sp_oledb_defdb sp_oledb_language sp_primary_keys_rowset sp_primary_keys_rowset;3 sp_primary_keys_rowset_rmt sp_procedure_params_90_rowset sp_procedure_params_rowset sp_procedure_params_rowset2 sp_procedures_rowset;2 sp_provider_types_90_rowset sp_schemata_rowset sp_special_columns_90 sp_statistics_rowset sp_statistics_rowset2 sp_table_constraints_rowset sp_table_constraints_rowset2 sp_table_privileges_rowset;2 sp_table_privileges_rowset_rmt sp_table_statistics_rowset sp_table_statistics2_rowset sp_tablecollations_90 sp_tables_info_90_rowset_64 sp_tables_info_90_rowset2_64

sp_tables_info_rowset sp_tables_info_rowset_64 sp_tables_info_rowset2 sp_tables_rowset;2 sp_tables_rowset_rmt sp_usertypes_rowset sp_usertypes_rowset2 sp_views_rowset2 sp_xml_schema_rowset2 Vea tambin Referencia CREATE PROCEDURE (Transact-SQL) Otros recursos

sp_tables_info_rowset;2 sp_tables_info_rowset_64;2 sp_tables_info_rowset2_64 sp_tables_rowset;5 sp_tables_rowset2 sp_usertypes_rowset_rmt sp_views_rowset sp_xml_schema_rowset

Procedimientos almacenados (motor de base de datos) Running Stored Procedures (OLE DB) Running Stored Procedures Ayuda e informacin Obtener ayuda sobre SQL Server 2005

También podría gustarte