ORA-01422功能简单 - 为什么行太多?

时间:2014-01-15 11:46:00

标签: sql oracle plsql

我有一张桌子

pricehist (product_id INTEGER,
           price FLOAT,
           valid_from DATE,
           valid_until DATE);

列出了特定时间产品的成本/成本。

我希望我的功能可以将差异返回到之前的价格:

CREATE OR REPLACE FUNCTION difference (prod_id IN NUMBER, val_from IN DATE) 
RETURN NUMBER AS 
 p_old NUMBER;
 p_new NUMBER;
BEGIN
 SELECT price INTO p_old FROM pricehist WHERE product_id = prod_id AND valid_until = val_from - 1;
 SELECT price INTO p_new FROM pricehist WHERE product_id = prod_id AND valid_from = val_from;
RETURN (p_new - p_old);
END difference;

我试过

SELECT product_id, price, valid_from, difference(product_id, valid_from) FROM pricehist

但我得到

  

01422.00000 - “确切的提取返回超过请求的行数”
  *原因:精确提取中指定的数字小于返回的行数。
  *操作:重写查询或更改请求的行数

我在这里做错了什么?感谢。

2 个答案:

答案 0 :(得分:0)

ORA-01422的原因是预期有一行结果,并且查询返回了几行。

在您的情况下,它发生是因为您的一个查询返回了几行。您应该重新定义WHERE条件,以确保只返回一行。

另一种方法是仅获取第一个结果,例如,使用ROWNUM <= 1

有了这个,你的查询应该是:

SELECT price INTO p_old
  FROM pricehist 
 WHERE product_id = prod_id 
   AND valid_until = val_from - 1
   AND ROWNUM <=1;

答案 1 :(得分:0)

我想您甚至可以使用此查询完全跳过该功能:

SELECT product_id, price, valid_from, 
    price - LAG(price, 1) OVER (PARTITION BY product_id ORDER BY valid_from) AS difference
FROM pricehist