Exceptions are not properly logged

I am an accidental postgres DBA and learning things every day. Apologies for my questions if not properly drafted.

I am trying to load data from the temp table to the main table and catch the exceptions inside another table.

temp table is cast with the main table data type and trying to load the data.

temp table is below.

enter image description here

category name is varchar(25) and is_active is boolean in main table. So i should get exceptions for 1st,2nd for category_name rows and 4 and 5th rows for boolean. In exception table results,its only showing

Exception table is below. Here instead of showing exception for value 12 in the is_active table its showing old exception for 15 itself.. Script is attached,,…SQLERRM value is not getting updated for row 12..WHat could be the reason for this?

enter image description here

CREATE OR REPLACE FUNCTION insert_temp_data_to_main_table()
RETURNS VOID AS $$
DECLARE
    v_main_table_name TEXT := 'main_categories';
    v_temp_table_name TEXT := 'tmp_categories';
    v_error_table_name TEXT := 'error_log_table';
    v_sql_statement TEXT;
BEGIN
    -- Clear the error log table
    EXECUTE 'TRUNCATE TABLE ' || v_error_table_name;

    -- Build the complete SQL statement with aggregated columns and select clauses
    v_sql_statement := format('
        INSERT INTO %I (%s)
        SELECT %s
        FROM %I',
        v_main_table_name,
        (SELECT string_agg(column_name, ', ') FROM information_schema.columns WHERE table_name = v_main_table_name),
        (SELECT string_agg('CAST(' || v_temp_table_name || '.' || column_name || ' AS ' || data_type || ')', ', ') FROM information_schema.columns WHERE table_name = v_temp_table_name),
        v_temp_table_name);

    -- Print the SQL statement
    RAISE NOTICE 'Generated SQL statement: %', v_sql_statement;

    -- Insert data into the main table from the temp table
    EXECUTE v_sql_statement;

EXCEPTION
    WHEN others THEN
        DECLARE
            v_error_msg TEXT;
            v_failed_column_name TEXT;
            v_row_counter INT := 1;
        BEGIN
            -- Get the specific error message
            v_error_msg := SQLERRM;

            -- Get the failed column name
            SELECT column_name INTO v_failed_column_name
            FROM information_schema.columns
            WHERE table_name = v_temp_table_name
            ORDER BY ordinal_position
            LIMIT 1 OFFSET v_row_counter - 1;

            -- Log the error into the error log table
            EXECUTE format('
                INSERT INTO %I (error_message, failed_column_name, failed_row_number)
                VALUES ($1, $2, $3)', v_error_table_name)
            USING v_error_msg, v_failed_column_name, v_row_counter;
        END;
END;
$$ LANGUAGE plpgsql;

Leave a Comment