Reputation: 2527
follow up to very large fields in As400 ISeries database ...
I want to build a large string in RPG and write it out to DDL CLOB field.
However even if I use a CLOB field in RPG code and a DDL CLOB field, I seem to be limited to 65531 characters, because data passes through an interim string value call 'wkClob_data'. Can I get over this limitation? maybe using a User Space?? [Still on V5R4]
DDL:
CREATE TABLE MYLIB/MYFILE
(MYDEC DEC (5) NOT NULL WITH DEFAULT,
MYCHAR CHAR (30) NOT NULL WITH DEFAULT,
MYCLOB CLOB (100000) ALLOCATE(1000) NOT NULL WITH DEFAULT)
RPG:
D wkValue S 65530a varying
D wkClob S sqltype(CLOB:65530)
// file up wkClob_data with a big string..
Eval wkClob_data = someData + %trim(moreData);
Eval wkClob_len = %len(%trim(someData + %trim(moreData)));
exec SQL
INSERT INTO MYFILE (MYDEC, MYCHAR, MYCLOB)
VALUES (123, 'Some Description',:wkClob);
Upvotes: 0
Views: 2961
Reputation: 11473
According to the v5.4 Knowledge Center you have two options for fields bigger than a valid host variable.
With the Locator field, DB2 returns a handle to the Large Object (LOB), and the data stays on the server. SQL statements can be used to substring or search the LOB into other host variables. Examples exist in the Knowledge center for C and COBOL, but the embedded SQL should remain the same for RPG.
Here is the Locator example from the Knowledge center translated to RPG IV
dcl-s empnum Char(6);
dcl-s resume SqlType(clob_locator);
dcl-s lobind Int(5);
dcl-s di_buffer SqlType(clob_locator);
dcl-s buffer SqlType(clob: 1024);
dcl-s di_begin_loc Int(20);
dcl-s di_end_loc Int(20);
dcl-proc lobloc;
exec sql
declare C1 cursor for
select empno, resume
from emp_resume
where resume_format = 'ascii'
and empno <> 'A00130';
exec sql open C1;
buffer_len = 0;
dow 1=1;
exec sql fetch C1 into :empnum, :resume :lobind;
if sqlcode <> 0;
// error, warning, or no data
leave;
endif;
if lobind < 0;
// LOB value is null
iter;
endif;
// Find the "Department Information" section
exec sql
values (posstr(:resume, 'Department Information'))
into :di_begin_loc;
// Find the "Education" section
exec sql
values (posstr(:resume, 'Education'))
into :di_end_loc;
// Get the Department information only into a new LOB
exec sql
values (substr(:resume, :di_begin_loc, :di_end_loc - :di_begin_loc))
into :di_buffer;
// Append the department info into a new CLOB field
exec sql
values (:buffer || :di_buffer) into :buffer;
enddo;
exec sql free locator :resume, :di_buffer;
return;
end-proc;
Note you can insert or update LOB fields using a locator as well as the select shown.
With the File field, DB2 transfers the contents of the LOB to or from a file in the IFS. Stream file API's can be used to read or write the file. There is an example similar to the locator example for LOB Files in the Knowledge Center.
Upvotes: 0
Reputation: 23793
Where's the data coming from?
Does it really have to go through an RPG program? C/C++ are also available on the IBM i. A hammer is always the right tool, not everything is a nail.
If you're stuck with RPG, the following might work...
D wkValue S 65530a varying
D wkClob1 S sqltype(CLOB:65530)
D wkClob2 S sqltype(CLOB:65530)
//<snip>
exec SQL
INSERT INTO MYFILE (MYDEC, MYCHAR, MYCLOB)
VALUES (123, 'Some Description',:wkClob1 CONCAT :wkClob2);
But honestly, the right way would probably be to take advantage of the SQL call level interface (SQL CLI) directly.
The Who Knew You Could Do That with RPG IV? Redbook has some code information about using CLI from RPG.
Upvotes: 2
Reputation: 5651
I'm guessing what I might try in SQLRPGLE before I gave up and made a java class that I could call from RPG.
exec SQL
INSERT INTO MYFILE (MYDEC, MYCHAR, MYCLOB)
VALUES (123, 'Some Description',:wkClob || :wkclob1 || :wkclob2);
exec SQL
update myfile set substring(myclob:32323412:11) = 'Hello World';
Upvotes: 1