今天开发的同事反馈一个问题,该程序已经使用一段时间,在查询昨天的数据时突然报出了错误:
图1 ORA-01427:single-row subquery returns more than one row
异常为:单行子查询返回多行
我得到了该查询页面对应的sql语句:
SELECT ID,(SELECT NAME FROM TABLE01 WHERE TID = t.id ) NAME FROM TABLE02 t WHERE TYPE = '1'
从sql语句能够猜出来错误应该是从子查询里返回的。
按照ORA-01427的错误,应该是子查询(SELECT NAME FROM TABLE01 WHERE TID = t.ID ) 返回了多行值。
验证一下,首先根据type='1'能够得到下面的查询结果
SQL>SELECT ID FROM TABLE02 t WHERE TYPE = '1'
ID
--------------------------------------------------
1
2
3
取出任意一条,然后按照两个表的关联字段值查询,可以看到输出大于一行数据。
SQL> SELECT NAME FROM TABLE01 WHERE TID = '3'
NAME
--------------------------------------------------------------------------------
3_NAME_01
3_NAME_02
3_NAME_03
所以这种情况的解决方案有几种:
* 这种方式可以输出结果而不会报错,存在冗余数据。
SELECT ID,NAME FROM TABLE01,TABLE02 t WHERE TID = t.id AND TYPE = '1'
* 另一种思路是在子查询中进行重复值的过滤,使用group by来完成。
SELECT ID,(SELECT NAME FROM TABLE01 WHERE TID = t.id GROUP BY NAME ) NAME FROM TABLE02 t WHERE TYPE = '1'
* 如果对这个问题进一步优化,可以在确认这个表结构的基础上,看看能够添加相应的约束,这样也能够保证表中的数据不会存在冗余,避免后续出现此类的问题。
* 与开发同事简单沟通,这个表中还是存在部分的脏数据,删除冗余的数据,问题就解决了,这种方案不用修改代码。
希望对你有帮助,祝你有一个好心情,加油!