0

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

/* 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 也被执行

谢谢你帮我解决这个问题。

4

3 回答 3

1

As @Roger Cornejo suggests, you need a way to not execute the 'no match' section if there is a match. no_match: is just a label so there's nothing to tell your code not to execute that section. You either need to return before that label, or goto something after it. You also need to close the cursor in the no-match scenario.

But this seems unnecessarily messy and as @Arion hinted you don't need an explicit cursor for this - just do a select into and catch the exception.

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();

You've said there will be zero or one rows; if there are more than one you'll get a too-many-rows error (ORA-02112).

于 2012-04-10T10:28:45.363 回答
0

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

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

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

然后

如果 ( sqlca.sqlcode != 0 )

评估为假(实际上,仅对捕获其他问题有用),然后

处理_客户();

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

于 2013-09-05T18:58:26.223 回答
0

在“EXEC SQL CLOSE customer_cursor;”之后添加 GOTO

于 2012-04-09T13:19:32.650 回答