【问题标题】:Pro*C Oracle -- looping through sql fetchPro*C Oracle -- 循环通过 sql fetch
【发布时间】:2014-02-22 20:06:42
【问题描述】:

我从 Pro*C 开始,并且有一个程序可以读取记录并按识别值(客人)分组打印出来。为了打印所有信息,我使用了 for 循环中的一个 break 来控制去哪里。它可以编译,但没有遵循打印方案,实际上进入了无限循环。最后的最后一个中断是停止无限循环,并且由于某种原因它没有达到任何条件(即使是默认的 else)。正在执行的远程数据库服务器上的调试有限(dbx 不可用)。

虽然不是光标结尾(即 sqlcode = 0) 如果 PrevSaleItem Not = Cursor.Item_ID 编写项目的小计 将 ItemQty 和 ItemTotal 初始化为 0 将 PrevSaleItem 设置为 Cursor.Item_ID 万一 打印详细信息行 将 Cursor.Quantity 添加到 ItemQty 将 Cursor.calc_tax 添加到 ItemTotal 和 GuestTotal 获取游标中的下一条记录 结束时 打印最后一项的小计 打印总计

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 循环中(未显示)。它应该打开光标,获取第一条记录,然后打印客人和销售项目的标题。然后它通过设置值来初始化总计和中断变量。虽然不是光标的结尾(sqlcode 为 0,而不是 while 仅用于带中断的循环)如果前一个项目!= 项目 ID,则它打印小计,将项目数量和总计初始化为 0,并将前一个项目设置为项目id (然后打破 if 条件)。项目数量按表中的数量增加,calc_tax 被添加到项目和客人总数中。获取下一条记录,打印最后一项的总计,然后打印该客人的总计。

它没有打印应该在的位置并且处于无限循环中,并且在我尝试了所有条件的中断之后,我无法解释它是如何发生的。我确信这是一个初学者的错误,所以也许一个 jr Oracle 开发人员(但专业人士会很棒)有时间让我回到正轨。

【问题讨论】:

  • 首先,由于您在终止for(;;) 循环的} 之前有一个休息时间,所以我看不出这怎么可能是无限循环。但是,尽管如此 - 循环内没有游标的获取,因此您永远不会从游标中读取另一行,因此您永远不会到达游标获取的数据的末尾。分享和享受。
  • 谢谢,我会将 fetch 放入循环中。至于无限循环,在帖子的第一段中间,我说最后一个break 是故意停止无限循环的。也许我应该写得更清楚,但我的意图是在最后一个 break 上发表评论,然后将其留在代码中,这样我就不会导致其他任何人遭受我经历过的无限循环的痛苦——不要不想阻止人们提供帮助:)
  • 作为一项规则,您应该以显示您所描述的问题的形式发布代码。

标签: sql c oracle oracle-pro-c embedded-sql


【解决方案1】:

您的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。所以它也无法到达下一个 else

【讨论】:

  • 谢谢!我明白你在说 fetch 应该在循环中。它仍然没有打印最终总计或项目总计。我不想再麻烦你了,但我刚刚意识到我在打印总数时也问了我做错了什么。我认为这不是问题的一部分,所以如果你没问题,我会接受你的回答,然后发布一个不同的问题,说明为什么它不能在循环中正确打印。
猜你喜欢
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2019-06-16
  • 2012-01-02
  • 2016-01-05
相关资源
最近更新 更多