创建ORA-01422的原因:精确提取返回的请求行数超过了请求的行数

Jam*_*213 1 c# oracle plsql oracle10g ora-01422

所以我正在开发一个安装程序,安装程序连接到数据库并创建表并填充它们.除非我尝试将行添加到certian表中,否则此方法的每个方面都能正常工作.

declare
  retVal INTEGER;
  rptID INTEGER;
  catID INTEGER;
  wsID INTEGER;
  paramID INTEGER;
  dtID INTEGER;
begin

  select PK into catID from RPT_CATEGORY where KEYVALUE = 'ProductivityReportsCategory';
  select PK into rptID from RPT_REPORT where KEYVALUE = 'ProductivitySummaryReport2';
  select PK into wsID from RPT_WEBSVC where KEYVALUE = 'NotApplicable' and category_fk = catID;
Run Code Online (Sandbox Code Playgroud)

填充数据库的select语句如下所示:

  select PK into wsID from RPT_WEBSVC where KEYVALUE = 'GetMachineNameList' and category_fk = catID;
  paramID := RPT_CONFIGURATION.ADD_PARAMETER( rptID, wsID, dtID, 'Machine', 'parameters.GetProductivityDataSet3.inserterid', 4, NULL, NULL, NULL, 0, 0, 0, 'Y', 'Y', 'N', 'N', 'Y' );
Run Code Online (Sandbox Code Playgroud)

还有13个这样的select语句(我不会添加它们,因为它们都是相似的,唯一的区别是存储在表中的值.)

我的问题是,当我运行安装程序时,我在完成后在日志中收到此错误:

ORA-01422: exact fetch returns more than requested number of rows 
ORA-06512: at line 30
Run Code Online (Sandbox Code Playgroud)

我想知道的是这个错误发生的原因究竟是什么,以及修复此错误的方法是什么?

我对这个主题做了一些研究,发现这是我搜索的常见主题:

1.代码中有一个错误,开发人员没有意识到你可以返回多行;

2.数据已被黑客攻击而不是使用API​​,因此验证已被破坏;

3.软件没问题,用户做了什么就行,但是同时发生了两次并行更新,两者都没有看到另一个未提交的更改 - 因此没有正确验证.

我很肯定它不是#2,但我不太明白其他两个原因是什么意思,或者如何修复它们.

非常感谢任何帮助或建议.

谢谢

Ton*_*ews 6

ORA-01422:精确提取返回超过请求的行数

只要执行SELECT INTO语句并找到多行,就会引发此异常.SELECT INTO语句期望只找到一行,不多或少 - 否则会引发异常.

在你的例子中:

select PK into wsID from RPT_WEBSVC
where KEYVALUE = 'GetMachineNameList'
and category_fk = catID;
Run Code Online (Sandbox Code Playgroud)

看起来每个(KEYVALUE,CATEGORY_FK)组合应该只有一行,但实际情况并非如此.如果只有一个,则表应该对这些列具有唯一约束:

alter table RPT_WEBSVC add constraint RPT_WEBSVC_UK
    unique (KEYVALUE, CATEGORY_FK);
Run Code Online (Sandbox Code Playgroud)

这会阻止某人(或某个进程)再次添加同一行.当然,在添加该约束之前,您需要对表进行重复数据删除.