Skip to content

Instantly share code, notes, and snippets.

@dancarlosgabriel
Forked from BirgittaHauser/BLOBPDF.SQLRPGLE
Created August 25, 2023 23:29
Show Gist options
  • Save dancarlosgabriel/b3cce9cfec6065b77f6d30e45b506109 to your computer and use it in GitHub Desktop.
Save dancarlosgabriel/b3cce9cfec6065b77f6d30e45b506109 to your computer and use it in GitHub Desktop.
Access a PDF document (with RPG) and pass the PDF document as Parameter to another Program/Procedure
//*********************************************************************************************
// I recently get asked how to read a small PDF document into a BLOB and pass it as parameter
// to another function or procedure
// 1. When working with embedded SQL character host variables can only be used up to 32k
// Larger data (up to 16 MB - RPG restriction)
// can be read into a LOB-Variable defined with the SQLTYPE keyword
// 2. Unfortunately the SQLTYPE Keyword cannot be used in a Prototype or Procedure Interface
// 3. But the SQL precompiler generates for the LOB variable a data structure with an
// UNS(4) Subfield _LEN and
// CHAR(xxx) Subfield _DATA
// and this is exactly the structure of a Varying Length field with a 4 digit length prefix
// --> for solving the problem the CLOB data must be transferred into varying lenth field
// this varying length field then can be passed as Parameter to the next procedure/program
// and in the next program the data can be transferred back into a LOB variable (if needed)
//---------------------------------------------------------------------------------------------
// Note: I'd normally not pass the CLOB but only the path where the PDF document is located
// and then read it in the second procedure/Program
//*********************************************************************************************
// In this program I read a PDF-Document into a BLOB Variable and then
// pass it to an (internal) procedure.
// And then write the PDF document back into the IFS with a differen name.
//---------------------------------------------------------------------------------------------
// Note: will only work for small (up to 16 MB) IFS Files
// Should work for Release 7.3 or higher
//*********************************************************************************************
Ctl-Opt DatFmt(*ISO);
/If Defined (*CRTBNDRPG)
CTL-Opt DftActGrp(*No) ActGrp(*NEW);
/EndIf
//*********************************************************************************************
DCL-S GblBlobPDF SQLTYPE(BLOB: 10000000);
DCL-S GblBlobVar VarChar(10000000: 4);
Dcl-S GblErrText VarChar(50);
//*********************************************************************************************
Exec SQL Set Option Commit=*None, DatFmt=*ISO, TimFmt=*ISO,
Naming=*SYS, CloSQLCsr=*EndActGrp;
//*********************************************************************************************
*InLR = *On;
Clear GblBlobPDF;
Exec SQL
Select Line into :GblBlobPDF
from Table(Qsys2.Ifs_Read_Binary(
Path_Name => '/home/Hauser/PDF/PDFDocument_01.pdf'));
If SQLCODE < *Zeros;
Exec SQL Get Diagnostics Condition 1 :GblErrText = MESSAGE_TEXT;
dsply GblErrText;
EndIf;
GblBlobVar = GblBlobPDF;
Int_WriteBack(GblBlobVar);
Return;
//********************************************************************************************
// Write Back
//********************************************************************************************
DCL-Proc Int_WriteBack;
DCL-PI Int_WriteBack;
GblBlobVar VarChar(10000000: 4);
End-Pi;
DCL-S LocBLOBPDF SQLTYPE(BLOB: 10000000);
//---------------------------------------------------------------------------------------------
Clear LocBLOBPDF;
LocBlobPDF = GblBlobVar;
Exec SQL
CAll QSYS2.IFS_Write_Binary(
Path_Name => '/home/Hauser/PDF/PDFDocument_XXX.pdf',
Line => :LocBlobPDF,
File_CCSID => 850,
Overwrite => 'REPLACE');
If SQLCODE < *Zeros;
Exec SQL Get Diagnostics Condition 1 :GblErrText = MESSAGE_TEXT;
dsply GblErrText;
EndIf;
End-Proc;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment