DRDA/DB2 Examples
DRDA/DB2 Examples
Practical examples for HeliosDB’s IBM DB2 DRDA protocol support.
Connection Examples
DB2 CLP
# Catalog remote databasedb2 catalog tcpip node HELIOS remote localhost server 50000db2 catalog database heliosdb at node HELIOS
# Connectdb2 connect to heliosdb user admin using password
# Execute querydb2 "SELECT * FROM employees FETCH FIRST 10 ROWS ONLY"
# Disconnectdb2 terminateJDBC (Java)
import java.sql.*;
public class DB2Example { public static void main(String[] args) throws Exception { String url = "jdbc:db2://localhost:50000/heliosdb"; Connection conn = DriverManager.getConnection( url, "admin", "password" );
Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT * FROM employees FETCH FIRST 10 ROWS ONLY" );
while (rs.next()) { System.out.println(rs.getString("name")); }
conn.close(); }}Python (ibm_db)
import ibm_db
conn_str = ( "DATABASE=heliosdb;" "HOSTNAME=localhost;" "PORT=50000;" "PROTOCOL=TCPIP;" "UID=admin;" "PWD=password;")
conn = ibm_db.connect(conn_str, "", "")
stmt = ibm_db.exec_immediate( conn, "SELECT * FROM employees FETCH FIRST 10 ROWS ONLY")
while ibm_db.fetch_row(stmt): name = ibm_db.result(stmt, "name") print(name)
ibm_db.close(conn)Query Examples
FETCH FIRST Pagination
-- First 10 rowsSELECT * FROM employeesFETCH FIRST 10 ROWS ONLY;
-- With OFFSETSELECT * FROM employeesORDER BY emp_idOFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
-- FETCH with TIESSELECT * FROM employeesORDER BY salary DESCFETCH FIRST 5 ROWS WITH TIES;Isolation Levels
-- Uncommitted read (dirty read allowed)SELECT * FROM employees WITH UR;
-- Cursor stability (default)SELECT * FROM employees WITH CS;
-- Read stabilitySELECT * FROM employees WITH RS;
-- Repeatable read (serializable)SELECT * FROM employees WITH RR;Common Table Expressions
-- Basic CTEWITH dept_counts AS ( SELECT department_id, COUNT(*) as emp_count FROM employees GROUP BY department_id)SELECT d.name, dc.emp_countFROM departments dJOIN dept_counts dc ON d.id = dc.department_id;Recursive CTE
-- Employee hierarchyWITH RECURSIVE emp_hierarchy (emp_id, name, manager_id, level) AS ( -- Base case: top-level managers SELECT emp_id, name, manager_id, 1 FROM employees WHERE manager_id IS NULL
UNION ALL
-- Recursive case: employees under managers SELECT e.emp_id, e.name, e.manager_id, h.level + 1 FROM employees e JOIN emp_hierarchy h ON e.manager_id = h.emp_id)SELECT * FROM emp_hierarchyORDER BY level, name;OLAP Functions
-- Running total by departmentSELECT emp_id, name, department_id, salary, SUM(salary) OVER ( PARTITION BY department_id ORDER BY emp_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) as running_totalFROM employees;
-- RankingSELECT emp_id, name, salary, RANK() OVER (ORDER BY salary DESC) as salary_rank, DENSE_RANK() OVER (ORDER BY salary DESC) as dense_rank, ROW_NUMBER() OVER (ORDER BY salary DESC) as row_numFROM employees;
-- Lag and LeadSELECT emp_id, name, salary, LAG(salary, 1) OVER (ORDER BY emp_id) as prev_salary, LEAD(salary, 1) OVER (ORDER BY emp_id) as next_salaryFROM employees;MERGE Statement
-- Upsert patternMERGE INTO employees tUSING (VALUES (100, 'John Smith', 75000)) AS s(emp_id, name, salary)ON t.emp_id = s.emp_idWHEN MATCHED THEN UPDATE SET name = s.name, salary = s.salaryWHEN NOT MATCHED THEN INSERT (emp_id, name, salary) VALUES (s.emp_id, s.name, s.salary);Array Functions
-- LISTAGG for string aggregationSELECT department_id, LISTAGG(name, ', ') WITHIN GROUP (ORDER BY name) as employeesFROM employeesGROUP BY department_id;Stored Procedures
Create Procedure
CREATE PROCEDURE get_employees_by_dept( IN p_dept_id INTEGER, OUT p_count INTEGER)LANGUAGE SQLBEGIN DECLARE v_count INTEGER;
SELECT COUNT(*) INTO v_count FROM employees WHERE department_id = p_dept_id;
SET p_count = v_count;END;Procedure with Result Set
CREATE PROCEDURE get_high_earners( IN p_min_salary DECIMAL(10,2))LANGUAGE SQLDYNAMIC RESULT SETS 1BEGIN DECLARE c1 CURSOR WITH RETURN FOR SELECT emp_id, name, salary FROM employees WHERE salary >= p_min_salary ORDER BY salary DESC;
OPEN c1;END;Call Procedure
// JDBC procedure callCallableStatement cs = conn.prepareCall("{CALL get_employees_by_dept(?, ?)}");cs.setInt(1, 10); // department_idcs.registerOutParameter(2, Types.INTEGER); // count
cs.execute();
int count = cs.getInt(2);System.out.println("Employee count: " + count);Triggers
BEFORE INSERT Trigger
CREATE TRIGGER emp_before_insertBEFORE INSERT ON employeesREFERENCING NEW AS nFOR EACH ROWBEGIN ATOMIC SET n.created_at = CURRENT TIMESTAMP; SET n.updated_at = CURRENT TIMESTAMP;END;AFTER UPDATE Trigger
CREATE TRIGGER emp_audit_updateAFTER UPDATE ON employeesREFERENCING OLD AS o NEW AS nFOR EACH ROWBEGIN ATOMIC INSERT INTO employee_audit ( emp_id, field_changed, old_value, new_value, changed_at ) VALUES ( n.emp_id, 'salary', CAST(o.salary AS VARCHAR(20)), CAST(n.salary AS VARCHAR(20)), CURRENT TIMESTAMP );END;Transaction Examples
Savepoints
-- Start transactionBEGIN;
INSERT INTO accounts (id, balance) VALUES (1, 1000);SAVEPOINT sp1;
INSERT INTO accounts (id, balance) VALUES (2, 500);SAVEPOINT sp2;
-- Rollback to sp2ROLLBACK TO SAVEPOINT sp2;
-- Commit transactionCOMMIT;Transaction with Java
conn.setAutoCommit(false);
try { Statement stmt = conn.createStatement();
stmt.executeUpdate("UPDATE accounts SET balance = balance - 100 WHERE id = 1"); Savepoint sp = conn.setSavepoint("transfer_start");
stmt.executeUpdate("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
// Verify balances ResultSet rs = stmt.executeQuery( "SELECT balance FROM accounts WHERE id = 1" ); if (rs.next() && rs.getDouble("balance") < 0) { conn.rollback(sp); throw new Exception("Insufficient funds"); }
conn.commit();} catch (Exception e) { conn.rollback(); throw e;}Bulk Operations
Batch Insert (JDBC)
PreparedStatement ps = conn.prepareStatement( "INSERT INTO employees (name, department_id, salary) VALUES (?, ?, ?)");
for (Employee emp : employees) { ps.setString(1, emp.getName()); ps.setInt(2, emp.getDeptId()); ps.setDouble(3, emp.getSalary()); ps.addBatch();}
int[] results = ps.executeBatch();conn.commit();LOAD Utility
-- Insert from valuesINSERT INTO employees (name, department_id, salary)VALUES ('Alice', 1, 50000), ('Bob', 2, 60000), ('Charlie', 1, 55000);Date/Time Examples
Date Arithmetic
-- Add daysSELECT hire_date + 30 DAYS as review_dateFROM employees;
-- Add monthsSELECT hire_date + 3 MONTHS as probation_endFROM employees;
-- Date differenceSELECT DAYS(CURRENT DATE) - DAYS(hire_date) as days_employedFROM employees;
-- Timestamp differenceSELECT TIMESTAMPDIFF(2, CHAR(CURRENT TIMESTAMP - hire_timestamp)) as hours_employedFROM employees;Date Formatting
-- Format dateSELECT emp_id, VARCHAR_FORMAT(hire_date, 'YYYY-MM-DD') as formatted_date, VARCHAR_FORMAT(hire_timestamp, 'YYYY-MM-DD HH24:MI:SS') as formatted_tsFROM employees;Query Optimization
OPTIMIZE FOR
-- Optimize for specific row countSELECT * FROM employeesWHERE department_id = 10OPTIMIZE FOR 100 ROWS;Explain Plan
-- Get execution planEXPLAIN PLAN FORSELECT * FROM employeesWHERE department_id = 10;Index Usage
-- Create indexCREATE INDEX idx_emp_dept ON employees (department_id);
-- Query using indexSELECT * FROM employeesWHERE department_id = 10;Python with SQLAlchemy
from sqlalchemy import create_engine, textfrom sqlalchemy.orm import sessionmaker
# Create engineengine = create_engine( 'db2+ibm_db://admin:password@localhost:50000/heliosdb')
Session = sessionmaker(bind=engine)session = Session()
# Execute queryresult = session.execute(text( "SELECT * FROM employees FETCH FIRST 10 ROWS ONLY"))
for row in result: print(row)
session.close()Related: README.md | CONFIGURATION.md | COMPATIBILITY.md
Last Updated: December 2025