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

Oracle ORA-01422需要解决方案:精确获取返回的行数超过请求的行数,oracle,plsql,oracle11g,ado.net,oracle-sqldeveloper,Oracle,Plsql,Oracle11g,Ado.net,Oracle Sqldeveloper,我被要求在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'

我被要求在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;
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;
然后我做了一个如下的过程,但是它抛出了下面的错误消息-

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

代码:

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

"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"
我最后的疑问如下-

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;
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的datatable中查询这些行。

这样,您就可以以表格形式获得答案,并以管道作为分隔符:

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

使用此选项,您将以表格形式获得答案,并以管道作为分隔符:

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

只需将dbms_output.put_行更改为一个调用并连接所有字段。另请参阅Microsoft文档,了解如何使用Oracle ref游标填充数据集。光标(rec)中的数据是表格,而不是表格。对dbms_output.put_line的每次调用产生一行输出。您可以连接每个字段(在字段之间使用合适的分隔符),或者将dbms_output.put_行更改为dbms_output.put(在两个字段之间使用合适的分隔符)然后添加dbms_output.new_line。@Belayer--我的主要问题是我需要使用此存储过程通过ado dot net数据集/数据表获取数据,我想再次将其绑定到网格视图,但使用此方法,数据表仅为空-旧样式的逗号分隔表列表样式已替换为中正确的ANSI
JOIN
语法ANSI-92 SQL标准(25年前)及其使用不鼓励调整dbms_output.put_行到一个调用并连接所有字段。另请参阅Microsoft文档,了解如何使用Oracle ref游标填充数据集。光标(rec)中的数据是表格,而不是表格。对dbms_output.put_line的每次调用产生一行输出。您可以连接每个字段(在字段之间使用合适的分隔符),或者将dbms_output.put_行更改为dbms_output.put(在两个字段之间使用合适的分隔符)然后添加dbms_output.new_line。@Belayer--我的主要问题是我需要使用此存储过程通过ado dot net数据集/数据表获取数据,我想再次将其绑定到网格视图,但使用此方法,数据表仅为空-旧样式的逗号分隔表列表样式已替换为中正确的ANSI
JOIN
语法ANSI-92 SQL标准(25年前)不鼓励使用它我的主要问题是我需要使用这个存储过程通过ado.net数据集/数据表来获取数据,我想再次绑定到网格视图,但有了这个数据表就是空的。你可以使用一个输出参数来获取这个输出。我的主要问题是我需要使用这个存储过程通过ado.net获取数据我想再次绑定到网格视图的dataset/data表,但有了它,datatable就是空的。您可以使用输出参数来获取此输出