Embedded SQL in RPG (specifically ILE RPG) allows you to seamlessly integrate SQL statements directly within your RPG programs. This enables your programs to interact with the database for tasks like retrieving, inserting, updating, and deleting data. Here's a comprehensive guide:
1. Setting up your RPG program:
EXEC SQL preprocessor.**FREE // For free-form RPG
CTL-OPT BNDDIR('QC2LE'); // Bind directory for SQL services
/COPY QSYSINC/SQLC // Include SQL definitions (important!)?
2. Embedding SQL Statements :
You embed SQL statements within your RPG code using the EXEC SQL keywords .
EXEC SQL SELECT * FROM CUSTOMERS;
EXEC SQL INSERT INTO ORDERS (CustNo, OrderDate) VALUES (:CustNo, :OrderDate);
* Host Variables : To pass data between your RPG program and the SQL statements, you use host variables. These are RPG variables preceded by a colon (:) in the SQL statement. They act as placeholders for data.
DCL-S CustNo INT(10);
DCL-S CustName CHAR(20);
DCL-S OrderDate D;
EXEC SQL SELECT CustName INTO :CustName FROM CUSTOMERS WHERE CustNo = :CustNo;
3. Handling SQL Results:
INTO clause in a SELECT statement specifies the host variables where the retrieved data will be stored.DCL-S CustName CHAR(20);
DCL-S CustNameInd INT(5); // Indicator variable
EXEC SQL SELECT CustName INTO :CustName :CustNameInd FROM CUSTOMERS WHERE CustNo = :CustNo;
IF CustNameInd < 0;
// CustName is null
ELSE;
// CustName has a value
ENDIF;?
* SQLCA (SQL Communication Area): The SQLCA is a structure that contains information about the execution of SQL statements, including error codes. It's essential for error handling.
DCL-S SQLCA SQLCA; // Include the SQLCA
EXEC SQL SELECT * FROM CUSTOMERS;
IF SQLCA.SQLCODE <> 0;
// Handle the error (SQLCA.SQLCODE contains the error code)
Dsply ('SQL Error: ' + %char(SQLCA.SQLCODE));
ENDIF;
4. Working with Multiple Rows (Cursors):
If your SELECT statement can return multiple rows, you need to use a cursor.
// Declare the cursor
EXEC SQL DECLARE CustCursor CURSOR FOR SELECT * FROM CUSTOMERS;
// Open the cursor
EXEC SQL OPEN CustCursor;
// Fetch rows from the cursor in a loop
DOWHILE SQLCA.SQLCODE = 0;
EXEC SQL FETCH CustCursor INTO :CustNo, :CustName;
IF SQLCA.SQLCODE = 0; // Check after each fetch
// Process the retrieved data
Dsply (CustName);
ENDIF;
ENDDO;
// Close the cursor
EXEC SQL CLOSE CustCursor;
5. Dynamic SQL:
For more flexibility, you can use dynamic SQL, where the SQL statements are built at runtime.
DCL-S SqlStmt VARCHAR(200);
SqlStmt = 'SELECT * FROM ' + TableName; // Build the SQL statement
EXEC SQL PREPARE MyStmt FROM :SqlStmt;
EXEC SQL EXECUTE MyStmt;
6. Error Handling:
Always check the SQLCA.SQLCODE after each SQL statement to handle potential errors.
7. Examples:
EXEC SQL INSERT INTO ORDERS (CustNo, OrderDate, OrderAmt) VALUES (:CustNo, :OrderDate, :OrderAmt);
IF SQLCA.SQLCODE <> 0;
// Handle insert error
ENDIF;
EXEC SQL UPDATE CUSTOMERS SET CustName = :NewName WHERE CustNo = :CustNo;
IF SQLCA.SQLCODE <> 0;
// Handle update error
ENDIF;
Key Considerations :
EXEC SQL statements are processed by a preprocessor before the RPG compiler runs.Embedded SQL is a crucial technique for integrating database access into your RPG programs. By mastering its use, you can create powerful applications that leverage the full capabilities of DB2 for i.