martes, 31 de marzo de 2009

Oracle: Unpivot artesanal

Todos estamos esperando utilizar el Oracle 11 que nos ahorre estos dolores de cabeza, pero mientras llega...

Si alguna vez se han preguntado ¿Puedo cambiar mis columnas a filas? Ejemplo:

Tenemos:
UNIDAD VALOR1 VALOR2 VALOR3
1 100 200 300
2 400 500 600

Queremos:
UNIDAD VALOR PRECIO
1 VALOR1 100
1 VALOR2 200
1 VALOR3 300
2 VALOR1 400
2 VALOR2 500
2 VALOR3 600

Sí! Es posible! Esto se llama unpivot, y la forma de hacerlo 'a la antigua' es:

SELECT UNIDAD, 'VALOR'l as VALOR,
DECODE(l, 1, VALOR1,
DECODE(l, 2, VALOR2,
DECODE(l, 3, VALOR3,
DECODE(l, 4, VALOR4,
DECODE(l, 5, VALOR5,
DECODE(l, 6, VALOR6 )))))) UNPIVOT
FROM TABLA,
(SELECT level l FROM DUAL X CONNECT BY LEVEL <= 6) NIVEL;

Esta es la página donde aparece el ejemplo:

http://www.club-oracle.com/forums/f6/unpivoting-column-to-row-conversion-techniques-sql-t145/

Mantener el Focus después de Evento TextChanged

Esto parecía una tontería y me demoré como 1,5 horas en encontrar una solución.

Asumamos que tenemos dos campos TextBox. El primero tiene el evento TextChanged y AutoPostBack TRUE, esto es así en mi caso porque luego de que introduzco un número de cuenta se supone que me debe aparecer el nombre de la cuenta. Cuando eso pasaba el focus se perdía para siempre.

Pero el señor del cual adjunto la página encontró la solución. Es demasiado larga para colocarla aquí, así que les comparto el link:

http://gmamaladze.googlepages.com/maintainfocusbetweenpostbacksalsoinasp.n

Nhibernate: Utilizar IN en un NamedQuery

Para poder usar IN se puede hacer utilizando SetParameterList y una lista con los valores a buscar.

Este es el ejemplo:

Nhibernate:
select id_tipo, tipo_dia, descripcion
from tipo_dia
where id_tipo in (:prueba)

VB:
Dim instance As New List(Of Int32)()
instance.Add(1)
instance.Add(2)

q = Me.GetCurrentSession.GetNamedQuery("ConsultaPrueba")
q.SetParameterList("prueba", instance)
Datos = q.List(Of Entities.Datos)()

Es decir, que tal vez desde el WebApps puedas enviar la lista, que opinas :)

Sumar una columna en un Dataset

Buenas compañeros,

El día de ayer me preguntaba si podía hacer una suma de una columna del dataset, pero sin recorrerlo.

Bueno, al parecer, desde la versión 2.0 esto se puede hacer con las funciones compute.

Les envío mi ejemplo y los sitios donde encontré la información:

Suma débitos:
Dim db As Object = dt.Compute("Sum(Monto)", "Mov = 'D'")

Suma créditos:
Dim db As Object = dt.Compute("Sum(Monto)", "Mov = 'C'")

Puntos a considerar:
El primer argumento de la función es el cálculo, y el segundo el filtro.
Permite: SUM, AVG, MIN, MAX, COUNT, y otras más que verán en los links que les adjunto.
Esto NO es permitido: Sum (Monto1 – Monto2). Habría que crear una columna computada y luego sumarla.
Todos los campos de un datatable creado manualmente son string por defecto, o sea que estos cálculos no se pueden hacer. Hay que crear la columna del tipo correcto.
IMPORTANTE: Este método aparentemente no es muy eficiente en datasets demasiado grandes, pero es mejor que recorrer el dataset. En tema de performance lo ideal es hacer esto directamente en la Base de Datos si es posible (http://weblogs.asp.net/eporter/archive/2003/11/11/36977.aspx)

Fuentes:
http://msdn.microsoft.com/es-es/library/system.data.datatable.compute(VS.80).aspx
http://msdn.microsoft.com/es-es/library/system.data.datacolumn.expression(VS.80).aspx