es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

PostgreSQL: ¿Cómo se establece una variable “contador” como índice de un arreglo en una declaración de bucle while?

Estoy tratando de implementar un bucle while que creará nuevas filas de tabla para cada elemento en un array.

En el código siguiente, prc_knw es una expresión introducida por el usuario que está estructurada como un array. Quiero tomar cada uno de los elementos en prc_knw y separarlos en nuevas filas de mi tabla processknowledgeentry, donde cada fila tiene el mismo prc_id tomado de otra tabla. Cada vez que el bucle se repite, quiero pasar al siguiente elemento del array prc_knw, y quiero que la variable counter indique el índice.

do $$

declare 
    counter integer := 1;
begin
    while counter <= (select array_length(prc_knw,1))  loop                            
        INSERT INTO processknowledgeentry (prc_id,knw_id, pke_delete_ind)
        VALUES ((SELECT prc_id FROM process
        WHERE prc_id = (SELECT MAX(p.prc_id) FROM process AS p)),prc_knw[counter], False);
        counter := counter + 1;
    end loop;
end$$;

Estoy atascado en cómo formatear prc_knw[counter]. El error que obtengo es: SyntaxError: error de sintaxis en o cerca de "[" LÍNEA 14: ...ECT MAX(p.prc_id) FROM process AS p)),ARRAY[1,2,3][counter],...

He intentado darle formato como prc_knw['%',counter], y el error que recibo es: IndexError: índice de lista fuera de rango (porque estoy construyendo esta aplicación en Python Dash y está conectada a una base de datos en pgAdmin 4).

Espero que puedas ayudarme, ¡gracias! También siéntete libre de decirme si hay un enfoque mejor para esto.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para formatear correctamente el elemento del array prc_knw, puedes utilizar la siguiente sintaxis:

    prc_knw[counter:counter+1][1]

    Esto cortará el array desde el índice counter hasta counter+1, y luego seleccionará el segundo elemento del subarray resultante, que es el elemento real que deseas insertar en la tabla.

    Por lo tanto, tu código debería verse así:

    do $$
    
    declare 
        counter integer := 1;
    begin
        while counter <= (select array_length(prc_knw,1))  loop                            
            INSERT INTO processknowledgeentry (prc_id,knw_id, pke_delete_ind)
            VALUES ((SELECT prc_id FROM process
            WHERE prc_id = (SELECT MAX(p.prc_id) FROM process AS p)),prc_knw[counter:counter+1][1], False);
            counter := counter + 1;
        end loop;
    end$$;
    

    En cuanto a un enfoque mejorado, puedes considerar el uso de la función unnest() para convertir el array en un conjunto de filas, y luego unirlo con la tabla process para insertar los valores.

    INSERT INTO processknowledgeentry (prc_id, knw_id, pke_delete_ind)
    SELECT p.prc_id, unnest(prc_knw), false
    FROM process p;
    

    Esto insertará una fila por cada elemento en el array prc_knw, con el correspondiente prc_id de la tabla process. Este enfoque puede ser más eficiente que usar un bucle.

Comments are closed.