[英]Pro*C Oracle — looping through sql fetch
我從Pro * C開始,有一個程序可以讀取記錄並按照識別值(客人)打印出來。 為了獲得所有打印的信息,我使用for循環中斷來控制其中的內容。 它編譯但它不遵循打印方案,實際上進入無限循環。 最后的最后一個突破是停止無限循環,並且由於某種原因它沒有達到任何條件(即使使用默認的其他)。 它正在執行的遠程數據庫服務器上的調試有限(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,而不是僅用於帶有中斷的循環)如果前一項!=項目ID,則它打印小計,初始化項目數量和總計為0並將前一項目設置為項目id(然后打破if條件)。 項目數量增加了表格中的數量, calc_tax
將添加到項目和客戶總計中。 獲取下一條記錄,打印最后一項的總計,然后打印該客戶的總計。
它不會打印它應該存在的數量並且處於無限循環中,並且在我嘗試了所有條件中的中斷之后,我無法解釋它是如何發生的。 我確定這是一個初學者的錯誤,所以也許一個小的Oracle開發人員(但專業人員會很棒)有一個時刻讓我回到正軌。
你的fetch
是在for
循環之外。 在第一次fetch
后進入循環。 如果sqlca.sqlcode
在第一次獲取后為零,則由於嵌套的if
和else
,它沒有到達任何中斷,因此它再次繞過循環。 因為沒有第二次獲取,你仍然有一個很好的sqlcode
,所以它繼續。 我想....無論如何,將你的fetch
移動到循環中看起來就像你想要發生的那樣?
它看起來確實應該啟動最終break
,但是昨天你發布了你修改過的代碼,所以我不確定這是否也是如此。
如果您重新格式化代碼並為else
條件引入大括號和嵌套,您可以看到它們沒有對齊。 最終{
你展示的不是for 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
必須是sqlca.sqlcode
或1403之外的else
。所以它也不能到達下一個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.