Domanda

I'm beginning with Pro*C and have a program that reads in records and prints out grouped by an identifying value (guests). In order to get all the information printed, I used a break from the for loop to control what goes where. It compiles but it's not following the printing scheme and actually goes into an infinite loop. The last break at the end is to stop the infinite loop, and it's not hitting any of the conditionals for some reason (even with a default else). There's limited debugging on the remote database server it's executing on (dbx is not available).

While not end of cursor (ie. sqlcode = 0) If PrevSaleItem Not = Cursor.Item_ID Write The Subtotals for the Item Initialize ItemQty and ItemTotal to 0 Set PrevSaleItem to Cursor.Item_ID End if Print Out Detail Line Add Cursor.Quantity to ItemQty Add Cursor.calc_tax to ItemTotal and GuestTotal Fetch next record in cursor End While Print the Subtotals for the last item Print the Grand totals

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:

Assume the break mechanism is within an outer for loop (not shown). It should open the cursor, fetch the 1st record, and then print the heading for the guest and the sales item. It then initializes the totals and break variables by setting the values. While not the end of cursor (sqlcode is 0, and instead of while just used for loop with break) if the previous item != the item id then it prints subtotals, initializes item quantities and totals to 0 and sets the previous item to item id (then breaks the if conditional). Item quantity is increased by the quantity in the table, and the calc_tax is added to the item and guest totals. The next record is fetched, the totals for that last item are printed, and then the grand totals for that guest are printed.

It's not printing the amounts where it should be and is in infinite loop, and after I tried breaks in all the conditionals, I'm at a loss to explain how it's happening. I'm sure it's a beginner mistake, so maybe a jr Oracle developer (but a pro would be great) has a moment to get me back on track here.

È stato utile?

Soluzione

Your fetch is outside the for loop. You go into the loop after the first fetch. If sqlca.sqlcode is zero after that first fetch, it isn't reaching any of the breaks because of the nested if and else, so it goes round the loop again. Becuase there is not a second fetch, you still have a good sqlcode, so it keeps going. I think.... Anyway, moving your fetch into the loop looks like what you want to happen?

It does look like that final break should kick in, but yesterday you posted code you'd modified so I'm not sure if that's the case here too.

If you reformat your code and introduce braces and nesting for the else conditions you can see they don't line up. The final { you showed isn't for the for, it's for one of the branches.

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 ;

The else if(sqlca.sqlcode != 0) is redundant; at this point sqlca.sqlcode has to be something other than 0, 100 or 1403. So it can't reach the next else either.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top