0

我想从我的查询中获取不同 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;
4

1 回答 1

1

游标语句中间不能有一个into;这是引发异常的那个。如果您的o_listCTE 只选择一个值,那么这将运行,但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值,然后在需要时引发异常;然后为实际消耗关闭并重新打开游标。但这仍然会执行两次游标查询。

或者,如果您的处理,尤其是 fetch,可以容纳它,您可以向现有游标查询添加分析计数:

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

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

如果您必须计入此过程但将光标返回给另一个过程/调用者,那将不起作用;调用者必须检查结果并引发异常,这可能不是您认为的工作方式。

于 2014-10-15T16:05:31.903 回答