viernes, diciembre 02, 2011

EasyMax: problemas de intercalacion (collation) en SQL Server

La librería FASTCALC.LIB utiliza frecuentemente una técnica que consiste en subir un cursor con ciertos datos al servidor en forma de tabla temporal, que luego es usada para filtrar datos específicos de una o mas tablas del sistema.

Sin embargo, cuando sucede que la BD utiliza un collation distinto al collation configurado en el servidor SQL Server (situación que se presenta típicamente cuando se restaura la BD desde un backup hecho en otro servidor que usaba un collation distinto), se produce un error de intercalación al intentar mezclar en un mismo SELECT los datos de la tabla temporal con datos de las tablas de la BD.

Aun peor, el problema no se limita a las funciones de FASTCALC.LIB sino que afecta a cualquier rutina que haga uso de las funciones QGetTempName(), QCursor2Temp() y QCloseTemp() de dicha librería.

El problema se genera en la función QVFP2ODBC(), que es la encargada de tomar un cursor de memoria y subirlo a la BD en forma de tabla temporal.  Al hacer esto, las columnas tipo CHAR o VARCHAR son creadas con el collation por omisión del servidor (digamos MODERN_SPANISH), el cual no necesariamente coincide con el collation usado en la BD actual (ej, LATIN_GENERAL).

La siguiente version de QVFP2ODBC() soluciona este problema instruyendo a SQL Server para que cree las columnas CHAR y VARCHAR de la tabla temporal usando el collation de la BD actual en lugar del collation del servidor, lo cual soluciona el problema al garantizar que tanto la tabla temporal como las tablas relacionadas en la BD actual usan el mismo collation:


* QVFP2ODBC (FASTCALC.LIB)
* Toma un cursor de memoria y lo sube a la BD actual utilizando el collation de la BD
*
#DEFPARAM pcCursor,pcTable,poDB

*-- Se obtienen la estructura del cursor local
*
#defvar aStr,nCount
#dim aStr[1x1]

#dbselect &pcCursor
nCount:=AFIELDS(aStr)

#let pcTable:="#"+pcCursor on vartype(pcTable)<>"C" or empty(pcTable)
#let pcTable:="#"+pcTable on left(pcTable,1)<>"#"
#let poDB:=CURDB on Type("poDB.Name")<>"C"


*-- Se crea el comando CREATE para crear la tabla temporal en SQL
*
#defvar i,cSQL,nResult,cSQLDT,cIL
cSQL:="CREATE TABLE "+pcTable+" ("
cIL:="("
#for i:=1 to nCount
 cSQLDT:=""
 #let cSQLDT:="CHAR("+ALLT(STR(aStr[i,3]))+") COLLATE database_default" on aStr[i,2]="C" and aStr[i,3]<=10
 #let cSQLDT:="VARCHAR("+ALLT(STR(aStr[i,3]))+") COLLATE database_default" on aStr[i,2]="C" and aStr[i,3]>10
 #let cSQLDT:="NUMERIC("+ALLT(STR(aStr[i,3]))+","+ALLT(STR(aStr[i,4]))+")" on aStr[i,2]="N"
 #let cSQLDT:="BIT" on aStr[i,2]="L"
 #let cSQLDT:="TEXT COLLATE database_default" on aStr[i,2]="M"
 #let cSQLDT:="DATETIME" on aStr[i,2] $ "DT"
 #let cSQLDT:="INT" ON aStr[i,2] $ "I"
 #IF EMPTY(cSQLDT)
  MESSAGEBOX("Tipo no reconocido: " + aStr[i,2],0,"QVFP2ODBC")
 #ENDIF
 cSQL:=cSQL + IIF(i>1,",","") + aStr[i,1] + " " + cSQLDT + " NOT NULL"
 cIL:=cIL + IIF(i>1,",","") + "?m."+aStr[i,1]
#endfor
cSQL:=cSQL + ")"
cIL:=cIL + ")"

#defvar nODBCHnd
nODBCHnd:=QGethODBC(poDB)

*-- Se crea la tabla temporal
nResult:=SQLEXEC(nODBCHnd,cSQL)
#IF nResult < 0
 SQLEXEC(nODBCHnd,"DROP TABLE "+pcTable)
 nResult:=SQLEXEC(nODBCHnd,cSQL)
#ENDIF
#If nResult < 0
 Kernel.Err.Capture()
 #return No
#ENDIF



*-- Se carga la data del cursor en la tabla temporal
*
#dbselect &pcCursor
#dbgo top
#dowhile not eof()
 #fieldstovars
 SQLEXEC(nODBCHnd,"INSERT INTO "+pcTable+" VALUES "+cIL)
 #dbskip
#ENDDO


#return Si

3 comentarios:

LEONEL LÓPEZ dijo...

Saludos Victor, me he dedicado a buscar info acerca de las personas que trabajaron o trabajan con el EasyMax, herramienta administrativa que se utiliza en la empresa donde trabajo actualmente desde hace muy poco tiempo.
La consulta que quiera hacerte primero que todo es sobre las bondades que ofrece este sistema, pues en mis pocos 35 años de edad he visto varios erp como SAP, people soft, A2 y en mis inicios saint, y la verdad no habia visto un sw con tan pocas oportunidades de crecimiento o expansion. Trabajo en el area de compras y la verdad no nos ayuda en nada.
Estoy preparando una presentacion donde quiero dar a conocer mis humildes opiniones sobre las mejoras que pueden hacerse en nuestros procesos, porque lamentablemente no podemos quedarnos haciendo todo "manual" en Excel, se pierde demasiado tiempo. Me comprenderas si conoces SAP.

Espero tus comentarios y quizas podamos compartir en linea muchos conocimientos y experiencias.

Leonel Lopez
lopezleonel3@gmail.com

LEONEL LÓPEZ dijo...

Saludos Victor, me he dedicado a buscar info acerca de las personas que trabajaron o trabajan con el EasyMax, herramienta administrativa que se utiliza en la empresa donde trabajo actualmente desde hace muy poco tiempo.
La consulta que quiera hacerte primero que todo es sobre las bondades que ofrece este sistema, pues en mis pocos 35 años de edad he visto varios erp como SAP, people soft, A2 y en mis inicios saint, y la verdad no habia visto un sw con tan pocas oportunidades de crecimiento o expansion. Trabajo en el area de compras y la verdad no nos ayuda en nada.
Estoy preparando una presentacion donde quiero dar a conocer mis humildes opiniones sobre las mejoras que pueden hacerse en nuestros procesos, porque lamentablemente no podemos quedarnos haciendo todo "manual" en Excel, se pierde demasiado tiempo. Me comprenderas si conoces SAP.

Espero tus comentarios y quizas podamos compartir en linea muchos conocimientos y experiencias.

Leonel Lopez
lopezleonel3@gmail.com

Victor Espina dijo...

Hola Leonel. La verdad, creo que en tu caso se trata principalmente de desconocimiento de la herramienta.

EasyMax es un sistema muy amigable (demasiado algunas veces) que facilita muchisimo los ciclos principales de cualquier empresa, especialmente en las areas de venta, compra, contabilidad y tesoreria.

Sin embargo, como todo ERP, su efectividad en una implantacion particular depende mucho del trabajo realizado durante el levantamiento de informacion y la posterior adaptacion del software.

Mi recomendacion seria que contataras a la empresa AvaQs Consultores (www.avacon.com.ve) y solicitaras una asesoria para ver de que forma pueden sacarle el maximo provecho a la herramienta que tienen.