我从Pro*C开始,有一个程序可以读取记录并按标识值(guests)分组输出。为了打印出所有的信息,我使用for循环的中断来控制到哪里。它进行编译,但不遵循打印方案,实际上进入了一个无限循环。最后一个中断是停止无限循环,它不会因为某种原因(即使使用默认的else)碰到任何条件。它在执行的远程数据库服务器上的调试有限(dbx不可用)。
而不是光标的末端(即sqlcode=0)
如果PrevSaleItem不=Cursor.Item\u ID
写出项目的小计
将itemQuantity和ItemTotal初始化为0
将PrevSaleItem设置为Cursor.Item\u ID
结束if
打印明细行
将光标.数量添加到项目数量
将Cursor.calc_tax添加到ItemTotal和GuestTotal
在游标中获取下一条记录
结束While
打印最后一项的小计
打印总计

exec sql open dbGuest;
exec sql fetch dbGuest into :sLastName, :sFirstName, :nItemID, :sItemName, :nQuantity, :nUnitPrice, :sTransDate, :sHotelName, :nHotelID, :sTaxable, :nCalcTax;
/* Lets check the status of the OPEN statement before proceeding , else exceptions would be suppressed */
if(sqlca.sqlcode !=0)  // If anything went wrong or we read past eof, stop the loop
 {
    printf("Error while opening Cursor <%d><%s>\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
    break;
 }
int PrevSaleItem = 0;
int ItemQty = 0;
double ItemTotal = 0.0;
double GuestTotal = 0.0;
for(;;)
{
    printf("%s %s %s %s %d\n","Charge Summary for:", sFirstName.arr, sLastName.arr, " Guest_ID:", nGuest_ID);
    printf("%s %d %s %s \n", "Sales_Item: ", nItemID, " - ", sItemName.arr);
    // Do the crazy stuff to end the C-Strings
    sLastName.arr[sLastName.len] = 0;
    sFirstName.arr[sFirstName.len] = 0;
    sItemName.arr[sItemName.len] = 0;
    sTransDate.arr[sTransDate.len] = 0;
    sHotelName.arr[sHotelName.len] = 0;
    sTaxable.arr[sTaxable.len] = 0;
    // initialize
    PrevSaleItem = nItemID;
    ItemQty = 0;
    ItemTotal = 0.0;
    GuestTotal = 0.0;
    //While not end of cursor (ie. sqlcode = 0)
    /* Check for No DATA FOUND */
    if (sqlca.sqlcode == 0)
    {
        if(PrevSaleItem != nItemID)
        {
            printf("ItemQty: %f \t ItemTotal: %f",ItemQty,ItemTotal);
            ItemTotal = 0.0;
            GuestTotal = 0.0;
            PrevSaleItem = nItemID;
        }
        printf("GuestTotal \t\t %f",GuestTotal);
        ItemQty += nQuantity;
        ItemTotal += nCalcTax;
        GuestTotal += nCalcTax;
    }
    else if(sqlca.sqlcode == 100 || sqlca.sqlcode == 1403)  // If anything went wrong or we read past eof, stop the loop
    {
        printf("CURSOR is empty after all fetch");
        PrevSaleItem = -1;
        break;
    }
    /* Check for other errors */
    else if(sqlca.sqlcode != 0)
    {
         printf("Error while fetching from Cursor <%d><%s>\n",sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
         break;
    }
    else {printf("HIT ELSE"); break;}
    break;
}
// close the cursor and end the program
exec sql close dbGuest ;

The logic that should be happening is as follows
假设中断机制在外部for循环内(未显示)。它应该打开光标,获取第一条记录,然后打印客户和销售项目的标题。然后通过设置值初始化总计和中断变量。While不是游标的结尾(sqlcode是0,而不是While只用于带有break的循环)如果是前一项!=项目id,然后打印小计,将项目数量和总计初始化为0,并将上一个项目设置为项目id(然后断开if条件)。项目数量将增加表中的数量,并且calc_tax将添加到项目和来宾总数中。获取下一条记录,打印最后一项的总计,然后打印该来宾的总计。
它没有打印出它应该在的位置,并且是无限循环的,在我尝试了所有条件句的中断之后,我不知所措地解释了它是如何发生的。我相信这是一个初学者的错误,所以也许一个jr甲骨文开发人员(但专业人士会很好)有一点时间让我回到正轨。

最佳答案

你的fetchfor循环之外。在第一个fetch之后进入循环。如果第一次提取之后sqlca.sqlcode为零,则由于嵌套的ifelse,它不会到达任何中断,因此它会再次循环。因为没有第二次取回,您仍然有一个好的sqlcode,所以它继续运行。我想。。。。总之,将fetch移动到循环中看起来像是要发生什么?
看起来最后的break应该开始了,但是昨天你发布了你修改过的代码,所以我不确定这里是否也是这样。
如果重新格式化代码并为else条件引入大括号和嵌套,则可以看到它们不对齐。您显示的最后一个{不是针对for,而是针对其中一个分支。

for(;;)
{
    if (sqlca.sqlcode == 0)
    {
        if(PrevSaleItem != nItemID)
        {
            ...
        }
        ....
    }
    else
    {
        if(sqlca.sqlcode == 100 || sqlca.sqlcode == 1403)
        {
            break;
        }
        else
        {
            if(sqlca.sqlcode != 0)
            {
                break;
            }
            else
            {
                printf("HIT ELSE");
                break;
            }
            break;
        }
       // close the cursor and end the program
       exec sql close dbGuest ;

else if(sqlca.sqlcode != 0)是多余的;此时sqlca.sqlcode必须不是0、100或1403。所以它也不能到达下一个。

07-26 01:36