批量插入记录时未找到数据或发生行数过多异常错误 [英] No data found or too many rows exception error occured during bulk record insertion

查看:51
本文介绍了批量插入记录时未找到数据或发生行数过多异常错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个 pl/sql 进程来插入从 select 语句获取的批量记录之后首先开始,但我会引发错误并且不插入任何记录帮助我修复错误插入如何插入从 select 语句返回的 11 个 gr_numbers/rows它显示未找到数据获取的行数更多异常发生.图片已附加.在此处输入图片描述在此处输入图片描述

I have Write a pl/sql process to insert bulk record which is getting from select statement after first begin but i will raised error and not insert any record help me to fix the error during insertion How to Insert my 11 gr_numbers/rows which is returned from select statement It Shows No Data found or More then rows fetched exceptions occour. Image has attached. enter image description here enter image description here

DECLARE
    vtm   NUMBER;
    tab   apex_application_global.vc_arr2;
BEGIN
    tab := apex_util.string_to_table(vtm);
    SELECT
        s.gr_number
    INTO vtm
    FROM
        student      s
        LEFT JOIN class_time   ct ON ct.class_id = s.class_id
                                   AND instr(s.class_time, ct.class_time) > 0
    WHERE
        upper(TRIM(ct.class_id)) = upper(TRIM(:app_user))
        AND s.gr_number IS NOT NULL
        AND is_active_flg = 'Y'
        AND gr_number = vtm;

    --dbms_output.put_line(vtm); 
    --for i in 1..tab.count loop

    FOR i IN 1..tab.count LOOP INSERT INTO student_class_attend (
        gr_number,
        student_id,
        period_next_day_flg,
        attend_date,
        period_start_dt,
        period_end_dt,
        period_duration,
        course_name,
        class_time,
        branch_id,
        shift_id,
        teacher_id,
        class_id,
        marked_by,
        course_id,
        class_uid
    )
        SELECT
            gr_number,
            student_id,
            next_day_flg,
            to_date(upper(:p7_attend_dt_tmp), 'DD-MON-YYYY'),
            prd_start_tm,
            prd_end_tm,
            prd_diff_minutes,
            course_name,
            class_time,
            branch_id,
            shift_id,
            teacher_id,
            class_id,
            :v_employee_id,
            course_id,
            class_uid
        FROM
            (
                WITH class_start_tm AS (
                    SELECT
                        s.gr_number,
                        s.class_id,
                        s.class_time AS student_class_time_list,
                        ct.class_time,
                        ct.seq,
                        to_date(upper(:p7_attend_dt_tmp)
                                || ' '
                                || ct.class_time, 'DD-MON-YYYY HHMIAM') AS class_first_tm
                    FROM
                        student      s
                        JOIN class_time   ct ON s.class_id = ct.class_id
                    WHERE
                        s.gr_number = :p7_gr_tmp
                        AND ct.seq = 1
                ), tm AS (
                    SELECT
                        s.gr_number,
                        cl.duration_minutes,
                        t.class_first_tm,
                        to_date(upper(:p7_attend_dt_tmp)
                                || ' '
                                || to_char(cl.start_time, 'HHMIAM'), 'DD-MON-YYYY HHMIAM') AS prd_start_tm,
                        to_date(upper(:p7_attend_dt_tmp)
                                || ' '
                                || to_char(cl.start_time, 'HHMIAM'), 'DD-MON-YYYY HHMIAM') + INTERVAL '30' MINUTE AS prd_end_tm,
                        (
                            CASE
                                WHEN to_date(upper(:p7_attend_dt_tmp)
                                             || ' '
                                             || to_char(cl.start_time, 'HHMIAM'), 'DD-MON-YYYY HHMIAM') < t.class_first_tm THEN
                                    'Y'
                                ELSE
                                    'N'
                            END
                        ) next_day_flg
                    FROM
                        calender_24hr    cl
                        JOIN student          s ON instr(s.class_time, cl.time_12hr) > 0
                                          AND s.gr_number = :p7_gr_tmp
                        JOIN class_start_tm   t ON t.gr_number = s.gr_number
                ), tm1 AS (
                    SELECT
                        gr_number,
                        duration_minutes,
--       class_first_tm,
                        (
                            CASE
                                WHEN next_day_flg = 'Y' THEN
                                    prd_start_tm + 1
                                ELSE
                                    prd_start_tm
                            END
                        ) prd_start_tm,
                        (
                            CASE
                                WHEN next_day_flg = 'Y' THEN
                                    prd_end_tm + 1
                                ELSE
                                    prd_end_tm
                            END
                        ) prd_end_tm,
                        next_day_flg
                    FROM
                        tm
                    ORDER BY
                        (
                            CASE
                                WHEN next_day_flg = 'Y' THEN
                                    prd_start_tm + 1
                                ELSE
                                    prd_start_tm
                            END
                        )
                ), tm2 AS (
                    SELECT
                        gr_number,
                        MAX(next_day_flg) AS next_day_flg,
                        MIN(prd_start_tm) AS prd_start_tm,
                        MAX(prd_end_tm) AS prd_end_tm,
                        round((MAX(prd_end_tm) - MIN(prd_start_tm)) * 24 * 60, 0) AS prd_diff_minutes,
                        SUM(duration_minutes) actual_minutes,
                        round((MAX(prd_end_tm) - MIN(prd_start_tm)) * 24 * 60, 0) - SUM(duration_minutes) AS gap_minutes
                    FROM
                        tm1
                    GROUP BY
                        gr_number
                )
                SELECT
                    st.gr_number,
                    st.student_id,
                    tm.next_day_flg,
                    prd_start_tm,
                    prd_end_tm,
                    tm.prd_diff_minutes,
                    tm.actual_minutes,
                    tm.gap_minutes,
                    st.course AS course_id,
                    cr.course_name,
                    cl.class_uid,
                    st.class_id,
                    st.class_time,
                    st.branch_id,
                    st.shift_id,
                    cl.teacher_id
                FROM
                    tm2       tm
                    JOIN student   st ON tm.gr_number = st.gr_number
                    LEFT JOIN course    cr ON cr.course_id = st.course
                    LEFT JOIN class     cl ON cl.class_id = st.class_id
            );

    END LOOP;

--exception 
--when too_many_rows then

EXCEPTION
    WHEN no_data_found THEN
        SELECT
            s.gr_number
        INTO vtm
        FROM
            student      s
            LEFT JOIN class_time   ct ON ct.class_id = s.class_id
                                       AND instr(s.class_time, ct.class_time) > 0
        WHERE
            upper(TRIM(ct.class_id)) = upper(TRIM(:app_user))
            AND s.gr_number IS NOT NULL
            AND is_active_flg = 'Y'
            AND gr_number = vtm;

        dbms_output.put_line('Error, rows = ' || vtm);
        end;
END loop;

COMMIT;

end;

推荐答案

no_data_found 实际上被引发了两次.在初始选择期间的第一次(begin 之后的第二条语句).第二次由异常过程处理第一次出现.发生这种情况是因为您的异常处理程序尝试完全相同的查询.因此完全相同的结果.
那么为什么第一次提出 no_data_found .您将局部变量 vtm 定义为数字,但未初始化该值.这使得它的值为 NULL.然后继续在 select 语句的 where 子句中使用 vtm :(AND gr_number = vtm;) 这个谓词只会返回 NULL 从而使整个 where 子句始终为 false,这意味着没有数据满足 where 条件.
更正:嗯,我不知道.您没有提供示例数据或参数值.但是,您必须以某种方式将变量 vtm 初始化为现有的 gr_number(这可能不是唯一的原因)或从查询中删除该变量.然后再次删除它可能是导致太多行"异常的原因.
如果是这种情况,那么您需要将select ... into ..."和从处理集合到处理游标的循环转换.

The no_data_found is actually being raised twice. The first time during the initial select (the 2nd statement after begin). The second time by the exception procedure handling the first occurrence. This occurs because your exception handler attempts the exact same query. Thus the exact same result.
So why is the no_data_found raised the first time. You define the local variable vtm as number, but you do not initialize the value. This makes its value NULL. You then go on to use vtm in the where clause of the select statement :(AND gr_number = vtm;) This predicate will only return NULL thus making the entire where clause always false, which means no data satisfies the where condition.
Correction: Well I don't know. You didn't provide sample data nor parameter values. However, somehow you must initialize the variable vtm to an existing gr_number (that may NOT be the only cause) or remove the variable from the query. Then again perhaps removing it is what caused your "too many rows" exception.
If that is the case then you need to convert "select ... into ..." and and the loop from processing a collection to processing the cursor.

declare
    gr_cursor cursor is 
       ( select s.gr_number
           from student      s
           left join class_time   ct 
                  on ct.class_id = s.class_id
                 and instr(s.class_time, ct.class_time) > 0
          where upper(trim(ct.class_id)) = upper(trim(:app_user))
            and s.gr_number is not null
            and is_active_flg = 'Y'
            and gr_number = vtm 
       ); 

begin
    for grc in gr_cursor
    loop 
      insert into student_class_attend (
        ... ;
    end loop;

    commit; 
end;

免责声明:我没有验证变量 vtm、tab 不在插入的扩展中,也没有尝试在该扩展中进行其他更改(如果有).但很可能有一些需要.

Disclaimer: I did NOT verify the variables vtm, tab are not in the expansion for the insert, nor attempt other changes, if any, within that expansion. But there may very well be some needed.

这篇关于批量插入记录时未找到数据或发生行数过多异常错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆