Oracle Pro * C:处理获取光标的结束

时间:2012-04-08 23:35:29

标签: c oracle error-handling cursor oracle11g

我无法弄清楚代码上的问题:

/* Declare a cursor for the FETCH statement. */
EXEC SQL DECLARE customer_cursor CURSOR FOR
SELECT CUSTOMER_ID, CUSTOMER_NAME
FROM CUSTOMER_TABLE 
WHERE CUSTOMER_CARD_NUM = :argv[1];

if ( sqlca.sqlcode != 0 )
{
        printf("Declare cursor failed\n");
        return( sqlca.sqlcode );
}
EXEC SQL OPEN customer_cursor;
if ( sqlca.sqlcode != 0 )
{
        printf("Open cursor failed\n");
        return( sqlca.sqlcode );
}
EXEC SQL WHENEVER NOT FOUND GOTO no_match;

for ( ;; )
{
    /* Fetching data */
    EXEC SQL FETCH customer_cursor 
        INTO :var_customer_id, :var_customer_name;
    if ( sqlca.sqlcode != 0 )
    {
            EXEC SQL CLOSE cust_data_cursor;
            return ( sqlca.sqlcode );
    }

    /* Doing some stuff here */
    processing_customer();

}
EXEC SQL CLOSE customer_cursor;

/* Handling the no data found here */    
no_match:

      printf("NO CUSTOMER MATCHING THIS CARD_NUM\n");
      /* Some stuff */
      ......
      return 1;

我的查询应该只返回一行或什么都不返回,当没有任何内容返回时,一切正常,但是当匹配时,执行函数processing_customer并且奇怪的是执行no_match

感谢您帮助我解决这个问题。

3 个答案:

答案 0 :(得分:1)

正如@Roger Cornejo建议的那样,如果匹配,你需要一种执行'不匹配'部分的方法。 no_match:只是一个标签,所以没有什么可以告诉你的代码不执行该部分。您需要在该标签之前返回,或者在goto之后返回。您还需要在不匹配方案中关闭光标。

但是这看起来不必要地混乱,因为@Arion暗示你不需要一个明确的游标 - 只需做一个select into并捕获异常。

EXEC SQL SELECT CUSTOMER_ID, CUSTOMER_NAME
    INTO :var_customer_id, :var_customer_name
    FROM CUSTOMER_TABLE 
    WHERE CUSTOMER_CARD_NUM = :argv[1];

if (sqlca.sqlcode == 1403)
{
    printf("NO CUSTOMER MATCHING THIS CARD_NUM\n");
    /* Some stuff */
    ......
    return 1;
}
if (sqlca.sqlcode != 0)
{
    return ( sqlca.sqlcode );
}

/* Doing some stuff here */
processing_customer();

你说过会有零行或一行;如果有多个,你会得到太多行错误(ORA-02112)。

答案 1 :(得分:0)

在“EXEC SQL CLOSE customer_cursor;”

之后添加GOTO

答案 2 :(得分:0)

将您的标签“no_match”更改为“no_more_records”,您就会明白为什么会运行2次:

a)当没有记录时,FETCH会立即提出NOT FOUND条件,因此会转到标签“no_more_records”

b)当有一个(或多个)记录时,执行FETCH返回第一个记录。

然后

  

if(sqlca.sqlcode!= 0)

评估为false(实际上,只对陷阱其他问题有用)然后

  

processing_customer();

之后,FETCH再次运行(通过无穷大)并且表现为(a):no_more_records条件到达。