sábado, 20 de septiembre de 2014

SQL Query analycer. Depurar un procedimiento almacenado (SP)

Introducción

En esta ocasión voy a explicar como ver lo que hace exactamente un sp utilizando el Query analycer de SQL SERVER. En vez de seguir la ejecución del sp paso a paso como si fuera un programa, lo que hacemos es convertirla en una consulta de SQL SERVER y ejecutarla para que devuelva el mismo resultado que si fuera una consulta más simple.

En muchas ocasiones los procedimientos almacenados (sp) contienen variables que comienzan por @ y no permiten su ejecución directa desde el analizador de consultas. Pero el método de depuración paso a paso con VS2005 puede ser demasiado tedioso o incluso no darnos la información que necesitamos.
Una forma más sencilla de ejecutar un sp rápidamente consiste el convertir en código ejecutable por SQL SERVER el sp a analizar y ejecutarlo directamente para ver el resultado.

Este ejemplo es tan sencillo que parecerá una perogrullada por que la salida será igual que la entrada. Pero en procedimientos muy complejos puede ser imposible su ejecución directa y tendremos que retraducir el procedimiento de este modo que se explicará a continuación. Por motivos didácticos no he considerado poner un sp más complejo.

Análisis del Procedimiento Almacenado



Para empezar abrimos en una nueva ventana el código del sp que deseamos depurar. Para ello, situados sobre el explorador de objetos de SQL SERVER desplegamos la lista de procedimientos almacenados y con el botón derecho del ratón elegimos la opción  Incluir procedimiento almacenado como-> CREATE To -> Nueva Ventana del editor de consultas.

Analizar un procedimiento almacenado complejo

Hecho esto, el procedimiento a depurar se abre en una ventana nueva. La idea es prescindir del código CREATE PROCEDURE y copiar todo el código incluidas las cláusulas DECLARE.

Este sería el código completo del procedimiento.

USE [dbDesarrollo]
GO
/****** Objeto:  StoredProcedure [DBO].[sp_Salvar]    Fecha de la secuencia de comandos: 09/15/2014 14:29:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO

create proc [Dbo].[sp_Salvar]
   @Codigo   char(2),
   @Descripcion varchar(80),
   @Instalacion char(7)
AS
   declare @Valor smallint
   select @valor = count(*) from dbo.Tbcarga
   where strcodigo = @Codigo and strcodigoinstalacion = @Instalacion
   if @Valor <> 0
      UPDATE dbo.TbCarga set strdescripcion = @descripcion
      where strcodigoinstalacion = @instalacion
      and   strcodigo = @Codigo
   else
      INSERT into dbo.Tbcarga values (@Instalacion,@Codigo,@Descripcion)

Sobre el procedimiento de ejemplo anterior marco a continuación en azul lo que copiaríamos para llevarnos y en marrón lo que no copiamos. Ojo, los parámetros de entrada del procedimiento almacenado los tenemos que sustituir por sus valores respectivos. No así con el resto de variables internas del sp.

USE [dbDesarrollo]
GO
/****** Objeto:  StoredProcedure [DBO].[sp_Salvar]    Fecha de la secuencia de comandos: 09/15/2014 14:29:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO

create proc [DBO].[sp_Salvar]
   @Codigo   char(2),
   @Descripcion varchar(80),
   @Instalacion char(7)
AS
   declare @Valor smallint
   select @valor = count(*) from dbo.Tbcarga,
   where strcodigo = '01' and strcodigoinstalacion = '1530300'
   if @Valor <> 0
      UPDATE dbo.TbCarga set strdescripcion = 'Ejemplo'
      where strcodigoinstalacion = '1530300'
      and   strcodigo = '01'
   else
      INSERT into dbo.Tbcarga values ('1530300','01','Ejemplo')


Si hacemos esto y nos llevamos el código marcado en azul al analizador de consultas las variables nos dará errores de este tipo y de otros..

Debe declarar la variable escalar "@Valor".

(en este caso concreto no dará error pues es un ejemplo muy sencillo)

Para poder ejecutar el procedimiento directamente en el analizador de consustas sin que nos de error podemos hacer lo siguiente:

Definimos una variable, por ejemplo la podemos llamar @Statement  Y la declaramos como Varchar de la máxima capacidad posible. Después la cargamos con el texto completo del procedimiento almacenado (lo que seleccionamos en azul) y entrecomillamos con comillas simples, esto lo coloreará de color rojo el propio analizador.

DECLARE @Statement VARCHAR (MAX)
   SET @Statement ='
    Bloque de texto del Procedimiento almacenado’
Print @Statement
--EXEC (@Statement)

GO

Si en vez de acabar con un EXEC como el que hemos comentado, ponemos un PRINT, la salida será un texto que contendrá una consulta ejecutable por el analizador de consultas. Nótese como las comillas simples se tienen que poner dobles.

DECLARE @Statement VARCHAR (MAX)
   SET @Statement ='
    declare @Valor smallint
   select @valor = count(*) from dbo.Tbcarga,
   where strcodigo = ''01'' and strcodigoinstalacion = ''1530300''
   if @Valor <> 0
      UPDATE dbo.TbCarga set strdescripcion = ''Ejemplo''
      where strcodigoinstalacion = ''1530300''
      and   strcodigo = ''01''
   else
      INSERT into dbo.Tbcarga values (''1530300'',''01'',''Ejemplo'')
Print @Statement
--EXEC (@Statement)

Si hemos puesto un PRINT obtendremos la siguiente salida.

declare @Valor smallint
   select @valor = count(*) from dbo.Tbcarga
   where strcodigo = '01' and strcodigoinstalacion = '1530300'
   if @Valor <> 0
      UPDATE dbo.TbCarga set strdescripcion = 'Ejemplo'
      where strcodigoinstalacion = '1530300'
      and   strcodigo = '01'
   else
      INSERT INTO dbo.Tbcarga values ('1530300','01','Ejemplo')


Ahora ya si podemos copiar este texto y ejecutarlo directamente en el analizador de consultas sin que nos de error.

En este caso concreto, la consulta es tan sencilla que el resultado de salida es el mismo que el de entrada, pero en sp muy complejos la salida puede ser  diferente. Si además son muy extensos, podemos ir troceando el sp para detectar en que bloque está el error.

Si el sp es demasiado largo no cabrá todo en una sola variable y habrá que trocearlo en varias variables situadas a intervalos regulares del procedimiento.


No hay comentarios:

Publicar un comentario