如何在sql/cobol中使用参数标记

vawmfj5a  于 2021-07-29  发布在  Java
关注(0)|答案(1)|浏览(382)

我必须编写一个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

不幸的是,当我运行程序时(给lk name一个非空的值),open语句返回一个sqlcode-313(execute或open语句中指定的主机变量的数目与准备好的sql语句中出现的参数标记(问号)的数目不同。)在我看来,主机变量和参数标记的数目都是1,那么问题出在哪里呢?
编辑
根据查尔斯的建议,第9200行改为

OPEN SQL_LIST USING DESCRIPTOR :SQLDA

现在给出了sqlcode-822。
编辑2
经过进一步研究,我了解到每个主机变量必须与链接部分中的一个指标变量相关联,sqlind的出现必须与这些指标变量的地址相关联。谢谢@charles

js81xvg6

js81xvg61#

了解这个平台会很有帮助。。
但是,我希望在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编程手册,对吗?
是的,通常静态语句更快。只要和动态版本相比不太复杂。

相关问题