Friday, June 10, 2011

Use select to query filesystem

Use the below code example to create a system that allows you to query system file info (logs, etc) and return them into a table you can select from - all in real time.

--create types
CREATE OR REPLACE TYPE FILE_CONTENTS_OBJ AS OBJECT
(
              LOG_CONTENTS CLOB
)
; CREATE OR REPLACE TYPE FILE_CONTENTS_TBL_OBJ AS TABLE OF FILE_CONTENTS_OBJ;

-- Create ORACLE directory
CREATE OR REPLACE DIRECTORY MY_DIR AS '/home/your/directory';

-- Create pipelined function using they types and directory
CREATE OR REPLACE FUNCTION RETURN_FILE_CONTENTS
(
              ORACLE_DIR VARCHAR2
             ,FILE_NAME VARCHAR2
) RETURN FILE_CONTENTS_TBL_OBJ PIPELINED AS

              LOG_CONTENT_REC FILE_CONTENTS_OBJ := FILE_CONTENTS_OBJ(LOG_CONTENTS => NULL);
              ALL_CONTENT CLOB;
              SRC_FILE BFILE := BFILENAME(ORACLE_DIR,FILENAME => FILE_NAME);
              OFFST PLS_INTEGER := 1;
              LANG_CTX NUMBER := DBMS_LOB.DEFAULT_LANG_CTX;
              V_WARNING NUMBER;

BEGIN

              DBMS_LOB.OPEN(SRC_FILE, DBMS_LOB.LOB_READONLY);

              DBMS_LOB.CREATETEMPORARY(LOB_LOC => ALL_CONTENT, CACHE   => FALSE);

              DBMS_LOB.LOADCLOBFROMFILE(DEST_LOB     => ALL_CONTENT
                                       ,SRC_BFILE    => SRC_FILE
                                       ,AMOUNT       => DBMS_LOB.LOBMAXSIZE
                                       ,SRC_OFFSET   => OFFST
                                       ,DEST_OFFSET  => OFFST
                                       ,BFILE_CSID   => DBMS_LOB.DEFAULT_CSID
                                       ,LANG_CONTEXT => LANG_CTX
                                       ,WARNING      => V_WARNING);

              DBMS_LOB.CLOSE(SRC_FILE);

              IF V_WARNING = 0 THEN
                            LOG_CONTENT_REC := FILE_CONTENTS_OBJ(ALL_CONTENT);
                            DBMS_LOB.FREETEMPORARY(ALL_CONTENT);
                            PIPE ROW(LOG_CONTENT_REC);
              ELSE
                            LOG_CONTENT_REC := FILE_CONTENTS_OBJ('Error reading file. Error number generated from dbms_lob.loadclobromfile was:' || V_WARNING);
                            DBMS_LOB.FREETEMPORARY(ALL_CONTENT);
                            PIPE ROW(LOG_CONTENT_REC);
              END IF;
              -- in a pipelined function, return is needed for syntax purposes only!
              RETURN;

EXCEPTION
              WHEN OTHERS THEN
                            DBMS_LOB.CLOSE(SRC_FILE);
                            DBMS_LOB.FREETEMPORARY(ALL_CONTENT);
           
                            LOG_CONTENT_REC := FILE_CONTENTS_OBJ('Error reading file. Error was: ' || SQLERRM);
                            PIPE ROW(LOG_CONTENT_REC);
           
                            -- in a pipelined function, return is needed for syntax purposes only!
                            RETURN;
           
END;

/* Usage examples */

--Select from pipelined function in your sql statment!:

--SELECT * FROM TABLE(rdsprd.return_file_contents('MY_DIR', 'yourfilename.log'))

No comments:

Post a Comment