我必须编写一个COBOL程序,从一个文件中读取一些记录,并使用它们进行一些计算。如果使用非空白筛选器调用例程,则应对结果进行筛选.
我试图在SQL中使用参数标记。以下是我的尝试:
100 IDENTIFICATION DIVISION. 19/11/07
200 PROGRAM-ID. MINIMALEX. 01/07/20
300 AUTHOR. ME. 01/07/20
400 DATE-WRITTEN. JULY 2020. 01/07/20
500 *----------------------------------------------------------------* 01/07/20
600 *--- Minimal example. ---* 01/07/20
700 *----------------------------------------------------------------* 01/07/20
800 ENVIRONMENT DIVISION. 19/11/07
900 CONFIGURATION SECTION. 19/11/07
1000 SOURCE-COMPUTER. IBM-AS400. 19/11/07
1100 OBJECT-COMPUTER. IBM-AS400. 19/11/07
1200 SPECIAL-NAMES. DECIMAL-POINT IS COMMA. 28/12/10
1300 *----------------------------------------------------------------* 01/07/20
1400 INPUT-OUTPUT SECTION. 19/11/07
1500 FILE-CONTROL. 19/11/07
1600 *----------------------------------------------------------------* 19/11/07
1700 DATA DIVISION. 19/11/07
1800 FILE SECTION. 19/11/07
1900 *----------------------------------------------------------------* 19/11/07
2000 WORKING-STORAGE SECTION. 19/11/07
2100 *--- Variables for SQL. 01/07/20
2200 EXEC SQL 01/07/20
2300 INCLUDE SQLCA 01/07/20
2400 END-EXEC. 01/07/20
2500 EXEC SQL 01/07/20
2600 INCLUDE SQLDA 01/07/20
2700 END-EXEC. 01/07/20
2800 01/07/20
2900 01 WK-NAME PIC X(80). 01/07/20
3000 01 WK-LASTNAME PIC X(80). 01/07/20
3100 01 WK-SELECT PIC X(34). 01/07/20
3200 01 WK-WHERE PIC X(65). 01/07/20
3300 01 WK-STATEMENT PIC X(100). 01/07/20
3400 *----------------------------------------------------------------* 01/07/20
3500 LINKAGE SECTION. 19/11/07
3600 01 LK-NAME PIC X(80). 01/07/20
3700 *----------------------------------------------------------------* 01/07/20
3800 PROCEDURE DIVISION USING LK-NAME. 01/07/20
3900 *----------------------------------------------------------------* 01/07/20
4000 A01-START. 01/07/20
4100 *--- Create and insert data into file. 01/07/20
4200 EXEC SQL 01/07/20
4300 DROP TABLE QTEMP/T 01/07/20
4400 END-EXEC. 01/07/20
4600 EXEC SQL 01/07/20
4700 CREATE TABLE QTEMP/T 01/07/20
4800 (NAME CHAR (80), LASTNAME CHAR (80)) 01/07/20
4900 END-EXEC. 01/07/20
5100 EXEC SQL 01/07/20
5200 INSERT INTO QTEMP/T VALUES ("ALFRED", "HITCHCOCK") 01/07/20
5300 END-EXEC. 01/07/20
5500 01/07/20
5600 MOVE 'SELECT NAME, LASTNAME FROM QTEMP/T' TO WK-SELECT. 01/07/20
5700 21/03/08
5800 MOVE SPACES TO WK-WHERE. 01/07/20
5900 MOVE 0 TO SQLN. 01/07/20
6000 01/07/20
6100 IF LK-NAME NOT = SPACES 01/07/20
6200 STRING 'WHERE NAME LIKE ("%" CONCAT ' 01/07/20
6300 'TRIM(CAST(? AS CHAR(80))) CONCAT "%")' 01/07/20
6400 DELIMITED BY SIZE INTO WK-WHERE 01/07/20
6500 ADD 1 TO SQLN 01/07/20
6600 END-IF. 01/07/20
6700 28/04/08
6800 STRING WK-SELECT DELIMITED BY SIZE 01/07/20
6900 ' ' DELIMITED BY SIZE 01/07/20
7000 WK-WHERE DELIMITED BY ' ' INTO WK-STATEMENT 01/07/20
7100 END-STRING. 21/04/08
7200 30/06/20
7300 EXEC SQL 30/06/20
7400 PREPARE STMT FROM :WK-STATEMENT 01/07/20
7500 END-EXEC. 30/06/20
7700 EXEC SQL 30/06/20
7800 DESCRIBE INPUT STMT INTO :SQLDA 01/07/20
7900 END-EXEC. 30/06/20
8100 21/04/08
8200 *--- Setting values for SQLDA. 01/07/20
8300 IF LK-NAME NOT = SPACES 01/07/20
8400 SET SQLDATA(1) TO ADDRESS OF LK-NAME 01/07/20
8500 END-IF. 01/07/20
8600 30/06/20
8700 EXEC SQL 21/04/08
8800 DECLARE SQL_LIST CURSOR FOR STMT 01/07/20
8900 END-EXEC. 21/04/08
9000 21/04/08
9100 EXEC SQL 21/04/08
9200 OPEN SQL_LIST 01/07/20
9300 END-EXEC. 21/04/08
9500 21/04/08
9600 A01-FETCH. 01/07/20
9700 EXEC SQL 01/07/20
9800 FETCH NEXT FROM SQL_LIST INTO :WK-NAME, :WK-LASTNAME 01/07/20
9900 END-EXEC. 01/07/20
10100 IF SQLCODE NOT = 0 01/07/20
10200 GO TO A01-CLOSE 01/07/20
10300 END-IF. 01/07/20
10400 01/07/20
10500 *--- Do some stuff with the fetched data, then fetch next row. 01/07/20
10600 GO TO A01-FETCH. 01/07/20
10700 21/04/08
10800 A01-CLOSE. 01/07/20
10900 EXEC SQL 13/02/20
11000 CLOSE SQL_LIST 01/07/20
11100 END-EXEC. 13/02/20
11300 13/02/20
11400 A01-END. 01/07/20
11500 GOBACK. 01/07/20不幸的是,当我运行程序时(将一个vAlue给LK-NAME,而不是空白),OPEN语句返回一个SQLCODE-313( EXECUTE或OPEN语句中指定的主机变量的数量与出现在准备好的SQL语句中的参数标记数(问号)不一样)。在我看来,主机变量和参数标记的数量都是1,那么问题在哪里呢?
编辑
按照Charles的建议,第9200行改为
OPEN SQL_LIST USING DESCRIPTOR :SQLDA这现在给出了SQLCODE-822。
编辑2
经过进一步的研究,我了解到每个主机变量必须与链接部分中的指示变量相关联,而SQLIND的出现必须与这些指示变量的地址相关联。谢谢查尔斯
发布于 2020-07-01 21:29:50
了解这个平台会有帮助。
但是,我希望看到您打算在open语句中在参数生成器中使用的变量。
EXEC SQL
OPEN SQL_LIST USING :LK-NAME
END-EXEC.open语句是替换参数标记的值被替换的地方。
尽管如此,您可能希望考虑静态SQL,而不是动态SQL。
静态SQL不需要准备.看起来就像
EXEC SQL
DECLARE SQL_LIST CURSOR FOR
SELECT NAME, LASTNAME FROM QTEMP/T
WHERE :LK-NAME = ' '
OR NAME LIKE ( '%' CONCAT TRIM(:LK-NAME) CONCAT '%')
END-EXEC.
EXEC SQL
OPEN SQL_LIST
END-EXEC.注意,即使在这里,在游标打开时,LK-NAME的值也是传入的,DECLARE CURSOR实际上是一个编译时语句。
编辑
您可以使用描述符区域,如果这种情况下,open将根据文档指定OPEN…USING DESCRIPTOR descriptor-name。我从来没有那样做过。
您已经阅读过嵌入式SQL编程手册,对吗?
是的,通常静态语句更快。与动态版本相比,只要它不太复杂。
https://stackoverflow.com/questions/62684801
复制相似问题