Cobol подключиться к оракулу не удалось, когда поле пароля определено дольше, чем значение реального пароля

Моя программа на языке COBOL не может подключиться к oracle, если для поля пароля задано значение, превышающее фактическую длину пароля для пользователя. т. е. если значением пароля является "mypasswd", переменная хоста для хранения пароля должна быть определена с помощью "PIC X(8)", в противном случае соединение не будет установлено; например:

 1         IDENTIFICATION DIVISION.
 2         PROGRAM-ID. SAMPLE.
 3         ENVIRONMENT DIVISION.
 4         DATA DIVISION.
 5         WORKING-STORAGE SECTION.
 6             EXEC SQL BEGIN DECLARE SECTION END-EXEC.
 7         01 USERNAME      PIC         X(010).
 8         01 PASSWD        PIC         X(010).
 9         01 DBSTRING      PIC         X(020).
10             EXEC SQL END DECLARE SECTION END-EXEC.
11             EXEC SQL INCLUDE SQLCA END-EXEC.
12
13         PROCEDURE DIVISION.
14         BEGIN-PGM.
15             EXEC SQL WHENEVER SQLERROR
16              DO PERFORM SQL-ERROR
17             END-EXEC.
18         LOGON.
19             MOVE "myuser" TO USERNAME.
20             MOVE "mypasswd" TO PASSWD.
21             MOVE "mydb" TO DBSTRING.
22             EXEC SQL
23              CONNECT :USERNAME IDENTIFIED BY :PASSWD USING :DBSTRING
24             END-EXEC.
25         LOGOUT.
26             DISPLAY "HAVE A GOOD DAY.".
27             EXEC SQL COMMIT WORK RELEASE END-EXEC.
28             STOP RUN.
29         SQL-ERROR.
30             EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
31             DISPLAY "ORACLE ERROR DETECTED:".
32             DISPLAY SQLERRMC.
33             EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
34             STOP RUN.

Я должен получить ошибку соединения: ORACLE ОБНАРУЖЕНА ОШИБКА: ORA-01017: неверное имя пользователя / пароль; вход запрещен

Но когда я изменяю определение поля пароля на: 8 01 PASSWD PIC X(008). т.е. длина равна длине действительного значения пароля (длина ("mypasswd")=8), программа может успешно подключиться к Oracle.

Моя ситуация такова, что нам нужно, чтобы пользователи могли указывать свое имя пользователя и пароль, поэтому мы должны сначала определить поля имени пользователя и пароля достаточно долго, чтобы сохранить максимально допустимую длину. Тем не менее, как указано выше, все запросы на подключение будут неудачными, если пользователь выберет более короткий пароль, чем максимальный.

Программа перенесена из старой версии Oracle 11.2.0.1.0, где у нас нет этой проблемы, программа работала нормально, операция подключения прошла успешно. Но проблема возникла после перехода на Oracle 12.1.0.1.0.

2 ответа

Решение

Если вы используете Pro*COBOL, то эта ссылка для вас: http://docs.oracle.com/cd/A57673_01/DOC/api/doc/PCO18/ch1.htm

Он показывает, как определить ваши поля имени пользователя и пароля как VARYING.

 WORKING STORAGE SECTION. 

     ... 

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 

         01  USERNAME  PIC X(10) VARYING. 

         01  PASSWD    PIC X(10) VARYING. 

         ... 

     EXEC SQL END DECLARE SECTION END-EXEC. 

     ... 

 PROCEDURE DIVISION. 

 LOGON. 

     MOVE "SCOTT" TO USERNAME-ARR. 

     MOVE 5 TO USERNAME-LEN. 

     MOVE "TIGER" TO PASSWD-ARR. 

     MOVE 5 TO PASSWD-LEN. 

     EXEC SQL WHENEVER SQLERROR GOTO LOGON-ERROR END-EXEC. 

     EXEC SQL 

         CONNECT :USERNAME IDENTIFIED BY :PASSWD 

     END-EXEC. 

Оказывается, приведенный пример не является полезным для вас (из комментариев), поскольку ваши пароли могут быть не пятью по длине.

Это действительно не проблема. Вы можете рассчитать длину пароля для данного пользователя, а затем вместо литерала 5 использовать рассчитанное вами значение.

@NealB показал в своем ответе простой способ сделать это (если у вас нет начальных или встроенных пробелов в пароле).

INSPECT PASSWD TALLYING PSSWDLEN FOR ALL SPACE
COMPUTE PSSWDLEN = LENGTH OF PASSWD - PSSWDLEN 

Если вы не можете использовать этот метод, простая конструкция цикла по вашему выбору, начиная с последнего байта поля пароля и продолжая, пока пробел встречается. Не упустите полностью космическую возможность.

В любом случае вы можете захотеть использовать одну и ту же технику для имени пользователя, так как она будет более переносимой среди различных разновидностей Oracle/OS (в зависимости от того, что позволяет вам работать). Я бы сделал это, если это абсолютно невозможно, что это когда-либо требуется.

Вы упоминаете о переходе на новую версию Oracle. Это поведение должно быть задокументировано в разделе "Сводка изменений" или аналогичном разделе документации. Если вы не можете найти ссылку на него, свяжитесь с Oracle и узнайте, что происходит.

Если вы не используете Pro*COBOL, вы можете эмулировать эффект VARYING.

     EXEC SQL BEGIN DECLARE SECTION END-EXEC. 

         01  USERNAME.
             05  USERNAME-LEN BINARY PIC 9(4).
             05  USERNAME-VALUE      PIC X(10). 

         01  PASSWD.
             05  PASSWD-LEN BINARY PIC 9(4).
             05  PASSWD-VALUE      PIC X(10). 

     END-EXEC. 

Затем:

 LOGON. 

     MOVE "SCOTT" TO USERNAME-VALUE. 

     MOVE 5 TO USERNAME-LEN. 

     MOVE "TIGER" TO PASSWD-VALUE. 

     MOVE 5 TO PASSWD-LEN. 

     EXEC SQL WHENEVER SQLERROR GOTO LOGON-ERROR END-EXEC. 

     EXEC SQL 

         CONNECT :USERNAME IDENTIFIED BY :PASSWD 

     END-EXEC. 

Возможно, вам придется попробовать:

         01  USERNAME.
             05  USERNAME-LEN BINARY PIC 9(4).
             05  USERNAME-VALUE.
                 10  FILLER OCCURS 1 TO 10 TIMES
                     DEPENDING ON USERNAME-LEN.
                     15  FILLER      PIC X. 

         01  PASSWD.
             05  PASSWD-LEN BINARY PIC 9(4).
             05  PASSWD-VALUE.
                 10  FILLER OCCURS 1 TO 10 TIMES
                     DEPENDING ON PASSWD-LEN.
                     15  FILLER      PIC X. 

     END-EXEC. 

Если вы ничего не получите с предложением, вам нужно предоставить больше информации, такой как ОС, версия COBOL, версия Oracle, и что вы пробовали, и какие результаты вы получили с этими попытками.

Вы пытались использовать эталонную модификацию для настройки длины имени пользователя / пароля в запросе на подключение?

Я не из тех, кто любит Oracle, но что-то вроде этого может сработать:

22             EXEC SQL
23              CONNECT :USERNAME(1:UNAMELEN) IDENTIFIED BY :PASSWD(1:PSSWDLEN) USING :DBSTRING
24             END-EXEC.

где UNAMELEN и PSSWDLEN - числовые переменные (например, PIC S9(4) BINARY), содержащие фактическую длину имени пользователя и пароля.

Определить значения для UNAMELEN и PSSWDLEN можно с помощью глагола INSPECT примерно так:

INSPECT PASSWD TALLYING PSSWDLEN FOR ALL SPACE
COMPUTE PSSWDLEN = LENGTH OF PASSWD - PSSWDLEN 

Это будет работать при условии, что пароли и имена пользователей не содержат внутренних пробелов. Если они это сделают, вам придется вычислять фактическую длину по-разному.

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