2013-05-11 2 views
0

Я извлекаю данные из своей базы данных, где одно из условий всегда будет одинаковым, а другое будет иметь значение от 1 до 13. Запрос должен выполняться 13 раз, один раз для каждого значения.Данные не извлекаются из базы данных (SQLCODE 100), хотя существуют данные

Все компилируется, но когда я смотрю на вывод, я замечаю, что значения, используемые для извлечения данных из инструкции SELECT, никогда не имеют значения. Когда я выполняю тот же запрос с жестко закодированными операциями WHERE в SQL Server Management Studio, данные извлекаются, как ожидалось. SQLCODE Я принимаю 100.

Когда я опускаю цикл PERFORM VARYING и дать мой запрос жестко закодированные данные, мои QUESTION-CODE и ANSWER-CODE поля содержат правильные данные, но AMOUNT один первый пустой, то нуль.

Я использую OpenCobol компилятор с SQL Server 2012.

Что я с видом?

01 WS-FIELDS. 
    05 I PIC 9(2). 

01 WS-EVALUATION. 
    05 QUESTION-CODE PIC 9(3). 
    05 ANSWER-CODE PIC 9(3). 

01 WS-RESULT. 
    05 OV PIC 9(3). 
    05 V PIC 9(3). 
    05 G PIC 9(3). 
    05 ZG PIC 9(3). 
    05 NVT PIC 9(3). 
    05 AMOUNT PIC 9(3). 

LINKAGE SECTION. 
    01 ROUTE-CODE PIC X(10) VALUE SPACES. 

    EXEC SQL 
    DECLARE crs 
    CURSOR FOR 
     SELECT QuestionCode, AnswerCode, COUNT(AnswerCode) 
     FROM Answers 
     WHERE Route = :ROUTE-CODE AND QuestionCode= :I 
     GROUP BY QuestionCode, AnswerCode 
    END-EXEC 

    EXEC SQL 
    OPEN crs 
    END-EXEC 

    PERFORM UNTIL SQLCODE <> 0 
    PERFORM VARYING I FROM 1 BY 1 UNTIL I = 13 

     EXEC SQL 
     FETCH crs INTO :QUESTION-CODE, :ANSWER-CODE, AMOUNT 
     END-EXEC 

     IF SQLCODE = 0 
     EVALUATE TRUE 
     WHEN ANSWER-CODE = 1 
     MOVE AMOUNT TO OV 
     WHEN ANSWER-CODE = 2 
     MOVE AMOUNT TO V 
     WHEN ANSWER-CODE = 3 
     MOVE AMOUNT TO G 
     WHEN ANSWER-CODE = 4 
     MOVE AMOUNT TO ZG 
     WHEN ANSWER-CODE = 5 
     MOVE AMOUNT TO NVT 
     WHEN OTHER 
     DISPLAY "Error" UPON SYSOUT 
     END-EVALUATE 
     END-IF 

    END-PERFORM 
    END-PERFORM 
    .  
+0

Я не знаю о SQL Server, но для DB2 100 строка не найдена. Это может быть вызвано несоответствием типа. Попробуйте изменить Route = trim (: Route), также есть код вопроса числовой ??? попробуйте определить I как comp sync. –

+0

Я добавил LTRIM (RTRIM()) и изменил определение поля на comp sync: ни одна разница не изменилась. Я считаю, что ошибка существует из-за объявления курсора: она объявлена ​​с переменной 'I', но это значение никогда не перезаписывается. Как мне это исправить? Могу ли я переписать этот курсор каждый раз с новым значением I? –

+0

Нет, измените SQL на QuestionCode между 1 и 13 (или это 0 и 14, мне нужно будет проверить) и не используйте PERFORM VARYING I FROM 1 BY 1 UNTIL I = 13, вам просто нужен PERFORM UNTIL SQLCODE < > 0 –

ответ

2

меняется следующим образом:

EXEC SQL 
    DECLARE crs 
     CURSOR FOR 
     SELECT QuestionCode, AnswerCode, COUNT(AnswerCode) 
     FROM Answers 
     WHERE Route = :ROUTE-CODE AND QuestionCode between 1 and 13 
     GROUP BY QuestionCode, AnswerCode 
     Order By QuestionCode 
    END-EXEC 

    EXEC SQL 
    OPEN crs 
    END-EXEC 

    EXEC SQL 
    FETCH crs 
     ...... 
    END-EXEC 

    PERFORM UNTIL SQLCODE <> 0 

     EXEC SQL 
     FETCH crs 
      ...... 
     END-EXEC 
    End-Perform 

Примечание: Вы, возможно, потребуется проверить, если QuestionCode отсутствует в зависимости от данных/логики

Также в Cobol не ВЫПОЛНИТЬ ПОКА SQLCODE <> 0 фактически является циклом while на большинстве языков. Если вы хотите, чтобы тест был выполнен в конце цикла, используйте опцию With Test After.

Альтернатива: вы можете удалить курсор и выбрать в цикле для каждой строки.

+0

Это решило проблему (по крайней мере: я на 99% уверен, что это так. Не могу сказать точно, потому что значение 'COUNT (AnswerCode)' не вводится в переменную)! Однако обратите внимание: предложение 'ORDER BY' должно быть размещено после' GROUP BY'. –