PL / SQL:ORA 01422提取返回超过请求的行数

时间:2018-03-10 06:48:57

标签: oracle plsql

我正在开发订单交易,用户可以订购产品。一旦他们点击了“添加到购物车”。按钮,它将能够以相同的订单ID在数据库中保存多少次。订单ID就像交易ID。

我的问题是,无论何时我想显示客户订购的商品,都会显示错误或ORA 01422.如何解决此错误?

这是我的代码

DECLARE 
  order_item_id NUMBER;
BEGIN
  order_item_id := :MOTOR_PRODUCTS_ORDER.M_ORDERID;

  SELECT MOTOR_ID, 
         MOTOR_QTY_PURCHASED, 
         UNITPRICE
   INTO :MOTOR_ORDER_ITEMS.MOTOR_ID, 
        :MOTOR_ORDER_ITEMS.MOTOR_QTY_PURCHASED, 
        :MOTOR_ORDER_ITEMS.UNITPRICE
   FROM MOTOR_ORDERS
  WHERE motor_order_id = order_item_id;

END;

3 个答案:

答案 0 :(得分:0)

正如krokodilo所说,导致此错误的原因是您的查询返回多行。根据您的要求,您有几种选择。

如果你想要多个值,那么要么使用循环并一次处理一行(如果你要执行dml操作,请使用批量收集)。如果您只想要一行,那么使用额外的where子句缩小结果集,或使用MAX确保只返回一个值。

答案 1 :(得分:0)

如果从查询中返回多行,则需要使用游标。一种方法是使用游标FOR循环:

DECLARE 
  order_item_id NUMBER;
BEGIN
  order_item_id := :MOTOR_PRODUCTS_ORDER.M_ORDERID;

  FOR aRow IN (SELECT MOTOR_ID, MOTOR_QTY_PURCHASED, UNITPRICE
                 FROM MOTOR_ORDERS
                 WHERE motor_order_id = order_item_id)
  LOOP
    -- Do something here with the values in 'aRow'. For example, you
    -- might print them out:

    DBMS_OUTPUT.PUT_LINE('MOTOR_ID=' || aRow.MOTOR_ID ||
                         ' MOTOR_QTY_PURCHASED=' || aRow.MOTOR_QTY_PURCHASED ||
                         ' UNITPRICE=' || aRow.UNITPRICE);
  END LOOP;
END;

祝你好运。

答案 2 :(得分:0)

这看起来像一个表单问题;是吗?如果是这样,我的建议是让Forms为您完成这项工作。

根据您发布的内容,有两个块:

  • MOTOR_PRODUCTS_ORDER(主要版块,表单类型)
  • MOTOR_ORDER_ITEMS(详情块,表格类型)

我猜他们之间有一个主 - 细节关系。如果没有,我建议您创建它。虽然你可以让它在没有这种关系的情况下工作,但它会变得更加困难。如果您不确定如何操作,请从头开始:

  • 删除MOTOR_ORDER_ITEMS块(详细信息)
  • 再次创建它,这次是按照数据块向导
  • 创建的
  • 将MOTOR_PRODUCTS_ORDER设置为其主块
  • 关系在ORDER_ID列/项目

让我们假设在这一点上,一切都已建立起来。检索属于该ORDER_ID的项目现在非常简单:

  • 导航至主程序块
  • 进入查询模式
  • 在表示ORDER_ID
  • 的项目中输入值
  • 执行查询

故事结束。表格触发器&过程(由向导创建)将完成其工作并检索主记录和详细记录。

无需额外编码;如果您是熟练的开发人员,您可以在几分钟内创建这样的表单。不会美丽,但会有效&可靠。

尽管有可能,手动操作真的没用。如果该ORDER_ID的单个项目,则您的代码可以正常运行。对于两个或更多项目,如您所知,它会因TOO-MANY-ROWS错误而失败。

基本上,如果你坚持,你应该使用循环:

  • 您将ORDER_ID输入主程序段
  • 因为您需要遍历详细信息块,即使用NEXT_RECORD,这是一个受限制的程序,您不能使用多个触发器(打开表格在线帮助系统并阅读它们),所以"显示项目"按钮(带有WHEN-BUTTON-PRESSED触发器)可能很好
  • 游标FOR循环将是您的选择
  • 对于它提取的每一行,您都会填充块项目和
  • 导航到下一条记录(否则,您将继续覆盖第一个表格块行中的现有值)

正如我所说:可能,但不推荐。