当定义的密码字段长于实际密码值时,Cobol连接到oracle失败
当定义的密码字段长度超过用户的实际密码长度时,我的COBOL程序无法连接到oracle。i、 e、如果密码值为“mypasswd”,则保存密码的主机变量必须定义为“picx(8)”,否则连接失败;例如:当定义的密码字段长于实际密码值时,Cobol连接到oracle失败,oracle,cobol,procobol,Oracle,Cobol,Procobol,当定义的密码字段长度超过用户的实际密码长度时,我的COBOL程序无法连接到oracle。i、 e、如果密码值为“mypasswd”,则保存密码的主机变量必须定义为“picx(8)”,否则连接失败;例如: 1 IDENTIFICATION DIVISION. 2 PROGRAM-ID. SAMPLE. 3 ENVIRONMENT DIVISION. 4 DATA DIVISION. 5 WORKING-STO
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:用户名/密码无效;拒绝登录
但当我将密码字段定义更改为:
图X(008)中的801个密码。
i、 e.长度等于实际密码值的长度(长度(“mypasswd”)=8),程序可以成功连接到Oracle
我的情况是,我们需要用户能够提供自己的用户名和密码,因此我们必须首先定义足够长的用户名和密码字段,以保持我们允许的最大长度。但是,如上所述,如果用户选择的密码比最大密码短,则所有连接请求都将失败
该程序是从Oracle 11.2.0.1.0的旧版本迁移而来的,在旧版本中我们没有此问题,程序运行正常,连接操作成功。
但问题发生在我们迁移到Oracle 12.1.0.1.0之后。您是否尝试过使用引用修改来调整连接请求中用户名/密码的长度 我不是一个神谕式的人,但像这样的事情可能会奏效:
22 EXEC SQL
23 CONNECT :USERNAME(1:UNAMELEN) IDENTIFIED BY :PASSWD(1:PSSWDLEN) USING :DBSTRING
24 END-EXEC.
其中UNAMELEN和PSSWDLEN是数字变量(例如PIC S9(4)二进制),包含用户名和密码的实际长度
可以使用类似以下内容的检查动词来确定UNAMELEN和PSSWDLEN的值:
INSPECT PASSWD TALLYING PSSWDLEN FOR ALL SPACE
COMPUTE PSSWDLEN = LENGTH OF PASSWD - PSSWDLEN
如果密码和用户名不包含内部空格,这将起作用。如果他们这样做,您将不得不以不同的方式计算实际长度。您是否尝试过使用引用修改来调整连接请求中用户名/密码的长度 我不是一个神谕式的人,但像这样的事情可能会奏效:
22 EXEC SQL
23 CONNECT :USERNAME(1:UNAMELEN) IDENTIFIED BY :PASSWD(1:PSSWDLEN) USING :DBSTRING
24 END-EXEC.
其中UNAMELEN和PSSWDLEN是数字变量(例如PIC S9(4)二进制),包含用户名和密码的实际长度
可以使用类似以下内容的检查动词来确定UNAMELEN和PSSWDLEN的值:
INSPECT PASSWD TALLYING PSSWDLEN FOR ALL SPACE
COMPUTE PSSWDLEN = LENGTH OF PASSWD - PSSWDLEN
如果密码和用户名不包含内部空格,这将起作用。如果他们这样做,您将不得不以不同的方式计算实际长度。如果您使用的是Pro*COBOL,则此链接适用于您: 它显示了如何将用户名和密码字段定义为可变字段
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
这真的没问题。您可以计算给定用户的密码长度,然后使用已计算的值,而不是使用文字5
@NealB在他的回答中展示了一种简单的方法(如果密码中没有前导空格或嵌入空格)
如果无法使用该方法,请选择一个简单的循环构造,从密码字段的最后一个字节开始,在遇到空格时继续。注意完全空间的可能性
无论如何,您可能希望对用户名使用相同的技术,因为它在不同风格的Oracle/OS之间更易于传输(取决于允许它为您工作的是什么)。我会这么做的,除非绝对不可能需要
您确实提到要升级到新的Oracle版本。这种行为应记录在文件的变更摘要或类似章节中。如果找不到对它的引用,请联系Oracle并了解发生了什么
如果您没有使用Pro*COBOL,您可能能够模拟变化的效果
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.
然后:
您可能必须尝试:
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版本,以及您尝试过的内容和尝试后得到的结果。如果您使用的是Pro*COBOL,则此链接适用于您: 它显示了如何将用户名和密码字段定义为可变字段
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
这真的没问题。您可以计算给定用户的密码长度,然后使用已计算的值,而不是使用文字5
@NealB在他的回答中展示了一种简单的方法(如果密码中没有前导空格或嵌入空格)
如果无法使用该方法,请选择一个简单的循环构造,从密码字段的最后一个字节开始,在遇到空格时继续。注意完全空间的可能性
无论如何,您可能希望对用户名使用相同的技术,因为它在不同风格的Oracle/OS之间更易于传输(取决于允许它为您工作的是什么)。我会这么做的,除非绝对不可能需要
您确实提到要升级到新的Oracle版本。这种行为应记录在文件的变更摘要或类似章节中。如果找不到对它的引用,请联系Oracle并了解发生了什么
如果您没有使用Pro*COBOL,您可能能够模拟变化的效果
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.
然后:
您可能必须尝试:
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版本,以及你尝试过的内容和尝试后得到的结果。你使用过你最喜欢的搜索引擎吗?甲骨文问道?查看文档?你使用过你最喜欢的搜索引擎吗?甲骨文问道?查看