PL SQL package backup tutorial
I started this project because i needed program that will easily back up my files from developer without clicking on package and exporting it to save my work...Second i wrote it because there is Bug in SQL DEVELOPER that causes lines to be messed up when you have large code...
Example:
You have large code and export it with right click on package name and select save specs and body
Real code is written like this...
1 line - BEGIN
2 LINE - SELECT RTRIM(SUBSTR(INSTANCE_NAME,1,8))||'-'||RTRIM(SUBSTR(HOST_NAME,1,15))
3 line - INTO L_INPUTNAME
4 line - FROM V$INSTANCE ;
5 line - EXCEPTION WHEN OTHERS THEN
6 LINE - NULL;
7 line - END;
but sometimes export does the weird thing and saves it messed up
switching the line order....
1 line - BEGIN
2 line - SELECT RTRIM(SUBSTR(INSTANCE_NAME,1,8))||'-'||RTRIM(SUBSTR(HOST_NAME,1,15))
4 line - FROM V$INSTANCE ;
3 line - INTO L_INPUTNAME
5 line - EXCEPTION WHEN OTHERS THEN
6 line - NULL;
7 line - END;
I googled this program somewhere on the web two years ago and manage to rewrite it for my needs...
So without any chit chat let's see the code
CREATE OR REPLACE
PROCEDURE BACKUP_OF_PL_FILES
(I_TIPE_OF_OBJECT VARCHAR2
,I_NAME_OF_OBJECT VARCHAR2 DEFAULT '%')
IS
PL_OUTPUT UTL_FILE.FILE_TYPE;
L_READ UTL_FILE.FILE_TYPE;
L_BUFFER VARCHAR2(4000);
G_SESSONID VARCHAR2(80);
L_LINE VARCHAR2(80);
L_COUNTER NUMBER(30) :=1 ;
L_SAVE VARCHAR2(32767);
L_INPUTNAME VARCHAR2(20);
L_ERRNUM NUMBER := 0;
L_DIRNAME VARCHAR2(100) := ' ';
BEGIN
G_SESSONID := USERENV('sessionid');
L_DIRNAME := 'BACKUP_PL/'||I_NAME_OF_OBJECT||'/'||TO_CHAR(TO_DATE(SYSDATE,'dd.mm.yy'),'yyyymmdd')||'/';
-----------------------------------------------------------------------------
BEGIN
SELECT RTRIM(SUBSTR(INSTANCE_NAME,1,8))||'-'||RTRIM(SUBSTR(HOST_NAME,1,15))
INTO L_INPUTNAME
FROM V$INSTANCE ;
EXCEPTION WHEN OTHERS THEN
NULL;
END;
IF I_NAME_OF_OBJECT='%' THEN
G_SESSONID := 'BAK_'||INITCAP(I_TIPE_OF_OBJECT)||'_'||L_INPUTNAME||'_'||TO_CHAR(SYSDATE, 'DDMMYY_HH24MI') || '.pls';
ELSE
G_SESSONID := 'BAK_'||INITCAP(I_NAME_OF_OBJECT)||'_'||L_INPUTNAME||'_'||TO_CHAR(SYSDATE, 'DDMMYY_HH24MI') || '.pls';
END IF;
PL_OUTPUT := UTL_FILE.FOPEN('c:\BACKUP', G_SESSONID,'A',4000);
UTL_FILE.PUT_LINE(PL_OUTPUT, 'c:\BACKUP' || L_DIRNAME || G_SESSONID);
FOR RS_TYPE IN (SELECT DISTINCT TYPE, NAME
FROM USER_SOURCE
WHERE TYPE LIKE UPPER(I_TIPE_OF_OBJECT)||'%'
AND NAME LIKE UPPER(I_NAME_OF_OBJECT)
ORDER BY 2,1 )
LOOP
FOR RS_NAME IN (SELECT TEXT
FROM USER_SOURCE
WHERE TYPE = RS_TYPE.TYPE
AND NAME = RS_TYPE.NAME )
LOOP
BEGIN
IF (L_COUNTER = 1 OR UPPER(RS_NAME.TEXT) LIKE '%PACKAGE BODY%') THEN
L_BUFFER := 'CREATE OR REPLACE '||RS_NAME.TEXT ;
ELSE
L_BUFFER := RTRIM(RS_NAME.TEXT,' ');
END IF;
IF SUBSTR(L_BUFFER,-1,1) = ';' THEN
UTL_FILE.PUT_LINE(PL_OUTPUT,RTRIM(L_BUFFER));
ELSE
UTL_FILE.PUT_LINE(PL_OUTPUT,RTRIM(L_BUFFER,SUBSTR(L_BUFFER,-1,1)));
END IF;
L_COUNTER := L_COUNTER + 1 ;
EXCEPTION WHEN OTHERS THEN
L_ERRNUM :=1 ;
DBMS_OUTPUT.PUT_LINE('error 2nd loop...'||SQLERRM);
END ;
END LOOP;
L_COUNTER := 1;
UTL_FILE.PUT_LINE(PL_OUTPUT,'/');
IF RS_TYPE.TYPE NOT LIKE '%PACKAGE%' OR RS_TYPE.TYPE LIKE '%PACKAGE BODY%' THEN
UTL_FILE.PUT_LINE(PL_OUTPUT,L_LINE);
END IF;
END LOOP;
UTL_FILE.FCLOSE(PL_OUTPUT);
L_READ := UTL_FILE.FOPEN('PL_OUT', G_SESSONID,'A',4000);
----------------------
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error... '||SQLCODE);
UTL_FILE.FCLOSE(PL_OUTPUT);
END BACKUP_OF_PL_FILES;
Basically this procedure is searching database same as export and write package in your local directory c:\BACKUP
Calling is easy. All you have to do is call it from anonymous block with specification(package,procedure,function...) and name of the Package/Procedure... like this
BEGIN
BACKUP_OF_PL_FILES('package','MY_PACKAGE_NAME_PKG');
BACKUP_OF_PL_FILES('package','MY_PACKAGE_NAME_PKG');
BACKUP_OF_PL_FILES('procedure','MY_PROCEDURE_NAME);
BACKUP_OF_PL_FILES('function','MY_FUNCTION_NAME');
END;
0 comments:
Post a Comment