为啥我得到的准确提取返回超过请求的行数
Posted
技术标签:
【中文标题】为啥我得到的准确提取返回超过请求的行数【英文标题】:why am I getting exact fetch returns more than requested number of rows为什么我得到的准确提取返回超过请求的行数 【发布时间】:2015-12-11 20:17:02 【问题描述】:这是获得对某项最高出价的userID
的过程。如果在maxPrice
上出现平局,那么获胜者将成为最先出价的人,给出该项目的itemID
和currentPrice
(中标)。
create or replace FUNCTION GARAGESALE_getWinner(id1 int, currentPrice int) Return varchar2 RESULT_CACHE
AS
uname varchar2(30) := 'none';
Begin
SELECT C1.username into uname
FROM GARAGESALE_BID B, GARAGESALE_Customer C1
WHERE B.maxPrice >= currentPrice
and C1.userID = B.UserID
and B.itemID = id1
and not exists (select *
from GARAGESALE_BID B2
where B2.bdate < B.bdate
and B.maxprice = B2.maxprice
and B2.itemID = B.itemID);
return uname;
End;
这是错误信息:
连接到数据库 Team 3. ORA-01422: 精确提取返回的行数多于请求的行数 ORA-06512:在“TEAM3.GARAGESALE_GETWINNER”,第 7 行 ORA-06512:在第 9 行 进程已退出。 与数据库 Team 3 断开连接。
【问题讨论】:
对于给定的UserID
值,您是否可能在GARAGESALE_Customer
中有多个记录?
只需运行不带 SQL*Plus(或 TOAD 或其他)中的 INTO
子句的查询,无论 id1
和 currentPrice
的值都失败,看看多行是什么。
刚试了一下,它返回了我希望它返回的一行。
【参考方案1】:
摆脱相关的子查询将减少您需要的表扫描次数:
CREATE FUNCTION GARAGESALE_getWinner(
i_itemID IN GARAGESALE_BID.ITEMID%TYPE,
i_currentPrice IN GARAGESALE_BID.MAXPRICE%TYPE
) RETURN GARAGESALE_CUSTOMER.USERNAME%TYPE RESULT_CACHE
AS
uname GARAGESALE_CUSTOMER.USERNAME%TYPE;
BEGIN
SELECT username
INTO uname
FROM (
SELECT C.username
FROM GARAGESALE_BID b
INNER JOIN GARAGESALE_CUSTOMER c
ON ( b.userID = c.userID )
WHERE b.maxPrice >= i_currentPrice
AND b.itemID = i_itemID
ORDER BY
b.maxPrice DESC,
b.BDATE DESC,
b.userID ASC
)
WHERE ROWNUM = 1;
RETURN uname;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN 'none'; -- Really? Why not NULL?
END GARAGESALE_getWinner;
/
SHOW ERRORS;
不清楚如果两个用户同时提交了相同的maxPrice
,那么抢七是什么 - 我选择了最早的userID
作为非随机的打破平局的方法。
【讨论】:
【参考方案2】:此错误表示您选择返回多于 1 行。
要使用“into”关键字,您必须确保只获得 1 行结果。
可以通过将'rownum'添加到约束来完成。
SELECT C1.username into uname
from GARAGESALE_BID B, GARAGESALE_Customer C1
WHERE rownum < 2 and
B.maxPrice >= currentPrice and C1.userID = B.UserID and B.itemID = id1 and not exists (select *
From GARAGESALE_BID B2
where B2.bdate < B.bdate and B.maxprice = B2.maxprice and B2.itemID = B.itemID)
这将确保您的选择仅返回 1 行。
如果您需要超过 1 行来返回,请尝试使用循环或游标。
【讨论】:
投反对票,因为那是创可贴。如果您希望获得 1 行并获得 2 行,则意味着您有错误。随机选择其中一个只是为了让您的代码“工作”不是答案。 @MatthewMcPeak 我们不知道确切的要求,也许选择随机行是可以的。无论如何我的答案 - 取决于。以上是关于为啥我得到的准确提取返回超过请求的行数的主要内容,如果未能解决你的问题,请参考以下文章
尝试从两列中提取多条记录时,精确提取返回的行数超过了请求的行数
PL/SQL ORA-01422:精确提取返回的行数超过了请求的行数