|
| 1 | +-- @version v3.1.0 |
| 2 | +-- repl_execute: SQL stored procedure for notebook integration |
| 3 | +-- |
| 4 | +-- This is self-contained. No external procedure registration needed. |
| 5 | +-- The RPG program REPLEXEC is called via QCMDEXC. |
| 6 | + |
| 7 | +CREATE OR REPLACE PROCEDURE repl_execute ( |
| 8 | + IN P_SOURCE CLOB(256K) CCSID 1208, |
| 9 | + IN P_SESSION_ID VARCHAR(28) |
| 10 | +) |
| 11 | +DYNAMIC RESULT SETS 1 |
| 12 | +LANGUAGE SQL |
| 13 | +SET OPTION COMMIT = *NONE |
| 14 | + |
| 15 | +BEGIN |
| 16 | + DECLARE v_snippetName CHAR(20) CCSID 37; |
| 17 | + DECLARE v_lineNum INT DEFAULT 1; |
| 18 | + DECLARE v_pos INT DEFAULT 1; |
| 19 | + DECLARE v_nextPos INT; |
| 20 | + DECLARE v_line VARCHAR(200) CCSID 37; |
| 21 | + DECLARE v_sourceLen INT; |
| 22 | + DECLARE v_cmd VARCHAR(200) CCSID 37; |
| 23 | + DECLARE v_source CLOB(256K) CCSID 37; |
| 24 | + DECLARE c_LF CHAR(1) CCSID 37 DEFAULT x'25'; |
| 25 | + |
| 26 | + -- Convert UTF-8 input to EBCDIC for table operations |
| 27 | + SET v_source = CAST(P_SOURCE AS CLOB(256K) CCSID 37); |
| 28 | + SET v_snippetName = LEFT(CAST(P_SESSION_ID AS VARCHAR(28) CCSID 37), 20); |
| 29 | + SET v_sourceLen = LENGTH(v_source); |
| 30 | + |
| 31 | + -- Clear previous source for this snippet |
| 32 | + DELETE FROM replsrc WHERE save_name = v_snippetName; |
| 33 | + |
| 34 | + -- Parse source into lines (split on EBCDIC LF x'25') |
| 35 | + IF v_sourceLen > 0 THEN |
| 36 | + WHILE v_pos <= v_sourceLen DO |
| 37 | + SET v_nextPos = LOCATE(c_LF, v_source, v_pos); |
| 38 | + |
| 39 | + IF v_nextPos = 0 THEN |
| 40 | + -- Last line (no trailing newline) |
| 41 | + SET v_line = CAST(SUBSTRING(v_source, v_pos, v_sourceLen - v_pos + 1) AS VARCHAR(200)); |
| 42 | + SET v_pos = v_sourceLen + 1; |
| 43 | + ELSE |
| 44 | + IF v_nextPos > v_pos THEN |
| 45 | + SET v_line = CAST(SUBSTRING(v_source, v_pos, v_nextPos - v_pos) AS VARCHAR(200)); |
| 46 | + ELSE |
| 47 | + SET v_line = ''; |
| 48 | + END IF; |
| 49 | + SET v_pos = v_nextPos + 1; |
| 50 | + END IF; |
| 51 | + |
| 52 | + -- Strip trailing CR if present (handles CRLF) |
| 53 | + IF LENGTH(v_line) > 0 |
| 54 | + AND SUBSTRING(v_line, LENGTH(v_line), 1) = x'0D' THEN |
| 55 | + SET v_line = LEFT(v_line, LENGTH(v_line) - 1); |
| 56 | + END IF; |
| 57 | + |
| 58 | + INSERT INTO replsrc |
| 59 | + (session_id, line_number, code, save_name, owner, source_type) |
| 60 | + VALUES |
| 61 | + ('', v_lineNum, v_line, v_snippetName, |
| 62 | + CURRENT_USER, 'mainline'); |
| 63 | + |
| 64 | + SET v_lineNum = v_lineNum + 1; |
| 65 | + END WHILE; |
| 66 | + END IF; |
| 67 | + |
| 68 | + -- Call RPG pipeline runner via QCMDEXC (no procedure registration needed) |
| 69 | + SET v_cmd = 'CALL PGM(REPLEXEC) PARM(''' || REPLACE(v_snippetName, '''', '''''') || ''')'; |
| 70 | + CALL QSYS2.QCMDEXC(v_cmd); |
| 71 | + |
| 72 | + -- Tag results with external session ID |
| 73 | + UPDATE replrslt SET external_session_id = P_SESSION_ID |
| 74 | + WHERE session_id = (QSYS2.JOB_NAME) |
| 75 | + AND (external_session_id IS NULL OR external_session_id = ''); |
| 76 | + |
| 77 | + -- Return results |
| 78 | + BEGIN |
| 79 | + DECLARE c_results CURSOR WITH RETURN FOR |
| 80 | + SELECT line_number, result_number, result_description, loop_count, result_type |
| 81 | + FROM replrslt |
| 82 | + WHERE external_session_id = P_SESSION_ID |
| 83 | + ORDER BY line_number, result_number; |
| 84 | + |
| 85 | + OPEN c_results; |
| 86 | + END; |
| 87 | + |
| 88 | + -- Clean up source |
| 89 | + DELETE FROM replsrc WHERE save_name = v_snippetName; |
| 90 | +END; |
| 91 | + |
| 92 | +COMMENT ON PROCEDURE repl_execute IS |
| 93 | + 'Run RPG source through RPGLE-REPL and return results'; |
0 commit comments