ORA-01427:单行子查询返回多个行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORA-01427:单行子查询返回多个行相关的知识,希望对你有一定的参考价值。

select 字段1

into 变量a
from 表A
where 条件

哪有问题啊?

由于查询结果有多行造成,确保查询结果只有一行数据。这样就不会报错了。

【错误例子】

“select a.id,a.case_id,e.case_name,e.case_code,(select enddate from ol_apply_process where id=a.id and result =10) as enddate from ol_apply a,ol_case e”,报错ORA-01427:单行子查询返回多个行。

解决方法:

查询中肯定有返回多行的情况,试着在子查询中加入rownum<2,也就是限制返回一行数据。

更改后的:

“select a.id,a.case_id,e.case_name,e.case_code,(select enddate from ol_apply_process where id=a.id and result =10 and rownum=1) as enddate from ol_apply a,ol_case e”。

参考技术A 这个错误是由于你的查询结果有多行造成的,因为你要into给变量a,所以只能查出一行,应该在where条件处控制,确保查询结果只有一样数据。这样就不会报错了。
如果不能确定记录为一行,可以这样写:select 字段1 into 变量a from 表a where 条件 and rownum = 1;追问

1、rownum=1的作用是什么,我才初学
2、这个是我在存储过程中写的,我where中的条件判断是根据参数中的值写的,那应该就是传进来的唯一的那一条啊,这是为什么呢

追答

1.rownum是oracle的伪列,通常用来做每条记录的序号。由于rownum必须从1开始记录,所以当where条件中写rownum=1时,就只能查到结果集中第一条记录,从而达到只查出一条记录的目的。

2.你的数据为什么不唯一我不清楚,我看不到你的数据,我只能说,出现这个错误,肯定是结果记录数>1你把语句拿到sql窗口查询一下,看看结果,如果是数据问题,删除多余数据就行了。

追问

我上网看有用游标赋值的,具体为下:
declare cur_a cursor is
select(select t.dydj from wgkh_mx_info t where t.dh = dy_rb_Res.Mxbh) from dual;
begin
open cur_A;
FETCH CUR_A into dydj ;
loop
....

end loop;
close cur_a;
....
end

想问下,中间的loop里应该写什么呢?

追答

select(select t.dydj from wgkh_mx_info t where t.dh = dy_rb_Res.Mxbh) from dual
这么写不对的。
不需要嵌套在select ... from dual中。再有语句有问题dy_rb_Res.Mxbh哪里来的啊,游标有没有入参,如果dy_rb_Res不是包范围的变量,这样写会报错的。

再说说loop里些什么。一般就是写要用游标中的每一行数据做什么。比如:赋值给一个结构,或者对某个表做dml操作等等。

想说两句题外话,游标不是为了使用游标而定义的,应该是为了使用数据做操作,才使用游标来查询数据。不要为了使用而使用。

本回答被提问者和网友采纳
参考技术B select 字段1

-- into 变量a
from 表A
where 条件
根据条件 查出来多行 字段1
参考技术C 变量适用于单个值 你where条件里检索出来的值可能是多个 这个时候可以把这些值放到游标里 参考技术D 不能用=号 用 in

ORA-01427: 单行子查询返回多个行

有人问题我一个问题,情况如下:
他要用根据divide_act_channel_day的new_amount字段去更新divide_stat的new_amount字段。
两张表关联的条件:day=log_time,channel=channel


--SQL如下:
update divide_stat
set divide_stat.new_amount=(select divide_act_channel_day.new_amount from divide_act_channel_day
where divide_stat.day=divide_act_channel_day.log_time
and divide_stat.channel=divide_act_channel_day.channel
);


SQL 错误: ORA-01427: 单行子查询返回多个行
01427. 00000 -  "single-row subquery returns more than one row"


--推测子查询中肯定有返回多行的情况,试着在子查询中加入rownum<2,也就是限制返回一行数据。成功!
update divide_stat
set divide_stat.new_amount=(select divide_act_channel_day.new_amount from divide_act_channel_day
where divide_stat.day=divide_act_channel_day.log_time
and divide_stat.channel=divide_act_channel_day.channel and rownum<2);


--找出divide_act_channel_day表重复行。有9行重复。
select * from
(
select count(*) total,log_time,channel  from divide_act_channel_day
group by log_time, channel
)
where total>1;


TOTAL                  LOG_TIME                  CHANNEL                                           
---------------------- ------------------------- --------------------------------------------------
2                      2012-12-12 00:00:00       0                                                 
2                      2012-12-13 00:00:00       0                                                 
2                      2013-01-07 00:00:00       0                                                 
2                      2012-12-15 00:00:00       0                                                 
2                      2012-12-01 00:00:00       0                                                 
2                      2012-12-31 00:00:00       0                                                 
2                      2012-12-04 00:00:00       0                                                 
2                      2012-12-23 00:00:00       0                                                 
2                      2012-12-21 00:00:00       0                                                 

9 所选行


--观察divide_act_channel_day表,发现它根本没有重复行。看来是where条件精度不够造成的行重复。


--观察divide_act_channel_day和divide_stat两张表,发现它们还有可以关联的列:amount和NEW_USER_AMOUNT。
--这样就没有重复行了。
select * from
(
select count(*) total,log_time,channel,amount,NEW_USER_AMOUNT  from divide_act_channel_day
group by log_time, channel, amount, NEW_USER_AMOUNT
)
where total>1;


no rows selected


--修改upadte语句
update divide_stat
set divide_stat.new_amount=(select divide_act_channel_day.new_amount from divide_act_channel_day
where divide_stat.day=divide_act_channel_day.log_time
and divide_stat.channel=divide_act_channel_day.channel and divide_stat.amount=divide_act_channel_day.amount
and  divide_stat.NEW_USER_AMOUNT=divide_act_channel_day.NEW_USER_AMOUNT
);


结论:
1.根据A表的某列去update B表的某列时,一定要找出A B两张表可以关联的所有字段,这样基本上不会出现"ORA-01427: 单行子查询返回多个行";
2.如果A表中真的有重复行,那就加上rownum<2条件解决。

以上是关于ORA-01427:单行子查询返回多个行的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01427:单行子查询返回多行 - 如何修复?

ORA-01427: 单行子查询返回多个行

ORA-01427:单行子查询返回多个行

ORA-01427:单行子查询返回多个行

ORA-01427:单行子查询返回多个行

得到以下错误 ORA-01427: 单行子查询返回多于一行 01427. 00000 - “单行子查询返回多于一行”