这是DB2官方文档给出的方案:
- Precompilation of embedded SQL applications that access more than one database server
To precompile an application program that accesses more than one server, you can
do one of the following tasks:
1. Split the SQL statements for each database into separate source files. Do not mix
SQL statements for different databases in the same file. Each source file can be
precompiled against the appropriate database. This is the recommended method.
2. Code your application using dynamic SQL statements only, and bind against
each database your program will access.
3. If all the databases look the same, that is, they have the same definition, you can
group the SQL statements together into one source file.
The same procedures apply if your application will access a host application server
through DB2 Connect. Precompile it against the server to which it will be
connecting, using the PREP options available for that server.
下面是一个例子如何一个COBOL程序访问多个DB2数据库,用到的是SET CONNECTION
语句:
代码如下:
$ cat SAMPLE.sqb
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 DBNAME PIC X(008).
01 DBUSER PIC X(010).
01 DBPASS PIC X(010).
01 DBNAME2 PIC X(008).
01 DBUSER2 PIC X(010).
01 DBPASS2 PIC X(010).
01 H-HOST-VARIABLE.
02 H-S-VALUE PIC X(10).
EXEC SQL END DECLARE SECTION END-EXEC.
EXEC SQL INCLUDE SQLCA END-EXEC.
PROCEDURE DIVISION.
BEGIN-PGM.
DISPLAY "ENTRY OF SAMPLE".
DISPLAY "DB2NAME" UPON ENVIRONMENT-NAME.
ACCEPT DBNAME FROM ENVIRONMENT-VALUE.
DISPLAY "DB2USER" UPON ENVIRONMENT-NAME.
ACCEPT DBUSER FROM ENVIRONMENT-VALUE.
DISPLAY "DB2PASS" UPON ENVIRONMENT-NAME.
ACCEPT DBPASS FROM ENVIRONMENT-VALUE.
DISPLAY "DB2NAME2" UPON ENVIRONMENT-NAME.
ACCEPT DBNAME2 FROM ENVIRONMENT-VALUE.
DISPLAY "DB2USER2" UPON ENVIRONMENT-NAME.
ACCEPT DBUSER2 FROM ENVIRONMENT-VALUE.
DISPLAY "DB2PASS2" UPON ENVIRONMENT-NAME.
ACCEPT DBPASS2 FROM ENVIRONMENT-VALUE.
* * CREATE 2 DATABASE CONNECTIONS
EXEC SQL
CONNECT TO :DBNAME USER :DBUSER USING :DBPASS
END-EXEC.
DISPLAY "CONNECTED TO DATABASE ", DBNAME,
" SQLCODE: ", SQLCODE OF SQLCA.
EXEC SQL
CONNECT TO :DBNAME2 USER :DBUSER2 USING :DBPASS2
END-EXEC.
DISPLAY "CONNECTED TO DATABASE ", DBNAME2,
" SQLCODE: ", SQLCODE OF SQLCA.
* * SELECT FROM DATABASE CONNECTION1
EXEC SQL
SET CONNECTION :DBNAME
END-EXEC.
DISPLAY "SET CONNECT TO DATABASE ", DBNAME,
" SQLCODE: ", SQLCODE OF SQLCA.
EXEC SQL
SELECT B
INTO :H-S-VALUE
FROM TESTTAB
END-EXEC.
DISPLAY "SELECT FROM DATABASE ", DBNAME,
" SQLCODE: ", SQLCODE OF SQLCA,
" VALUE: ", H-S-VALUE.
EXEC SQL COMMIT END-EXEC.
* * SELECT FROM DATABASE CONNECTION2
EXEC SQL
SET CONNECTION :DBNAME2
END-EXEC.
DISPLAY "SET CONNECT TO DATABASE ", DBNAME2,
" SQLCODE: ", SQLCODE OF SQLCA.
EXEC SQL
SELECT B
INTO :H-S-VALUE
FROM TESTTAB
END-EXEC.
DISPLAY "SELECT FROM DATABASE ", DBNAME2,
" SQLCODE: ", SQLCODE OF SQLCA,
" VALUE: ", H-S-VALUE.
EXEC SQL COMMIT END-EXEC.
* * DISCONNECT FROM DATABASE
EXEC SQL
DISCONNECT :DBNAME
END-EXEC.
DISPLAY "DISCONNECT FROM DATABASE ", DBNAME,
" SQLCODE: ", SQLCODE OF SQLCA.
EXEC SQL
DISCONNECT :DBNAME2
END-EXEC.
DISPLAY "DISCONNECT FROM DATABASE ", DBNAME2,
" SQLCODE: ", SQLCODE OF SQLCA.
STOP RUN.
makefile
$ cat makefile
all: SAMPLE SAMPLE.gnt
.SUFFIXES: .sqb .cbl .gnt
.PRECIOUS: %.cbl
SAMPLE: SAMPLE.cbl
cob -x -o SAMPLE SAMPLE.cbl -L$(DB2DIR)/lib64 -ldb2 -ldb2gmf -lstdc++
@echo ".cbl->.exe Done"
.sqb.cbl:
db2 connect to $(DB2NAME) user $(DB2USER) using $(DB2USER)
db2 prep '$*.sqb' BINDFILE PACKAGE USING '$(notdir $<)' CONNECT 2 VERSION $(firstword $(shell echo `uname -n`:$(CURDIR)/'$<'|md5sum ))
db2 bind '$*.bnd'
db2 connect to $(DB2NAME2) user $(DB2USER2) using $(DB2USER2)
db2 bind '$*.bnd'
@echo ".sqb->.cbl Done"
clean:
-rm -rf c *.lst *.lis *.int *.idy *.so *.gnt *.o *.bnd *.cbl core.* SAMPLE
有两点需要注意:
- 预处理的时候(db2 prep)需要指定database connect类型为2,请google 类型1和类型2的区别。
- bind的时候需要bind到两个DB2数据库,所以这种模式就有一个要求:
2.1 两个DB2数据库必须结构一样,否则bind就不会成功。
网友评论