lunes, septiembre 07, 2009

Migrar BD de Mysql a PostGreSQL (parte 3)

Conversión de tipos

Resulta, que cuando vemos lo que nos dice el espejo que hemos creado de mysql sobre postgresql con dbi-link, los campos son creados como tipo text, con un comentario en la vista que dice qué tipo de dato aproximado debería haber ahí...

Esto es así, porque los tipos de datos entre diferentes gestores normalmente no son iguales, es decir, todos aplican los estándares, pero además, cada uno le da su toque, de manera que es posible que tenga más o menos, y que de paso, se llamen diferentes... o más bien, se le aplique aliases...

El tema es que cuando trato de leer para insertar en otra tabla, en un proceso de migración, debo tener muy presente los tipos de datos, ocasionalmente, podría recibir un mensaje del tipo:

Error de SQL:

ERROR: la columna «id» es de tipo integer pero la expresión es de tipo text
LINE 1: INSERT INTO cultu03 (id, cultu02_001, cultu03_002) (SELECT c...
^
HINT: Necesitará reescribir la expresión o aplicarle una conversión de tipo.

En la declaración:
INSERT INTO cultu03 (id, cultu02_001, cultu03_002) (SELECT codcat, codedi, catedi FROM sir_cultura_catedi)

Con lo cual, cualquiera se asusta a la primera... y no hace falta... con leer el mensaje y fijarme en la frase "aplicarle una conversión de tipos" será más que suficiente para tener algo de calma nuevamente...

¿qué es una conversión de tipos? digamos que tenemos un campo de un tipo de dato (p.e. text), pero queremos "interpretar" su contenido como sí fuera otro tipo de dato (p.e. int)... a eso se le conoce como conversión de tipos

INSERT INTO cultu03 (id, cultu02_001, cultu03_002) (SELECT codcat::int, codedi::int, catedi FROM sir_cultura_catedi)

o

INSERT INTO cultu03 (id, cultu02_001, cultu03_002) (SELECT cast(codcat as int), cast (codedi as int), catedi FROM sir_cultura_catedi)

y listo!!!

Una consultica que tiene algo más:

INSERT INTO cultu04 (reg_001, est_001, mun_001, par_001, cpo_001, cultu04_001, cultu04_002, cultu04_003, cultu04_004, cultu04_005, cultu04_006, cultu04_007, cultu02_001, cultu03_001)
(SELECT codreg, codest, codmun, codpar, codcen, anno, nombre, direccion, telefono, correo, web,
CASE WHEN area <> '' THEN
CAST(area AS numeric)
ELSE
0
END,
codedi::int, codcat::int FROM sir_cultura_edif_det)

Creo que no hace falta explicar la estructura de las tablas, sólo entender que leo en una tabla e inserto lo que estoy leyendo, con algunas particularidades sencillas....

Una más

INSERT INTO acu03 (reg_001, est_001, mun_001, par_001, cpo_001, acu03_001, acu01_001, acu03_003, acu03_004, acu03_005, acu02_001, acu03_006, acu03_007, acu03_008)
(SELECT codreg, codest, codmun, CASE WHEN codpar = 'NA' THEN '00' ELSE codpar END, CASE WHEN codcen = 'NA' THEN '000' ELSE codcen END, EXTRACT(YEAR FROM agno)::int, tipo::int, nb_acueducto, fuentes, caudal, tratamiento::int, suscriptores, poblacion, produccion FROM servicios_acueducto)

2 comentarios:

Cesar Carbonara dijo...

INSERT INTO edu04 (reg_001, est_001, mun_001, par_001, cpo_001, edu07_001, id, edu04_002, edu04_003, edu02_001, edu04_004, edu09_001)
(SELECT codreg, codest, codmun, codpar, codcen,
CASE WHEN anoesc = '2004-2005' THEN 1
WHEN anoesc = '2005-2006' THEN 2
ELSE 0
END::int,
codplan::int, nomplan, nomdir, coddep::int, dirplan,
CASE WHEN areaplan = 'RURAL' THEN 4
WHEN areaplan = 'URBANO' THEN 5
WHEN areaplan = '0' THEN 0
END::int
FROM sireduca01);

Cesar Carbonara dijo...

INSERT INTO est03 (reg_001, est_001, mun_001, par_001, cpo_001, est01_001, est03_001, est03_002, est03_003, est03_004, est03_005, est03_006, est02_001)
(SELECT codreg, codest, codmun,
CASE
WHEN codpar = 'NA' THEN '00'
WHEN codpar = '' THEN '00'
ELSE codpar END,
CASE
WHEN codcen = 'NA' THEN '000'
WHEN codcen = '' THEN '000'
ELSE codcen END,
codact, anno, nombre, direcc, telefono, nroemp::int, nroobr::int,
CASE
WHEN estrato = '0' THEN 1
WHEN estrato = 'I' THEN 2
WHEN estrato = 'II' THEN 3
WHEN estrato = 'III' THEN 4
WHEN estrato = 'IV' THEN 5
END
FROM establec)