Oracle ORA-01422需要解决方案:精确获取返回的行数超过请求的行数
我被要求在Oracle中为下面的查询创建一个存储过程,该查询将输入参数作为where子句中的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'
@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数据集/数据表获取数据,我想再次将其绑定到网格视图,但使用此方法,数据表仅为空-旧样式的逗号分隔表列表样式已替换为中正确的ANSIJOIN
语法ANSI-92 SQL标准(25年前)不鼓励使用它我的主要问题是我需要使用这个存储过程通过ado.net数据集/数据表来获取数据,我想再次绑定到网格视图,但有了这个数据表就是空的。你可以使用一个输出参数来获取这个输出。我的主要问题是我需要使用这个存储过程通过ado.net获取数据我想再次绑定到网格视图的dataset/data表,但有了它,datatable就是空的。您可以使用输出参数来获取此输出