Oracle选择变量,ERROR ORA-00947没有足够的值

时间:2014-10-15 14:52:19

标签: oracle variables plsql cursor select-into

我想从我的查询中获取不同ASN_NO的计数,以便稍后检查我的存储过程,如果我找到多个并抛出错误。

而不是试图打开光标(我也没有正确地做),我想也许我可以用临时表选择并在我填充光标时存储值。也许这是不可能的,但我的错误对我来说毫无意义。

这是我的简化代码,我打破了count语句,以更好地识别错误的位置。

V_ASN_COUNT           NUMBER;

OPEN O_CURSOR FOR  
  WITH O_LIST AS(
     SELECT *
       FROM AN_ORDER_INFO OI, AN_SHIPMENT_INFO SI
       -- where bunch of stuff
  ),   
  COUNT_ASN_NO AS  (
          SELECT COUNT(DISTINCT ASN_NO) AS "ASN_COUNT"
          FROM O_LIST 
  ),
  SAVE_ASN_COUNT AS (
   SELECT ASN_COUNT
   INTO V_ASN_COUNT
   FROM COUNT_ASN_NO -- error on this line, not enough values, its just 1:1, i dont get it?
  ) 
  SELECT * FROM O_LIST;   

IF(V_ASN_COUNT > 1) THEN
    RAISE MULTIPLE_ASNS;
END IF;   

或许我需要打开光标然后做这样的事情,除了我知道这是错的,我得到"期待BULK INTO"错误:

  OPEN O_CURSOR; 
      LOOP
          FETCH COUNT(DISTINCT ASN_NO) INTO V_ASN_COUNT;
          EXIT WHEN ASN_NO%NOTFOUND;
      END LOOP;
  CLOSE O_CURSOR;

1 个答案:

答案 0 :(得分:1)

您不能在游标语句中间有into;它是抛出异常的东西。如果您的o_list CTE仅选择单个值,那么这将会运行,但v_asn_count之后仍然为空。在o_list中选择了多个列后,它将获得ORA-00947。 (这可能是一个解析器错误;可以说它应该是错误,因为有一个into子句,或者使用正确的CTE查询中的选择列表。)

如果您根本不需要光标并且正在尝试减少代码重复,那么目前还不是很清楚,但看起来您真的只想这样做:

SELECT COUNT(DISTINCT ASN_NO)
INTO V_ASN_COUNT
FROM AN_ORDER_INFO OI, AN_SHIPMENT_INFO SI
-- where bunch of stuff
;

IF(V_ASN_COUNT > 1) THEN
  RAISE MULTIPLE_ASNS;
END IF;

(您的where bunch of stuff可能包含加入条件;它是偏离主题的,但您可能需要考虑使用ANSI连接语法。

如果你有一个现有的游标并且想要实际使用游标(和之前)分别计算不同的值,你可以打开它,迭代它以检查asn_no值,然后引发异常如果需要的话;然后为实际消耗关闭并重新打开光标。但那仍然会执行两次游标查询。

或者,如果您的处理(尤其是提取)可以容纳它,您可以将分析计数添加到现有的游标查询中:

COUNT(DISTINCT dummy) OVER (PARTITION BY NULL) AS ASN_COUNT

...它会在整个结果集中为您提供不同asn_no值的数量,作为该结果集的每一行的额外列。然后,您可以在执行任何其他操作之前在第一次获取之后检查该数字,并在此时引发异常。

如果您必须在此过程中计算但是将光标返回到另一个过程/调用者,那么它将无法工作;调用者必须检查结果并引发异常,这可能不是你看到这种情况的工作原理。