PL/SQL存储过程统计同日期销售行数报exact fetch多行错误
报错根因
PL/SQL中使用SELECT ... INTO语句向标量变量赋值时,强制要求查询结果必须恰好返回1行:
- 返回0行触发
ORA-01403: no data found错误 - 返回超过1行就会触发你遇到的
ORA-01422: exact fetch returns more than requested number of rows错误
你的代码里第二个统计查询用了COUNT(1)聚合,永远只会返回1行,不可能触发该错误。问题出在第一个查询:传入c_order_id=1267的条件下,sales表中匹配该order_id的记录数大于1,因此直接抛出错误,不会执行后续的打印、同日期销量统计逻辑。
修复方案
根据实际业务场景选择对应处理方式:
- 如果业务规则定义1个order_id仅对应1条销售记录:先排查
sales表测试数据,清理order_id重复的脏数据即可。 - 如果业务规则允许1个订单对应多条销售明细:你当前用单个标量变量接收多行列值的写法本身逻辑不成立,可按需求选择以下改法:
- 仅需要取该订单任意一条记录的销售日期做后续统计:给查询加行数限制,仅返回1行即可,Oracle 12c及以上版本可直接用
FETCH FIRST语法,低版本可加ROWNUM=1条件:
- 仅需要取该订单任意一条记录的销售日期做后续统计:给查询加行数限制,仅返回1行即可,Oracle 12c及以上版本可直接用
-- 12c及以上版本改法 SELECT sales_date,product_id,customer_id,salesperson_id,quantity,unit_price,sales_amount,tax_amount,total_amount INTO c_sales_date,c_product_id,c_customer_id,c_salesperson_id,c_quantity,c_unit_price,c_sales_amount,c_tax_amount,c_total_amount FROM sales WHERE order_id = c_order_id FETCH FIRST 1 ROW ONLY;
-- 低版本兼容改法 SELECT sales_date,product_id,customer_id,salesperson_id,quantity,unit_price,sales_amount,tax_amount,total_amount INTO c_sales_date,c_product_id,c_customer_id,c_salesperson_id,c_quantity,c_unit_price,c_sales_amount,c_tax_amount,c_total_amount FROM sales WHERE order_id = c_order_id AND ROWNUM = 1;
- 需要遍历该订单下所有销售明细:不能用单个标量变量接收结果,需要改用游标、PL/SQL集合类型处理多结果集。
额外避坑提示:建议给存储过程入参、局部变量加专属前缀区分,比如入参加
p_前缀、局部变量加l_前缀,避免变量名和表字段重名时,Oracle优先识别表字段导致WHERE条件恒成立(比如变量名和字段名都叫order_id时,WHERE order_id = order_id等价于无条件查询全表,必然返回多行触发报错)。
内容的提问来源于stack exchange,提问作者Cc Max
相关产品推荐
相关产品推荐

