Last active
August 30, 2023 10:08
-
-
Save BirgittaHauser/041e1fb82b5f8bbeee26578b0a438f4e 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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//********************************************************************************************* | |
// 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; |
cool stuff, thanks for sharing Birgitta, and Bob.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
`
Ctl-Opt DatFmt(*ISO);
/If Defined (*CRTBNDRPG)
CTL-Opt DftActGrp(*No) ActGrp(*NEW);
/EndIf