IDENTIFICATION DIVISION.
PROGRAM-ID. EXTXN01.
*
* InstantSQL Transaction Example 01.
*
*This example connects to the data
source named
*Bank.
It then executes a transfer transaction
*from a checking account to a savings
account.
*The transaction is committed only if it
is
*successful, otherwise it is rolled
back.
*
DATA DIVISION.
WORKING-STORAGE SECTION.
COPY "lisqlall.cpy".
01 WS-Handles.
05 WS-QryHandleReadCkg USAGE ISqlHandle.
05 WS-QryHandleUpdtCkg USAGE ISqlHandle.
05 WS-QryHandleUpdtSvg USAGE ISqlHandle.
01 WS-Account-Data.
05 WS-CkgAccountNo PIC 9(09).
*> checking acct number
05 WS-SvgAccountNo PIC 9(09).
*> savings acct number
05 WS-CkgBalance PIC S9(16)V9(2). *> checking balance
05 WS-SvgBalance PIC S9(16)V9(2). *> savings balance
05 WS-TrfAmount PIC S9(16)V9(2). *> transfer amount
05 WS-TxnFlag PIC X.
88 WS-TxnIsActive VALUE
"Y" FALSE "N".
05 WS-Timeout PIC S9(5) BINARY VALUE 20.
01 PBuf PIC X(80) VALUE SPACES.
01 P1 PIC S9(5) BINARY VALUE 0.
01 I PIC S9(5) BINARY VALUE 0.
78 ErrMsgContSize VALUE 50.
PROCEDURE DIVISION.
A.
*Initialize.
SET WS-TxnIsActive TO FALSE.
*Connect to data source named Bank.
SQL CONNECT DATASOURCE sql-ConnectionHandle
"Bank"
"MyName"
"MyPassword".
IF NOT sql-OK
DISPLAY "<Error
connecting to Bank data source.>"
PERFORM DescAndDisplaySqlError
STOP RUN
END-IF.
*Prepare query for verifying Checking
balance larger than
*transfer amount.
SQL PREPARE QUERY
WS-QryHandleReadCkg
sql-ConnectionHandle
"SELECT Balance FROM Checking
WHERE AccountNo = ?"
sql-Concur-Lock.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
SQL BIND COLUMN WS-QryHandleReadCkg
1 WS-CkgBalance OMITTED.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
SQL BIND PARAMETER
WS-QryHandleReadCkg
1 sql-Integer sql-Param-Input
WS-CkgAccountNo OMITTED.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
*Prepare queries for updating Checking
and Savings balances.
SQL PREPARE QUERY
WS-QryHandleUpdtCkg
sql-ConnectionHandle
"UPDATE Checking SET
Balance = ? WHERE AccountNo = ?".
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
SQL BIND PARAMETER
WS-QryHandleUpdtCkg
1 sql-Decimal sql-Param-Input
WS-CkgBalance OMITTED
2 sql-Integer sql-Param-Input
WS-CkgAccountNo OMITTED.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
SQL PREPARE QUERY
WS-QryHandleUpdtSvg
sql-ConnectionHandle
"UPDATE Savings SET
Balance = Balance + ?
-
"WHERE AccountNo = ?".
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
SQL BIND PARAMETER
WS-QryHandleUpdtSvg
1 sql-Decimal sql-Param-Input
WS-TrfAmount OMITTED
2 sql-Integer sql-Param-Input
WS-SvgAccountNo OMITTED.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
*Get account numbers and transfer amount.
MOVE 001346759 TO WS-CkgAccountNo.
MOVE 002478291 TO WS-SvgAccountNo.
MOVE 1000.00 TO WS-TrfAmount.
*Start transaction for transfer from
checking to savings.
SQL START TRANSACTION
sql-ConnectionHandle
sql-TXN-Repeatable-Read.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
SET WS-TxnIsActive TO TRUE.
*Read checking account balance.
SQL START QUERY WS-QryHandleReadCkg
WS-Timeout.
IF NOT sql-OK PERFORM TxnSqlError
END-IF.
SQL FETCH ROW WS-QryHandleReadCkg.
IF NOT sql-OK PERFORM TxnSqlError
END-IF.
*Verify transfer does not exceed
checking balance.
IF WS-TrfAmount > WS-CkgBalance
DISPLAY "Transaction failed:
insufficient funds."
PERFORM TxnCobolError
ELSE
*> Do transfer.
SUBTRACT WS-TrfAmount FROM
WS-CkgBalance
SQL START QUERY WS-QryHandleUpdtCkg
WS-Timeout
IF NOT sql-OK PERFORM TxnSqlError
END-IF
SQL START QUERY
WS-QryHandleUpdtSvg WS-Timeout
IF NOT sql-OK PERFORM TxnSqlError
END-IF
IF WS-TxnIsActive
SQL COMMIT TRANSACTION
sql-ConnectionHandle
SET WS-TxnIsActive TO FALSE
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF
DISPLAY "Transfer
completed."
END-IF
END-IF.
*End queries
SQL END QUERY WS-QryHandleUpdtSvg.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
SQL END QUERY WS-QryHandleUpdtCkg.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
SQL END QUERY WS-QryHandleReadCkg.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
*Disconnect from Bank data source.
SQL DISCONNECT DATASOURCE
sql-ConnectionHandle.
IF NOT sql-OK PERFORM
DescAndDisplaySqlError END-IF.
*Terminate InstantSQL and application
SQL SHUTDOWN.
STOP RUN.
TxnSqlError.
DISPLAY "Transaction failed:
SQL error or account busy."
PERFORM DescAndDisplaySqlError.
PERFORM TxnCobolError.
TxnCobolError.
IF WS-TxnIsActive PERFORM RollBackTxn END-IF.
RollBackTxn.
DISPLAY "Rolling back
transaction.".
SQL ROLLBACK TRANSACTION
sql-ConnectionHandle.
SET WS-TxnIsActive TO FALSE.
IF NOT sql-OK PERFORM DescAndDisplaySqlError
END-IF.
DescAndDisplaySqlError.
PERFORM WITH TEST AFTER UNTIL
sql-EndOfData
SQL DESCRIBE ERROR
sql-Error-Description
IF NOT sql-OK
IF sql-EndOfData
DISPLAY "--->End of
error list."
ELSE
DISPLAY "Error
describing error: " sql-Return
CONVERT
ELSE
PERFORM DisplayErrorDesc
END-IF
END-PERFORM.
STOP "*** Transfer error
occurred. ***".
DisplayErrorDesc.
STRING " Error type = " sql-ErrType
DELIMITED SIZE INTO PBuf
POINTER P1.
EVALUATE TRUE
WHEN sql-IsOdbcError
STRING " (ODBC error)"
DELIMITED SIZE INTO PBuf
POINTER P1
WHEN sql-IsInternalError
STRING " (internal error)"
DELIMITED SIZE INTO PBuf
POINTER P1
WHEN OTHER
STRING " (unknown error type)"
DELIMITED SIZE INTO PBuf POINTER P1
END-EVALUATE.
PERFORM OutputPBuf.
STRING " Error statement = " sql-ErrStatement
DELIMITED SIZE INTO PBuf
POINTER P1.
PERFORM OutputPBuf.
STRING " Error
SQL state = " sql-ErrSqlState
DELIMITED SIZE INTO PBuf
POINTER P1.
PERFORM OutputPBuf.
STRING " Error number = " sql-ErrNo(3:)
DELIMITED SIZE INTO PBuf
POINTER P1.
PERFORM OutputPBuf.
STRING " Error msg len = " sql-ErrMsgLength(2:)
DELIMITED SIZE INTO PBuf
POINTER P1.
PERFORM OutputPBuf.
STRING " Error message = """
DELIMITED SIZE INTO PBuf
POINTER P1.
IF sql-ErrMsgLength > 0
IF sql-ErrMsgLength <=
ErrMsgContSize
STRING sql-ErrMsg(1:
sql-ErrMsgLength)
DELIMITED SIZE INTO PBuf
POINTER P1
ELSE
STRING sql-ErrMsg(1: ErrMsgContSize)
DELIMITED SIZE INTO PBuf
POINTER P1
END-IF
SUBTRACT ErrMsgContSize FROM
sql-ErrMsgLength
ADD ErrMsgContSize 1 GIVING I
PERFORM VARYING I FROM I BY
ErrMsgContSize
UNTIL sql-ErrMsgLength
<= 0
PERFORM OutputPBuf
STRING " "
DELIMITED SIZE INTO PBuf
POINTER P1
IF sql-ErrMsgLength <=
ErrMsgContSize
STRING sql-ErrMsg(I:
sql-ErrMsgLength)
DELIMITED SIZE INTO PBuf
POINTER P1
ELSE
STRING sql-ErrMsg(I:
ErrMsgContSize)
DELIMITED SIZE INTO PBuf
POINTER P1
END-IF
SUBTRACT ErrMsgContSize FROM
sql-ErrMsgLength
END-PERFORM
END-IF.
STRING """"
DELIMITED SIZE INTO PBuf POINTER P1
PERFORM OutputPBuf.
OutputPBuf.
DISPLAY PBuf.
MOVE SPACES TO PBuf.
MOVE 1 TO P1.
END PROGRAM EXTXN01.