La función tiene como propósito el checar una tabla para encontrar similitudes entre sus datos (duplicados), para después quitarlos, por endé se le envían las columnas a comparar y el nombre de la tabla también.
Ahora he hecho que la función pueda construir las consulta necesarias, tanto para la creación de una tabla de respaldo donde trabajara y hasta ahora la consulta que detectará de forma única la "N" cantidad de elementos repetidos a los cuales debo pasar a otra tabla, la cuál solo tenga la estructura base de unicamente las columnas que se envían a través de la función, además de una columnas extra llamada "group_duplicate" la cual solo debe marcar con un identificador único a cada elmento de grupos repetidos.
Esta última consulta ya también esta, tanto para la creación de la tabla a base de las columnas enviadas.
Por ejemplo para una llamada como:
SELECT emu_winpure('articulo, autor, clasif, u_fech_mov, fech_ped, codigo', 'productos');
Obtengo estás consultas:
NOTICE: CREATE TABLE productos_winpure AS (SELECT * FROM productos)
NOTICE: ALTER TABLE productos_winpure ADD COLUMN orden_winpure SERIAL NOT NULL
NOTICE: CREATE TABLE duplicados AS (SELECT (NULL)::integer AS group_duplicate, orden_winpure, articulo, autor, clasif, u_fech_mov, fech_ped, codigo FROM productos_winpure LIMIT 0)
NOTICE:
SELECT DISTINCT ON(a.articulo, a.autor, a.clasif, a.u_fech_mov, a.fech_ped, a.codigo)
a.articulo, a.autor, a.clasif, a.u_fech_mov, a.fech_ped, a.codigo
FROM productos_winpure a, productos_winpure b
WHERE
(CASE WHEN (quita_caracter(a.articulo, ' ') IS NULL) OR (quita_caracter(b.articulo, ' ') IS NULL) THEN (1=1)::boolean ELSE (UPPER(quita_caracter(a.articulo, ' '))=UPPER(quita_caracter(b.articulo, ' ')))::boolean END)::boolean
AND (CASE WHEN (quita_caracter(a.autor, ' ') IS NULL) OR (quita_caracter(b.autor, ' ') IS NULL) THEN (1=1)::boolean ELSE (UPPER(quita_caracter(a.autor, ' '))=UPPER(quita_caracter(b.autor, ' ')))::boolean END)::boolean
AND (CASE WHEN (quita_caracter(a.clasif, ' ') IS NULL) OR (quita_caracter(b.clasif, ' ') IS NULL) THEN (1=1)::boolean ELSE (UPPER(quita_caracter(a.clasif, ' '))=UPPER(quita_caracter(b.clasif, ' ')))::boolean END)::boolean
AND (CASE WHEN (quita_caracter(a.u_fech_mov, ' ') IS NULL) OR (quita_caracter(b.u_fech_mov, ' ') IS NULL) THEN (1=1)::boolean ELSE (UPPER(quita_caracter(a.u_fech_mov, ' '))=UPPER(quita_caracter(b.u_fech_mov, ' ')))::boolean END)::boolean
AND (CASE WHEN (quita_caracter(a.fech_ped, ' ') IS NULL) OR (quita_caracter(b.fech_ped, ' ') IS NULL) THEN (1=1)::boolean ELSE (UPPER(quita_caracter(a.fech_ped, ' '))=UPPER(quita_caracter(b.fech_ped, ' ')))::boolean END)::boolean
AND (CASE WHEN (quita_caracter(a.codigo, ' ') IS NULL) OR (quita_caracter(b.codigo, ' ') IS NULL) THEN (1=1)::boolean ELSE (UPPER(quita_caracter(a.codigo, ' '))=UPPER(quita_caracter(b.codigo, ' ')))::boolean END)::boolean
ORDER BY a.articulo, a.autor, a.clasif, a.u_fech_mov, a.fech_ped, a.codigo
Las cuales se ejecutan de forma correcta pero esta consulta:
NOTICE:
SELECT DISTINCT ON(a.orden_winpure, a.articulo, a.autor, a.clasif, a.u_fech_mov, a.fech_ped, a.codigo)
a.orden_winpure, a.articulo, a.autor, a.clasif, a.u_fech_mov, a.fech_ped, a.codigo
FROM productos_winpure a
WHERE
a.articulo::varchar=$$lista.articulo$$::varchar
AND a.autor::varchar=$$lista.autor$$::varchar
AND a.clasif::varchar=$$lista.clasif$$::varchar
AND a.u_fech_mov::varchar=$$lista.u_fech_mov$$::varchar
AND a.fech_ped::varchar=$$lista.fech_ped$$::varchar
AND a.codigo::varchar=$$lista.codigo$$::varchar
ORDER BY a.orden_winpure, a.articulo, a.autor, a.clasif, a.u_fech_mov, a.fech_ped, a.codigo
Cómo verán depende de un elemento "lista" obtenido de este "for":
FOR lista IN EXECUTE consulta LOOP
cont:=cont+1;
consulta_1:=('\nSELECT DISTINCT ON(a.orden_winpure, ' || columnas || ') \n a.orden_winpure, ' || columnas || '\nFROM ' || new_table || ' a\nWHERE\n' || condiciones || '\nORDER BY a.orden_winpure, ' || columnas || '\n');
RAISE NOTICE '%', consulta_1;
FOR lista_aux1 IN EXECUTE consulta_1 LOOP
RAISE NOTICE 'En segunda consulta';
-- EXECUTE 'INSERT INTO duplicados (SELECT ' || cont || ', lista_aux1.* || ' FROM ' || new_table || ')';
END LOOP;
END LOOP;
Más sin embargo al ejecutar la consulta en el segundo "for", los valores son pasados como cadena y no como una referencia en los elementos tales como "lista.articulo" que es lo que desearía.
Poniendo la consulta de forma directa como:
consulta_1:=
'
SELECT DISTINCT ON(a.orden_winpure, a.articulo, a.autor, a.clasif, a.u_fech_mov, a.fech_ped, a.codigo)
a.orden_winpure, a.articulo, a.autor, a.clasif, a.u_fech_mov, a.fech_ped, a.codigo
FROM productos_winpure a
WHERE
a.articulo::varchar=\$\$' || lista.articulo || '\$\$::varchar
AND a.autor::varchar=\'' || lista.autor || '\'::varchar
AND a.clasif::varchar=\'' || lista.clasif || '\'::varchar
AND a.u_fech_mov::varchar=\'' || lista.u_fech_mov || '\'::varchar
AND a.fech_ped::varchar=\'' || lista.fech_ped || '\'::varchar
AND a.codigo::varchar=\'' || lista.codigo || '\'::varchar
ORDER BY a.orden_winpure, a.articulo, a.autor, a.clasif, a.u_fech_mov, a.fech_ped, a.codigo
';
Funciona bien, más sin embargo aun haciendo el código necesario para que me construya esta instrucción tal cual, me arroja un error o me toma la variable "linea.xx" de forma textual y no como referencia.
Cómo podría hacer para construir una consulta dentro de un varchar que pueda ejecutar con el comando EXECUTE y la cual haga referencia a los elementos de una variable perteneciente a un "for" superior, tal cual se presenta en los "for" aninados que les muestro arriba?
Alguna sugerencia?
_________________________________________________________________
Herramientas para combatir la crisis. MSN Dinero
http://dinero.es.msn.com/--
TIP 5: ¿Has leído nuestro extenso FAQ?
http://www.postgresql.org/docs/faqs.FAQ.html
No comments:
Post a Comment