0

我的存储过程有问题。在以下情况下失败

cntmismatch NUMBER;

SELECT COUNT(keyvalue) INTO cntmismatch 
FROM tbl_temp GROUP BY keyvalue HAVING count(keyvalue) > 1

如果没有符合上述标准的数据,则失败

我什至尝试使用

SELECT NVL(COUNT(keyvalue),0) INTO cntmismatch 
FROM tbl_temp GROUP BY keyvalue HAVING count(keyvalue) > 1

但它仍然让我在这里返回 null 并且 proc 失败

4

4 回答 4

3

查询:

SELECT COUNT(keyvalue) INTO cntmismatch FROM tbl_temp GROUP BY keyvalue

cntmismatch... 将尝试为每个返回一行,如果表为空并且如果有多个keyvalue,这将失败。no_data_foundtoo_many_rowskeyvalue

添加:

HAVING count(keyvalue) > 1

...意味着它只会为任何keyvalue具有多个条目的值返回一个值,很明显,所以现在你会得到no_data_found表是否为空或 nokeyvalue出现两次;too_many_rows如果不止一个有keyvalue重复。keyvalue仅当您恰好有一个具有重复项时,它才会起作用。

您没有显示其余的逻辑,但大概您正在根据该返回值做某事,在这种情况下 - 如果只有一个keyvalue,这不太可能 - 您可以省略该HAVING子句并仅测试该值:

SELECT COUNT(keyvalue) INTO cntmismatch FROM tbl_temp GROUP BY keyvalue;
IF cntmismatch > 1 THEN
   ... -- some processing
END IF:

但充其量,它告诉你的只是是否有任何keyvalue出现不止一次;它没有告诉你它们keyvalue是什么,而且仍然无法应对不止一个。

如果要检索具有多个匹配行的所有值并对其进行处理,则可以使用游标:

FOR dup_keyvalues IN (SELECT keyvalue, COUNT(*) AS cnt 
    FROM tbl_temp GROUP BY keyvalue HAVING COUNT(*) > 1) LOOP
    ... - some processing, e.g.
    DBMS_OUTPUT.PUT_LINE('keyvalue ' || dup_keyvalues.keyvalue
        || ' has ' || dup_keyvalues.cnt || ' matches');
    ...
END LOOP;
于 2013-07-12T10:37:25.247 回答
1

如果要计算多次keyvalue出现的值,则需要使用子选择:

SELECT COUNT(*) INTO cntmismatch 
FROM
( SELECT keyvalue, count(*) FROM tbl_temp GROUP BY keyvalue HAVING count(*) > 1)
于 2013-07-12T10:37:15.823 回答
0

尝试这个

BEGIN
   SELECT COUNT(keyvalue) INTO cntmismatch 
    FROM tbl_temp GROUP BY keyvalue HAVING count(keyvalue) > 1
EXCEPTION
  WHEN no_data_found THEN cntmismatch := 0;
END;
于 2013-07-12T10:41:55.803 回答
0

您应该简单地捕获并处理代码中的异常。在你的情况下,你会得到一个 NO_DATA_FOUND 异常。

您将在下面找到一个示例。

PROCEDURE count_mismatch AS
  cntmismatch NUMBER;
BEGIN
  BEGIN
    SELECT COUNT(keyvalue) INTO cntmismatch FROM tbl_temp GROUP BY keyvalue;
  EXCEPTION
  WHEN no_data_found THEN
    cntmismatch := -1;
  END;
END 

我认为,您不再需要 HAVING 子句。因此,我已将其删除。如果您的语句将返回多于预期的 1 行,那么您还必须处理 TOO_MANY_ROWS 异常!

于 2013-07-12T10:39:11.217 回答