sábado, 6 de febrero de 2010

t-innova: Migración Vistas SQLServer2000 a SQLServer2005

Esta semana me he encontrado un problema importante al migrar un t-innova de un SQL Server 2000 a un 2005.

El principal problema ha sido el Collation o Intercalación; este concepto de hace referencia al patrón de bits utilizado para representar/almacenar cada carácter, y en consecuencia también se refiere a las reglas utilizadas para ordenar y comparar caracteres. Evidentemente, se trata de un concepto que afecta sólo a los campos de texto. Para más información leer este Link

Para T.innova, como indica en su documentación, el collation que se indica que tiene que tener es Sql_Latin1_General_CP1_CI_AS.
El ESS el collation que tiene que tener es el Tradicional_Spanish_CS_AS.

Estas Collations son incompatibles y si haces una Query que junte ambos entornos obtendrás un error del estilo: "Cannot resolve collation conflict for equal to operation"

La solución pasa por, sobre la base de datos del ESS, recrear las vistas que atacan contra la base de datos de Tinnova, para forzar el collation que tienen en nuestra base datos (ESS) de la siguiente forma:

CREATE VIEW [dbo].[M4_ACUMU_CERHAB_ST]
AS SELECT
A.ID_SOCIEDAD COLLATE Tradicional_Spanish_CS_AS,
A.ID_EMPLEADO COLLATE Tradicional_Spanish_CS_AS,
. . .
FROM M4T_ACUMULADO_RL A, M4T_ACUM_RL2_ST B
WHERE
. . . .
GO


Podemos obtener el script completo de las vistas (sino lo tenemos) mediante la herramienta de SQL Server: "Microsoft SQL Server Management Studio". Nos posicionaremos en la base de datos del ESS y generamos los scripts con la opción "Generar secuencias de comandos".

Ahora que tenemos el script, tenemos el problema saber que campos son los que son afectados por el cambio de COLLATION en vistas que suelen ser "select * from"

Así que probe a hacer otras cosas... cambiar el collation de la base de datos del ESS, que se cambia, pero no los objetos que ya existieran, crear una BD nueva crear las tablas con un script optenido con "Generar secuencias de comandos", cargar los datos usando bcp o RAMDL,... pero nada obtenía errores.

Así que me puse a ver como estaban definidas las vistas y lo conseguí... (una semana depués pero en fin)
  1. Necesito saber las vistas y las columnas que usa el portal y que apuntan a EMIND:
    select a.name, b.name, b.xusertype, c.name
    from sysobjects a, syscolumns b, systypes c
    where
    a.xtype = 'V'
    and a.name not in('M4VCH_CONCEPTS', 'M4VCH_ITEMS', 'M4VCH_PI_COMP_TP', 'M4VCH_PICOMPONENTS', 'M4VDC_FIELDS','M4VDC_TIS_OWNER_T3', 'M4VDC_TIS_T3','M4VWP_OUTPUT_REP')
    and a.id = b.id
    and b.xtype = c.xtype
    order by a.name


    [El not in está creado viendo las vistas que son de PeopleNet]
  2. Luego las he llevado al excel "Migracion Vistas SQLServer2000 a SQLServer2005.xls" Hoja "VISTAS + COLUMNAS" (que os dejo en un link al final del articulo). Se pegan las 4 columnas de la vista en la columnas A,B,C,D (La D realmente no hace falta porque es informativa)
  3. En la Hoja "VISTAS ESPECIALES" ponemos en la columna A las vista que no son "SELECT *". En la columna "C" dejaremos la creación de estas vistas teniendo en cuenta el COLLATION.
  4. La propia columna H, de la hoja "VISTAS + COLUMNAS", nos da el script que hace la creación de todas las vistas teniendo en cuenta el nuevo Collation que dejaríamos en la celda B1=Traditional_Spanish_CS_AS.
  5. Para poder lanzar el script en SQL Server de forma masiva es necesario pegar en algun editor y cambiar ")" por ")[RET.CARRO]GO[[RET.CARRO]" (i.e., en Winword es: )^lGO^l)
  6. Antes de hacer creación será necesario crear el script de DROPs (os dejo mi ejemplo) de vistas y luego lanzar este más el de las tablas Especiales (os dejo mi ejemplo).

Y después todo a funcionado...

Hay teneis los archivos: Link

Si teneis dudas ... ya direis

[08/02/2010] Bueno, mi gozo en un pozo... al seguir haciendo pruebas, me he encontrado con un problema tras crear las vistas; ahora cuando intento insertar en las vistas, i.e.:

INSERT INTO M4T_ABSENTISMOS (COMENT, FEC_ALTA_EMPLEADO, FEC_ALTA_RECAIDA, FEC_FIN, FEC_FIN_RECAIDA, FEC_INI_RECAIDA, FEC_INICIO, ID_EMPLEADO, ID_SOCIEDAD, ID_TIPO_ABSENTISMO) VALUES (NULL, {d '2009-11-04'}, NULL, {d '2010-03-02'}, NULL, NULL, {d '2010-03-01'}, '02280481', '02', '9')

Obtengo otro error:

Mens. 4406, Nivel 16, Estado 1, Línea 1
Update or insert of view or function 'M4T_ABSENTISMOS' failed because it contains a derived or constant field.


Buscando por Google he visto que esto se deriba de intentar hacer inserts contra tablas que tengan algún campo calculado. [Recordemos que tras mis modificaciones inciales, cambiamos los select * de las vistas estándar de Meta4 por sus select campos]

He visto, en concreto en esta tabla que la columnas USUARIO, FEC_ULT_ACUALIZACION y HOSPITALIZACION se calculan al insertar, pero quitandolos de la vista sigo obteniendo el mismo error.

La solución pasa por generar triggers INSTEAD OF para que no se guarde en la vista sino a través de ella:


CREATE TRIGGER INSTEADOF_TR_I_M4T_ABSENTISMOS
ON M4T_ABSENTISMOS
INSTEAD OF INSERT AS
BEGIN
INSERT INTO LINK.EMIND.dbo.M4T_ABSENTISMOS (COMENT, FEC_ALTA_EMPLEADO, FEC_ALTA_RECAIDA, FEC_FIN, FEC_FIN_RECAIDA, FEC_INI_RECAIDA, FEC_INICIO, ID_EMPLEADO, ID_SOCIEDAD, ID_TIPO_ABSENTISMO)
SELECT COMENT, FEC_ALTA_EMPLEADO, FEC_ALTA_RECAIDA, FEC_FIN, FEC_FIN_RECAIDA, FEC_INI_RECAIDA, FEC_INICIO, ID_EMPLEADO, ID_SOCIEDAD, ID_TIPO_ABSENTISMO
FROM INSERTED

END

Con esto parece que todo va ok... habría que replicar este tipo de trigger (para INSERT, UPDATE y DELETE) para el resto de vistas y tablas que den problemas.



1 comentario:

Alex dijo...
Este comentario ha sido eliminado por un administrador del blog.