lunes, 23 de agosto de 2010

Debugar asp.net

Recientemente he tenido un problema en el momento de debugar aplicaciones asp.net, y es que si bien me permitia ejecutar no se detenia en los puntos de debugación marcados. La solución a este problema es la siguiente :

1.Abre el Editor de Registro (Inicio / Ejecutar / Regedit.exe)

2.Navegue hasta la clave: HKEY_LOCALMACHINE / SOFTWARE / Microsoft / Internet Explorer / Main

3.Dentro de esa clave, agregue un Valor DWORD de nombre TabProcGrowth (Dentro de la clave haga clic derecho, seleccione la opción Nuevo y luego Valor DWORD)

4.Finalmente haga doble clic en el valor creado y establezca su valor en 0 (cero).

5.Cierre el Editor de Registro.

miércoles, 28 de octubre de 2009

with Recompile

Desde hacia días detectaba un procedimiento con un extraño comportamiento, el rendimiento de la consulta era inferior a la ejecución de la consulta directamente. ¿Como puede ser esto?

Como siempre en estos casos recurrí a los foros de internet, rápidamente obtuve una respuesta "parameter sniffing".

Resulta que una de las subconsultas del procedimiento se obtenía de una función que devolvía una tabla, y en este caso no se calcula correctamente el plan de ejecución. Asi que si no se recompila el procedimiento el rendimiento es deficiente, para subsanar este problema se puede añadir la clausula with recompile, obligando a sql-server a preparar cada vez un nuevo plan de ejecución.

El uso de la clausula es como sigue:

create proc dbo.prueba
@id int
with recompile
as
select * from tabla where id = @id

miércoles, 13 de mayo de 2009

Quitar hora a la fecha en tsql

Función para eliminar la parte de hora en una fecha.

ALTER FUNCTION [dbo].[f_fechaCadena] (@fecha datetime)
returns varchar(15)
as
begin
declare @fechaStr varchar(15)
set @fechastr = CONVERT(VARCHAR,@FECHA,103)
return @fechaStr
end

Convert con la clausula 103, elimina la parte de hora de una fecha en sql-server.

jueves, 7 de mayo de 2009

With para tablas temporales

With consulta1 (id, codigo) as (select id,codigo from tabla where campo2 = 'x')

select * from consulta1

resultados:
ID CODIGO
--- ----------
1 32323
2 CODIGO 2

Una cosa curiosa, es que antes de esta instrucción la instruccion previa debe terminar con ';'.

viernes, 24 de abril de 2009

Parametros multiples con tsql (xml)

Como varias filas a sql-server para que hacer inserciones multiples, o transaccionales en un mismo procedimiento.. pues con xml.

BEGIN

DECLARE @HDOC INT -- Puntero a la estructura xml

DECLARE @XML xml -- Xml en 2005, para 2000 seria una cadena de caracteres

SET @XML = 'xml' -- el xml de ejemplo

EXEC SP_XML_PREPAREDOCUMENT @HDOC OUTPUT, @XML -- preparamos el documento xml para procesarlo

SELECT * FROM OPENXML(@HDOC,'/ArrayOfInt/int',3) WITH (xint int 'text()')
-- lo procesamos fijarse en la clausula with donde se especifica la estructura de la tabla de destino

EXEC SP_XML_REMOVEDOCUMENT @HDOCEND -- Liberamos de memoria la preparación del documento

CASE EN TSQL

Case se utiliza para devolver un valor condicionalmente dependiendo de otro valor o un calculo.

Por ejemplo imajinaros que queremos que en una consulta aparezca un semaforo dependiendo de una variable.
declare @campo1 int

set @campo1 = 2
select case @campo1 when 1 then 'verde' when 2 then 'rojo' else 'naranja' end

jueves, 23 de abril de 2009

Uso de cursores

Hace tiempo leí en un artículo una frase referente a cursores que me quedo grabada. "Todo lo que se pueda hacer con cursores se puede hacer con sql" y la verdad es ha sido mi guión a la hora de desarrollar nuevos procedimientos.

He de comentar que realmente he comprobado dicha frase, y es más también puedo decir que la diferencia entre usar cursores y es mucha, Sobre todo en cuanto a tiempo de proceso hablamos.

Pero menos rollo y vamos al tema:

  • Primero lo declaramos, le daremos un nombre (para el ejemplo lo llamares cr1) y prepararemos la select que usaremos para seleccionar la información que queremos. DECLARE CR1 CURSOR LOCAL FOR SELECT CAMPO1,CAMPO2 FROM TABLA
  • Fijaos que aunque usamos DECLARE, el nombre de la variable no lleva la arroba (@).
  • Deberemos declarar las variables que usaremos para almacenar el valor de los campos. DECLARE @CAMPO1, @CAMPO2 INT
  • Se declararan tantas variables como campos tengamos en la select.
  • Ya podemos abrir el cursor OPEN CR1
  • Y Movemos el cursor al primer registro, los valores los almacenaremos en las variables declaradas y el orden de los campos debe ser el mismo que en la select.
  • FETCH NEXT FROM RS INTO @CAMPO1, @CAMPO2
  • Ya podemos empezar el bucle de recorrido del cursor:

WHILE @@FETCH_STATUS = 0

BEGIN

PROCESOS ----

FETCH NEXT FROM CR1 INTO @CAMPO1, @CAMPO2

END

  • No se debe olvidar de cerrar el cursor (CLOSE CR1) y liberar de la memoria el cursor (DEALLOCATE CR1).

El tema de cursores se puede complicar más, por ejemplo el @@fetch_status puede tener diferentes valores y el cursor se puede mover adelante y atrás. Pero esto lo explicare en otro artículo. ;)