Note: This document is recognized for including obsolete content and is due for being updated. IFS/Design and Rational Rose are no longer used in development of IFS Applications 8. IFS Windows Client and IFS Client Developer are not in use.
The need for the possibility to save large amount of data in IFS Applications Logical Units (LU) attributes has become bigger and bigger the last years. Up until IFS Applications 2004 we have used two data types for storing Large Objects, these are Long Raw and Long. Long Raw and Long is data types that have been deprecated by Oracle, meaning that one should not use them anymore and that support for them can be removed in any forthcoming Oracle release. For that reason we have decided to support the new data types Character Large Object (CLOB) and Binary Large Object (BLOB).
We will introduce a new tablespace IFSAPP_LOB which by default will store all LOB data. To have a specific tablespace for LOB's makes it easier for DBA's to manage LOB data. Using IFSAPP_LOB is the default behavior for IFS Applications, but this can be changed by the person designing the new LOB attributes in the LU.
This tablespace, as well as all other tablespaces, is defined if you create a new Oracle instance using the included Oracle DBCA templates. If you are upgrading you database, IFSAPP_LOB will be added when preparing your database since this process verify that all default tablespaces exist in the database.
A lob in IFS Applications will never be null, so it will never be possible to compare a LOB with a null in a SQL statement. Instead we will give the LOB the default value of empty LOB, by the functions empty_clob() or empty_blob().
Since we will use a view for retrieving LOB data and a PL/SQL procedure for writing data normal Foundation1 security is used. This means that end-users must be granted Select on the view and Execute on the package and also Execute on the method.
When adding LOB support to a form it is recommended to scan the form to get the new database grants to the Presentation Object. The database grants is needed for making it possible for end users to run the form by granting the Presentation Object to the end user.
The following restriction will is valid for LOB's in IFS Applications 2004-1 SP4:
We will try to remove some of these restrictions in the next core release.
This is a example of an LU that originally had two attributes Id and Description. The LU has been extended with tow LOB's, one CLOB called Text and one BLOB called Picture. So now the LU includes four attributes:
Example of Create Table statement (changes in bold):
CREATE TABLE lob_tab ( id VARCHAR2(10) NOT NULL, description VARCHAR2(100) NOT NULL, text CLOB NOT NULL, picture BLOB NOT NULL) lob (text) STORE AS (TABLESPACE ifsapp_lob CHUNK 4096 DISABLE STORAGE IN ROW) lob (picture) STORE AS (TABLESPACE ifsapp_lob CHUNK 4096 DISABLE STORAGE IN ROW) TABLESPACE for the table ...; or ALTER TABLE lob_tab ADD text CLOB LOB (text) STORE AS (TABLESPACE ifsapp_lob CHUNK 4096 DISABLE STORAGE IN ROW) / UPDATE lob_tab SET text = empty_clob() WHERE text IS NULL / ALTER TABLE lob_tab MODIFY text NOT NULL / ALTER TABLE lob_tab ADD picture BLOB LOB (picture) STORE AS (TABLESPACE ifsapp_lob CHUNK 4096 DISABLE STORAGE IN ROW) / UPDATE lob_tab SET picture = empty_blob() WHERE picture IS NULL / ALTER TABLE lob_tab MODIFY picture NOT NULL /
Example of view (changes in bold):
CREATE OR REPLACE VIEW LOB AS SELECT id id, description description, picture picture, text text, rowid objid, ltrim(lpad(to_char(rowversion,'YYYYMMDDHH24MISS'),2000)) objversion FROM lob_tab WITH read only
Example of Insert___ method (changes in bold):
PROCEDURE Insert___ ( objid_ OUT VARCHAR2, objversion_ OUT VARCHAR2, newrec_ IN OUT LOB_TAB%ROWTYPE, attr_ IN OUT VARCHAR2 ) IS BEGIN newrec_.rowversion := sysdate; objversion_ := to_char(newrec_.rowversion,'YYYYMMDDHH24MISS'); INSERT INTO lob_tab ( id, description, text, picture, rowversion) VALUES ( newrec_.id, newrec_.description, empty_clob(), empty_blob(), newrec_.rowversion)RETURNING &OBJID INTO objid_;
EXCEPTION WHEN dup_val_on_index THEN Error_SYS.Record_Exist(lu_name_); END Insert___;
Example of Update___ method (no changes required):
PROCEDURE Update___ ( objid_ IN VARCHAR2, oldrec_ IN LOB_TAB%ROWTYPE, newrec_ IN OUT LOB_TAB%ROWTYPE, attr_ IN OUT VARCHAR2, objversion_ IN OUT VARCHAR2, by_keys_ IN BOOLEAN DEFAULT FALSE ) IS BEGIN newrec_.rowversion := sysdate; objversion_ := to_char(newrec_.rowversion,'YYYYMMDDHH24MISS'); IF by_keys_ THEN UPDATE lob_tab SET id = newrec_.id, description = newrec_.description, rowversion = newrec_.rowversion WHERE id = newrec_.id; ELSE UPDATE lob_tab SET id = newrec_.id, descripiton = newrec_.description, rowversion = newrec_.rowversion WHERE rowid = objid_; END IF; EXCEPTION WHEN dup_val_on_index THEN Error_SYS.Record_Exist(lu_name_); END Update___;
Example of Delete___ method (no changes required):
PROCEDURE Delete___ ( objid_ IN VARCHAR2, remrec_ IN LOB_TAB%ROWTYPE ) IS key_ VARCHAR2(2000); BEGIN key_ := remrec_.result_key || '^'; Reference_SYS.Do_Cascade_Delete(lu_name_, key_); DELETE FROM lob_tab WHERE rowid = objid_; END Delete___;
Example of Write BLOB procedure:
PROCEDURE Write_Picture__( objversion_ IN OUT VARCHAR2, rowid_ IN ROWID, blob_loc_ IN BLOB ) IS rec FND_LOG_TAB%ROWTYPE; BEGIN General_SYS.Init_Method(lu_name_, 'LOB_API', 'Write_Picture__'); rec := Lock_By_Id___(rowid_, objversion_); UPDATE lob_tab SET picture = blob_loc_, rowversion = SYSDATE WHERE rowid = rowid_ RETURNING to_char(rowversion,'YYYYMMDDHH24MISS') INTO objversion_; END Write_Picture__;
Example of Write CLOB procedure:
PROCEDURE Write_Text__( objversion_ IN OUT VARCHAR2, rowid_ IN ROWID, clob_loc_ IN CLOB ) IS rec FND_LOG_TAB%ROWTYPE; BEGIN General_SYS.Init_Method(lu_name_, 'LOB_API', 'Write_Text__'); rec := Lock_By_Id___(rowid_, objversion_); UPDATE lob_tab SET text = clob_loc_, rowversion = SYSDATE WHERE rowid = rowid_ RETURNING to_char(rowversion,'YYYYMMDDHH24MISS') INTO objversion_; END Write_Text__;
There are six methods in cSessionManager handling all LOB operations:
( Please refer the documentation for each one of them for more details and examples. )
The methods above can be categorized in two sections:
Object methods: DbLobRead, DbClobWrite & DbClobWrite
File Methods: DbLobReadToFile, DbClobWriteFromFile & DbBlobWriteFromFile
Object methods will stream the data between the database and an object (normally a string variable). That will result in a memory allocation on the client side that is equal to the LOB size. Small LOB objects might not be noticeable but when handling larger object (GB Size), you might end up in performance losses.
File methods will stream the data between the database and a file, without using the client as "middle hand" for memory allocation which might many times result in a better response time. Of course, you might not always want to receive a file in the end and should then not use the file methods, but one of the object methods.