Pro*C Oracle - циклический выбор SQL
Я начинаю с Pro*C и имею программу, которая читает записи и распечатывает их сгруппированные по идентифицирующему значению (гости). Чтобы напечатать всю информацию, я использовал перерыв в цикле for, чтобы контролировать, что и куда идет. Он компилируется, но не следует схеме печати и фактически заходит в бесконечный цикл. Последний разрыв в конце состоит в том, чтобы остановить бесконечный цикл, и он по какой-то причине не выполняет ни одного из условий (даже с другим значением по умолчанию). На удаленном сервере баз данных, на котором он выполняется, имеется ограниченная отладка (dbx недоступен).
Пока не конец курсора (т. Е. Sqlcode = 0) Если PrevSaleItem Not = Cursor.Item_ID Записать промежуточные итоги для элемента Инициализировать ItemQty и ItemTotal в 0 Установить PrevSaleItem в Cursor.Item_ID Конец, если вывести строку детализации, добавить Cursor.Quantity в ItemQty Add Cursor.calc_tax to 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, и вместо того, чтобы просто использовать его для цикла с разрывом), если предыдущий элемент!= Идентификатор элемента, то он печатает промежуточные итоги, инициализирует количество элементов и итоги равными 0 и устанавливает предыдущий элемент в элемент id (затем ломает условное выражение if). Количество предметов увеличивается на количество в таблице, а calc_tax
добавляется к элементу и итоговому количеству гостей. Извлекается следующая запись, печатаются итоги по последнему элементу, а затем печатаются итоги по этому гостю.
Он не печатает суммы, где это должно быть, и находится в бесконечном цикле, и после того, как я попробовал разрывы во всех условных выражениях, я не могу объяснить, как это происходит. Я уверен, что это ошибка новичка, так что, возможно, у младшего разработчика Oracle (но профессионал был бы хорош) есть момент, чтобы вернуть меня в нужное русло.
1 ответ
Ваш fetch
находится за пределами for
петля. Вы идете в петлю после первого fetch
, Если sqlca.sqlcode
ноль после этой первой выборки, он не достигает ни одного из разрывов из-за вложенного if
а также else
так что снова идет по кругу. Потому что нет второй выборки, у вас еще есть хороший 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
или.