ORA-01422的解决方案:精确获取返回的行数超过了请求的行数

问题描述 投票:1回答:1

我被要求在Oracle中为以下查询创建一个存储过程,该查询将在where子句中将输入参数作为@FID来给我结果。

它由4列组成,对于每个不同的输入,结果通常为100行以上。初始查询如下-

SELECT 
    TJV.FID, TD.F_CLASS_NAME,  
    CASE 
       WHEN TJV.job_operation_id = 1 THEN 'INSERT' 
       WHEN TJV.JOB_OPERATION_ID = 2 THEN 'UPDATE' 
       WHEN TJV.job_operation_id = 3 THEN 'DELETE' 
    END AS JOB_OPERATION_TYPE, 
    TJV.OPERATION_DATE 
FROM 
    TB_JOB_VERSION TJV, 
    TB_DICTIONARY TD, TB_UFID TU 
WHERE 
    TJV.JOB_ID = @FID 
    AND TU.FID = TJV.FID 
    AND TU.F_CLASS_ID = TD.F_CLASS_ID;

然后我在下面做了这样的过程,但是它抛出了以下错误消息-

ORA-01422:精确提取返回的行数超过了请求的行数ORA-06512:在TCGM3D.JOB_EXPLORER,第8行,ORA-06512:在第6行

代码:

CREATE OR REPLACE PROCEDURE job_explorer (
    j_fid IN INT
) AS
    v_fid                  NUMBER;
    v_f_class_name         VARCHAR2(30);
    v_job_operation_type   VARCHAR(100);
    v_operation_date       DATE;
BEGIN
    SELECT
        tjv.fid,
        td.f_class_name,
        CASE
            WHEN tjv.job_operation_id = 1 THEN
                'INSERT'
            WHEN tjv.job_operation_id = 2 THEN
                'UPDATE'
            WHEN tjv.job_operation_id = 3 THEN
                'DELETE'
        END AS job_operation_type,
        tjv.operation_date
    INTO
        v_fid,
        v_f_class_name,
        v_job_operation_type,
        v_operation_date
    FROM
        tcgm3d.tb_job_version   tjv,
        tcgm3d.tb_dictionary    td,
        tcgm3d.tb_ufid          tu
    WHERE
        tjv.job_id = j_fid
        AND tu.fid = tjv.fid
        AND tu.f_class_id = td.f_class_id;

    dbms_output.put_line('FID'
                         || v_fid
                         || 'F_CLASS_NAME'
                         || v_f_class_name
                         || 'JOB_OPERATION_TYPE'
                         || v_job_operation_type
                         || 'OPERATION_DATE'
                         || v_operation_date);

END job_explorer;

我再次尝试使用循环修改查询,但结果不是表格形式,它只是在查询输出窗口中这样显示出来-

"FID85225493
F_CLASS_NAMESCE_EL_TRN_POLE_TBL
JOB_OPERATION_TYPEUPDATE
OPERATION_DATE04-JAN-17
FID251101047
F_CLASS_NAMESCE_EL_SEG_SECTION
JOB_OPERATION_TYPEINSERT
OPERATION_DATE04-JAN-17
FID251101038
F_CLASS_NAMEEL_CONNECTOR
JOB_OPERATION_TYPEINSERT
OPERATION_DATE04-JAN-17
FID251100923
F_CLASS_NAMEEL_PAD
JOB_OPERATION_TYPEINSERT
OPERATION_DATE04-JAN-17"

我对此的最终查询是在下面-

CREATE OR REPLACE PROCEDURE job_explorer (
    j_fid IN INT
) AS
BEGIN
    FOR rec IN (
        SELECT
            tjv.fid,
            td.f_class_name,
            CASE
                WHEN tjv.job_operation_id = 1 THEN
                    'INSERT'
                WHEN tjv.job_operation_id = 2 THEN
                    'UPDATE'
                WHEN tjv.job_operation_id = 3 THEN
                    'DELETE'
            END AS job_operation_type,
            tjv.operation_date
        FROM
            tcgm3d.tb_job_version   tjv,
            tcgm3d.tb_dictionary    td,
            tcgm3d.tb_ufid          tu
        WHERE
            tjv.job_id = j_fid
            AND tu.fid = tjv.fid
            AND tu.f_class_id = td.f_class_id
    ) LOOP
        dbms_output.put_line('FID' || rec.fid);
        dbms_output.put_line('F_CLASS_NAME' || rec.f_class_name);
        dbms_output.put_line('JOB_OPERATION_TYPE' || rec.job_operation_type);
        dbms_output.put_line('OPERATION_DATE' || rec.operation_date);
    END LOOP;
END job_explorer;

[如果有人可以帮助我以表格格式获取每一行的数据,这将很有帮助,然后我必须在ado.net的数据表中进行查询。

oracle plsql oracle11g ado.net oracle-sqldeveloper
1个回答
0
投票

通过此操作,您可以得到表格形式的答案,并使用管道作为分隔符:

CREATE OR REPLACE PROCEDURE job_explorer(j_fid IN INT)
AS
BEGIN
  /* header */
  dbms_output.put_line(       rpad('FID',12)
                       ||'|'||rpad('F_CLASS_NAME',30)
                       ||'|'||rpad('JOB_OPERATION_TYPE',18)
                       ||'|'||rpad('OPERATION_DATE',19)
                       );
  --
  /*data*/
  FOR rec IN (SELECT tjv.fid,
                     td.f_class_name,
                     CASE
                         WHEN tjv.job_operation_id = 1 THEN
                             'INSERT'
                         WHEN tjv.job_operation_id = 2 THEN
                             'UPDATE'
                         WHEN tjv.job_operation_id = 3 THEN
                             'DELETE'
                     END AS job_operation_type,
                     tjv.operation_date
              FROM tcgm3d.tb_job_version   tjv,
                   tcgm3d.tb_dictionary    td,
                   tcgm3d.tb_ufid          tu
              WHERE tjv.job_id = j_fid
               AND tu.fid = tjv.fid
               AND tu.f_class_id = td.f_class_id
              ) LOOP
       --
      dbms_output.put_line(       lpad(rec.fid,12)
                           ||'|'||rpad(rec.f_class_name,30)
                           ||'|'||rpad(rec.job_operation_type,18)
                           ||'|'||to_char(rec.operation_date,'dd-MON-yy')
                          );
  END LOOP;
END job_explorer;

输出将是:

FID      |F_CLASS_NAME                  |JOB_OPERATION_TYPE|OPERATION_DATE
 85225493|SCE_EL_TRN_POLE_TBL           |UPDATE            |04-JAN-17
251101047|SCE_EL_SEG_SECTION            |INSERT            |04-JAN-17
251101038|EL_CONNECTOR                  |INSERT            |04-JAN-17
251100923|EL_PAD                        |INSERT            |04-JAN-17
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.