1
+ export const VALIDATOR_NAME = `VALIDATE_STATEMENT` ;
2
+ export const WRAPPER_NAME = `CHECKSTMTWRAPPED` ;
3
+ export const VALID_STATEMENT_LENGTH = 32740 ;
4
+ export const MAX_STATEMENT_COUNT = 200 ;
5
+
6
+ export function getValidatorSource ( schema : string , version : number ) {
7
+ return /*sql*/ `
8
+ create or replace procedure ${ schema } .${ WRAPPER_NAME } (
9
+ IN statementText char(${ VALID_STATEMENT_LENGTH } ) FOR SBCS DATA,
10
+ IN statementLength int,
11
+ IN recordsProvided int,
12
+ IN statementLanguage char(10),
13
+ IN options char(24),
14
+ OUT statementInfo char(1000),
15
+ IN statementInfoLength int,
16
+ OUT recordsProcessed int,
17
+ OUT errorCode char(1000)
18
+ )
19
+ LANGUAGE RPGLE
20
+ NOT DETERMINISTIC
21
+ MODIFIES SQL DATA
22
+ EXTERNAL NAME QSYS/QSQCHKS
23
+ PARAMETER STYLE GENERAL;
24
+
25
+ comment on procedure ${ schema } /${ WRAPPER_NAME } is '${ version } - QSQCHKS Wrapper';
26
+
27
+ create or replace function ${ schema } .${ VALIDATOR_NAME } (statementText char(${ VALID_STATEMENT_LENGTH } ) FOR SBCS DATA) --todo: support 1208 parms
28
+ returns table (
29
+ messageFileName char(10),
30
+ messageFileLibrary char(10),
31
+ numberOfStatementsBack int,
32
+ curStmtLength int,
33
+ errorFirstRecordNumber int,
34
+ errorFirstColumnNumber int,
35
+ errorLastRecordNumber int,
36
+ errorLastColumnNumber int,
37
+ errorSyntaxRecordNumber int,
38
+ errorSyntaxColumnNumber int,
39
+ errorSQLMessageID char(7),
40
+ errorSQLSTATE char(5),
41
+ errorReplacementText char(1000),
42
+ messageText char(132)
43
+ )
44
+ modifies sql data
45
+ begin
46
+ -- Variables required for parameters
47
+ declare stmtLength int default 0;
48
+ declare recordsProvided int default 1;
49
+ declare statementLanguage char(10) default '*NONE';
50
+ declare options char(24) default '000000000000000000000000';
51
+ declare statementInfo char(1000) for bit data default '';
52
+ declare statementInfoLength int default 1000;
53
+ declare recordsProcessed int default 0;
54
+ declare errorCode char(1000) default '';
55
+ --
56
+
57
+ -- Variables required for parsing the error list
58
+ declare messageFileName char(10);
59
+ declare messageFileLibrary char(10);
60
+ declare numberOfStatementsBack int default 0;
61
+ declare currentStatementIndex int default 0;
62
+
63
+ -- Variables for each error
64
+ declare errorOffset int default 25;
65
+ declare curStmtLength int default 0;
66
+ declare errorFirstRecordNumber int default 0;
67
+ declare errorFirstColumnNumber int default 0;
68
+ declare errorLastRecordNumber int default 0;
69
+ declare errorLastColumnNumber int default 0;
70
+ declare errorSyntaxRecordNumber int default 0;
71
+ declare errorSyntaxColumnNumber int default 0;
72
+ declare errorSQLMessageID char(7) default '';
73
+ declare errorSQLSTATE char(5) default '';
74
+ declare errorRepLen int default 0;
75
+ declare errorReplacementText char(1000) default '';
76
+ declare messageText char(132) default '';
77
+
78
+ set stmtLength = length(rtrim(statementText));
79
+ set options = x'00000001' concat x'00000001' concat x'0000000A' concat '*NONE '; --No naming convention
80
+ -- set options = x'00000001' concat x'00000008' concat x'00000004' concat x'000004B0'; -- ccsid
81
+
82
+ call ${ schema } .${ WRAPPER_NAME } ( statementText, stmtLength, recordsProvided, statementLanguage, options, statementInfo, statementInfoLength, recordsProcessed, errorCode);
83
+
84
+ -- set ${ schema } .outlog = statementInfo;
85
+ -- set ${ schema } .outlog = substr(statementInfo, 21, 4);
86
+
87
+ -- Parse the output
88
+ set messageFileName = rtrim(substr(statementInfo, 1, 10));
89
+ set messageFileLibrary = rtrim(substr(statementInfo, 11, 10));
90
+ set numberOfStatementsBack = interpret(substr(statementInfo, 21, 4) as int);
91
+ set errorOffset = 25;
92
+
93
+ while currentStatementIndex < numberOfStatementsBack do
94
+ set curStmtLength = interpret(substr(statementInfo, errorOffset, 4) as int);
95
+ set errorFirstRecordNumber = interpret(substr(statementInfo, errorOffset + 4, 4) as int);
96
+ set errorFirstColumnNumber = interpret(substr(statementInfo, errorOffset + 8, 4) as int);
97
+ set errorLastRecordNumber = interpret(substr(statementInfo, errorOffset + 12, 4) as int);
98
+ set errorLastColumnNumber = interpret(substr(statementInfo, errorOffset + 16, 4) as int);
99
+ set errorSyntaxRecordNumber = interpret(substr(statementInfo, errorOffset + 20, 4) as int);
100
+ set errorSyntaxColumnNumber = interpret(substr(statementInfo, errorOffset + 24, 4) as int);
101
+ set errorSQLMessageID = rtrim(substr(statementInfo, errorOffset + 28, 7));
102
+ set errorSQLSTATE = rtrim(substr(statementInfo, errorOffset + 35, 5));
103
+ set errorRepLen = interpret(substr(statementInfo, errorOffset + 40, 4) as int);
104
+ set errorReplacementText = rtrim(substr(statementInfo, errorOffset + 44, errorRepLen));
105
+
106
+ set errorOffset = errorOffset + 44 + errorRepLen;
107
+
108
+ set currentStatementIndex = currentStatementIndex + 1;
109
+
110
+ select message_text
111
+ into messageText
112
+ from table(qsys2.message_file_data(messageFileLibrary, messageFileName))
113
+ where message_id = errorSQLMessageID;
114
+
115
+ pipe (
116
+ messageFileName,
117
+ messageFileLibrary,
118
+ numberOfStatementsBack,
119
+ curStmtLength,
120
+ errorFirstRecordNumber,
121
+ errorFirstColumnNumber,
122
+ errorLastRecordNumber,
123
+ errorLastColumnNumber,
124
+ errorSyntaxRecordNumber,
125
+ errorSyntaxColumnNumber,
126
+ errorSQLMessageID,
127
+ errorSQLSTATE,
128
+ errorReplacementText,
129
+ messageText
130
+ );
131
+ end while;
132
+
133
+ return;
134
+ end;
135
+
136
+ comment on function ${ schema } /${ VALIDATOR_NAME } is '${ version } - SQL Syntax Checker';
137
+
138
+ --select *
139
+ --from table(${ schema } .validate_statement('select from sample.employee order by a')) x;
140
+ --
141
+ --select * from table(qsys2.message_file_data('QSYS', 'QSQLMSG'));
142
+ --
143
+ --values hex(substr(${ schema } .outlog, 21, 4));
144
+ --values interpret(hex(substr(${ schema } .outlog, 21, 4)) as int);
145
+ --values hex(1) concat hex(1) concat hex(10) concat '*NONE ';
146
+ --values length(x'000004B8');
147
+ --values hex(1200);
148
+ ` ;
149
+ }
0 commit comments