miércoles, 5 de diciembre de 2012

SSIS y los MessageBox

Sigo en mi proceso de migración de los paquetes versión 2000 a 2008, en está ocasión me encontré con una características que me libera de una preocupación.

En muchas ocasiones cuando he estado desarrollando un paquete he utilizado un MessageBox desde una tarea de script, para depurar los valores de las variables del paquete. En una ocasión le sucedió a un colega que olvidó comentar la linea de código del MessageBox y actualizó el paquete en el ambiente de producción, esto provocó muchos problemas porque el paquete no terminaba de ejecutarse esperando su clic en el botón "Ok" del MessageBox y detenía todo la cola de procesos.

Pero con SSIS 2008 no se presenta ese problema, MS lo hizo más inteligente, ¿Sería  que con mucha frecuencía los desarrolladores dejaban MessageBox en sus paquetes? pues ahora se genera el siguiente error cuando se ejecuta un paquete con MessageBox

Description: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. --->; System.InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application.
Cuidado, que si SSIS esta configurado para mostrar la notificaciones el MessageBox se invocará y se quedará esperando su clic para continuar.

El código para ejecutar el paquete:

DTExec 
  /sql Operaciones
  /set \Package.Variables[User::correo].Properties[Value];mi@correo.com
  /set \Package.Variables[User::file].Properties[Value];data.zip
  /set \Package.Variables[User::tipo].Properties[Value];mensual

viernes, 16 de noviembre de 2012

SSIS: NULL(DT_STR, «length», «code_page»)

Migrando un DTS de SQL Server 2000 a un paquete de SSIS 2008, me econtré dos situaciones muy interesante.

Escenario


El DTS se encarga de cargar un archivo de texto plano de una fuente externa a una tabla en SQL Server, en una columna tipo fecha se presenta una particularidad. El campo presenta tres valores diferentes:

  1. vacío, separador de columna continuo (,,) el cual se intepreta como valor nulo
  2. el texto NULL
  3. o una fecha con hora (01/01/2012 00:00:00)

DTS Preview
Imagen 1 - Columna con tres diferentes valores

Caso 1


Con el DTS de SQL Server 2000 los datos se cargan sin ninguna complicación, tanto vacío como NULL son intepretado como un valor nulo en la tabla. Esto no ocurre en el paquete SSIS 2008, sino que se genera un error "The value could not be converted because of a potential loss of data.", el motivo de este error es obvio, el texto NULL no se puede convertir a una fecha validad.

Datos en la Tabla
Imagen 2 - Datos importados a SQL Server


La solución a este caso fue utilizar una transformación Derived Column, esta me permite evaluar el valor de la columna problemática y generar uno nuevo a partir de este.


Caso 2

Como el problema era el valor NULL, por lo anto el objetivo consistió en usar la transformación Derived Column para remplazarlo por vacío, además se configuró la transformación para que sobreescriba el campo y no generar una columna nueva. El tipo de dato de la columna era string[DT_STR] esto es de esperarse porque la fuente de los datos es un archivo de texto plano.

En la primera expresión que escribí utilicé la función NULL(DT_STR, «length», «code_page»), esta función debería de devolver un valor vacío (nulo) válido para el tipo de dato de la columna origen.

[Column 53] == "NULL" ? NULL(DT_STR,50,1252) : [Column 53]


Pero la expresión generaba este error:

Error at Cargo datos [Derived Column [369]]: For operands of the conditional operator, the data type DT_STR is supported only for input columns and cast operations. The expression "[Column 53] == "NULL" ? NULL(DT_STR,50,1252) : [Column 53]" has a DT_STR operand that is not an input column or the result of a cast, and cannot be used with the conditional operation. To perform this operation, the operand needs to be explicitly cast with a cast operator.
¿Qué? El mensaje de error explica que el valor resultante debe provenir de una columna de entrada o o de una operación de conversión de tipos. Entonces, el tercer argumento del operador ternario ?: esta correcto porque el valor proviene de una columna de entrada de datos, pero el segúndo argumento es la función NULL() que no es un cast ni es un una columna de entrada, por lo tanto lo correcto es:

--ahora con cast
[Column 53]=="NULL"?(DT_STR,50,1252)NULL(DT_STR,50,1252):[Column 53]


Resumen

--incorrecto
[Column 53]=="NULL"?NULL(DT_STR,50,1252):[Column 53]
--cast incorreto
(DT_STR,50,1252)([Column 53]=="NULL"?NULL(DT_STR,50,1252):[Column 53])
--correcto
[Column 53]=="NULL"?(DT_STR,50,1252)NULL(DT_STR,50,1252):[Column 53]

jueves, 15 de noviembre de 2012

Recomendado: JavaScript Succinctly

Recuerdo mi primer ¡Hola mundo! con Javascript, eso fue en el año 2002, mi editor HTML en esa época era Notepad. Estoy casi seguro que todos los programaodores Web han tenido un amor a primera vista con Javascript.

Aún sin tener la plena conciencia de lo que era Javascript en esos días y de lo que llegaría hacer hoy, empecé a introducirme en el mundo mágico de este lenguaje para manipular el DOM. Navegando entre varios sitios, unos muy buenos otro no, fui mejorando mi habilidad en usar el lenguaje.

Pero a pesar de toda la experiencia adquiridad en el camino y de ser una herramienta indiscutible en mis últimos proyectos Web, nuca consideré tener un profundo conocomiento del lenguaje hasta que leí el e-book JavaScript Succinctly de Syncfusion.com. Gracias a ese libro logré entender la arquitéctura de Javascript.

miércoles, 14 de noviembre de 2012

sysindexes, sys.indexes y INFORMATION_SCHEMA

Estoy en el proceso de migrar los DTS de SQL Server 2000 a paquetes de SSIS de 2008. Estoy aprovechando para implementar algunas mejores prácticas. La primera duda que tuve fue con el uso de sysindexes para saber de la existencia de un índice, era de mi conocimiento que lo recomendado por MS es utilizar sys.indexes porque sysindexes es considerado obsoleto y se mantiene para compatibilidad con versiones anteriores, es decir que el código que escribí en 2006 aún funciona, pero aún tenía la duda ¿cuál sería la mejor práctica?

Decidí consultar con él DBA, su repuesta fue que la mejor práctica para consultar la metadata en SQL Server es utlizar el conjunto de vistas INFORMATION_SCHEMA que es un estándar ANSI que MS implentó en SQL Server, pero el estándar no contempla brindar información de los indices.

Al final mi sentencia quedó:

IF EXISTS(SELECT 1 FROM sys.indexes WHERE name = 'IDX')
 DROP INDEX nombre_tabla.IDX

Para finalizar, doy a conocer mi decepción de la función "Migrate..." para los DTS, no me ha servido para nada porque la parte fundametal que es el Data Flow no la migra.

jueves, 18 de octubre de 2012

Aprendí a leer la ayuda

En el primer semestre de mi carrera me introdujeron en el mundo de PASCAL y C para convertir la teoría en práctica. Al inicio era muy fácil porque solo se trataba de transcribir los código que el profesor(a) nos daba en papel.

Luego llegó el momento en que deje ser un simple mono (digitador) y me volví un Homo Sapiens, deseaba hacer cosas diferentes y aprender nuevas funciones, expresiones, etc., pero me encontré con una temible tecla F1.

Para mí era como leer jeroglíficos, no entendía para nada el lenguaje usado en la ayuda y me costaba interpretar los ejemplos proporcionados. A medida a que más me enfrentaba a la ayuda fue mejorando mi habilidad para leer misma, sobre todo la notaciones usadas para representar la sintaxis del lenguaje.

Ahora que he adquirido algo de madurez lo primero que hago al valorar cualquier herramienta tecnológica es revisar la calidad de la ayuda con el objetivo de disminuir la curva de aprendizaje  de la nueva herramienta.

Cuando empezó popularizarse el uso de las librerías de JavaScript lo primero que hice fue investigar en los foros cuales eran las más usadas, encontré algunos nombres como Prototype, Mootools y JQuery. En esa epoca las más populares eran Mootools y JQuery, pero para decidirme en cual usar visité cada sitio para leer su respectiva documentación (ayuda), para mí la de Prototype era la más fácil de aprender y minimizaría la curva de aprendizaje, la documentación de las otras me pareció muy confusa.

Prototype sin duda me consquistó al mundo de las librerías de JavaScript, pero JQuery se popularizó bastante y empezó hacer la más usada, además ofrecía muy buenas características que realmente me interesaban, así que pronto me cruce a JQuery. Pero mi paso por Prototype me ayudó mucho facilitarme la transición. Cuando visitaba la documentación de JQuery ya no me pareció confusa y se me hizo más fácil interpretar y comprender los ejemplos.

Sin duda el saber leer la documentación o ayuda ha sido una de mis mejores armas para poder profundizar mis conocimientos en una herramienta tecnológica.

viernes, 13 de abril de 2012

Deseo Cumplido


Nunca pensé que extrañaría algo de MS Access, pero así fue.

La primera versión de MS SQL Server que usé fue la 7, aunque por muy poco tiempo, la transición a 2000 fue rápida; con 2k fue que profundice en la codificación de T-SQL.

Lo impensable, extrañaba la función IIF de MS Access, era un experto usándola y con frecuencia me preguntaba ¿Por qué SQL Server no tiene la función IIF? me imagino que pensaras que soy un caprichoso y que la expresión CASE WHEN era mas que suficiente y asi es, estas en toda la razón.

Pero me parece que MS se dio cuenta de la importancia de poder escribir código con personalidad y elegancia. Y desde la versión 2005 a venido agregando mayores características a T-SQL que permiten escribir un código de programador elite, por ejemplo TRY CATCH, WITH, etc.

Sorpresa, mi deseo fue cumplido en la versión 2012 que incluye la función IIF, ahora podre escribir código T-SQL con un toque de poesía. Lo anterior me lleva a pensar que mi deseo no era un capricho sino una validad necesidad.

Para conocer más de las nuevas características de SQL 2012 visita Programmability Enhancements (Database Engine)

lunes, 9 de abril de 2012

A defenderse de XSRF

El desarrollo web implica mucho estar al tanto de las diferentes forma de ataques, hasta el momento conocía SQL Injection y Cross-site scripting (XSS). Hoy conocí Cross-Site Request Forgery (XSRF), así que tengo que algo nuevo que  aprender y aplicar en los sitios que tengo en producción.
´