为什么我得到的确切提取返回超过请求的行数

时间:2015-12-11 20:17:02

标签: sql oracle stored-procedures

这是获取对某个项目出价最高的userID的过程。如果maxPrice出现平局,那么获胜者将根据该项目的itemIDcurrentPrice(中标)首先参与竞价。

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行   流程退出。
  断开与数据库团队3的连接。

2 个答案:

答案 0 :(得分:0)

删除相关的子查询将减少所需的表扫描次数:

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作为打破关系的非随机方法。

答案 1 :(得分:-1)

此错误表示您选择返回的行数超过1行。

使用&#39;进入&#39;关键字你必须确保你只得到一行。

可以通过添加&#39; rownum&#39;约束。

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行返回,请尝试使用循环或光标。