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 или.

Другие вопросы по тегам