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

Posted

技术标签:

【中文标题】Oracle 选择变量,错误 ORA-00947 没有足够的值【英文标题】:Oracle select into variable, ERROR ORA-00947 not enough values 【发布时间】:2014-10-15 14:52:18 【问题描述】:

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

游标语句中间不能有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 值,然后在需要时引发异常;然后为实际消耗关闭并重新打开游标。但这仍然会执行两次游标查询。

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

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

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

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

【讨论】:

谢谢 Alex,我正在从存储过程中返回游标。如果我没有遇到多个供应商发送相同 ASN 号的情况,“o_list”会返回什么。我必须执行该查询两次,一次计算,然后一次获取我的列表。因此,在这种情况下,听起来打开光标会更有效,但在语法和找到正确的资源示例时会遇到问题。 它不一定会更有效,但会减少代码重复,从而减少维护 - 以及一个查询被更改而另一个查询丢失的风险。 我也是这么想的。我用我当前的光标打开绊脚石更新了我的问题,因为这似乎是现在手头的真正问题。也许我应该把这个问题的标题改得更合适。 也许像你建议的那样通过分区将计数添加到主查询会更容易,尝试一下。 我认为这回答了我问的关于我的错误的实际问题。如何用光标实现这一点是我在这里发布的另一个问题:***.com/questions/26388104/…

以上是关于Oracle 选择变量,错误 ORA-00947 没有足够的值的主要内容,如果未能解决你的问题,请参考以下文章

oracle创建存储过程时,提示错误是:错误(5,18): PL/SQL: ORA-00947: 没有足够的值?代码如下:

oracle创建存储过程时,提示错误是:错误(5,18): PL/SQL: ORA-00947: 没有足够的值?代码如下:

向oracle数据库中添加数据时提示ORA-00947: 没有足够的值

ORA-00947: 在 Oracle 中创建对象时值不足

向Oracle数据库插入数据时提示 ora-00947: 没有足够的值

SQL 错误:ORA-00947:没有足够的值 - 尝试使用默认值