開發過程中,需要不停的備份數據庫對象, 特別是存儲過程, 每次手動備份不免很低能啊
歷經幾次修改終於, 完美了,O(∩_∩)O哈哈~ (當然,你也可以再改簡便一點~~~)
select dbms_metadata.get_ddl('PROCEDURE',"PROCEDURE_NAME",'NAG') 遇到大存儲過程老是丟東西不說, 對象名 還老是 "用戶名"."對象名" 的格式,膩煩人!~
CREATE OR REPLACE PROCEDURE OBJAUTOSTORE
AS
/* 功能:備份存儲過程和視圖
准備工作:
--1.創建文件夾 :'D:/OracleBackUp/ProcBack';--文本存放的路徑
--2.執行:create or replace directory MyProcBakPath as 'D:/OracleBackUp/ProcBack';
--3.賦權限:
sqlplus /nolog
conn nag/nag as sysdba
grant select on DBA_OBJECTS to NAG;
--4.創建Job,自動執行,自動備份存儲過程
+縮減代碼,歸類循環執行 lzpong 2015/03/18
+更改代碼,使超大存儲過程也能保存,並且 不會出現 "用戶名"."對象名" 的格式 lzpong 2015/07/14
*/
OutFile UTL_FILE.FILE_TYPE;
type user_source_table_type is table of user_source.text%TYPE INDEX BY BINARY_INTEGER;
user_source_table user_source_table_type;
pos INTEGER;
line integer;
towner VARCHAR2(50) :='NAG';
cursor abc is
SELECT 'PROCEDURE' otype,'Proc_'||to_char(sysdate, 'yyyymmddhh24miss')||'.sql' ofile FROM DUAL
union all SELECT 'VIEW' otab,'View_'||to_char(sysdate, 'yyyymmddhh24miss')||'.sql' ofile FROM DUAL
union all SELECT 'TRIGGER' otab, 'Trig_'||to_char(sysdate, 'yyyymmddhh24miss')||'.sql' ofile FROM DUAL
union all SELECT 'SEQUENCE' otab, 'Sequ_'||to_char(sysdate, 'yyyymmddhh24miss')||'.sql' ofile FROM DUAL
union all SELECT 'FUNCTION' otab, 'Func_'||to_char(sysdate, 'yyyymmddhh24miss')||'.sql' ofile FROM DUAL
;
BEGIN
for rec in abc loop
dbms_output.put_line(rec.otype||','||rec.ofile);
OutFile:=UTL_FILE.FOPEN('MYPROCBAKPATH' , rec.ofile,'w',32767);
for robj in (select owner,object_name from dba_objects where object_type=rec.otype and owner=towner) loop
--select dbms_metadata.get_ddl(rec.otype,robj.object_name,towner) into v_sql from dual;
execute immediate 'SELECT TEXT FROM user_SOURCE WHERE name='''||robj.object_name||''' order by line ' bulk collect into user_source_table;
UTL_FILE.put_line(OutFile,'-----------------start '||robj.object_name||' (line:'||user_source_table.count||')----------------');
pos:=1;
line:=1;
--大對象寫入文件
UTL_FILE.put(OutFile,'create or replace ');
WHILE pos<=user_source_table.count LOOP
if(line>500)then --防止 文件寫入緩存滿了
dbms_output.put_line(pos||' '||robj.object_name);
UTL_FILE.fflush(OutFile);
line:=1;
end if;
UTL_FILE.put(OutFile,user_source_table(pos));
pos:=pos+1;
line:=line+1;
END LOOP;
UTL_FILE.put_line(OutFile,'-----------------end '||robj.object_name||'----------------');
end loop;
UTL_FILE.put_line(OutFile,'-----------------end of file '||rec.ofile||'----------------',true);
UTL_FILE.FCLOSE(OutFile);
end loop;
EXCEPTION
WHEN OTHERS THEN
UTL_FILE.put(OutFile,' pos:'||pos||chr(10)||SQLERRM||chr(10)||dbms_utility.format_error_backtrace);
UTL_FILE.FCLOSE(OutFile);
dbms_output.put_line(SQLERRM||chr(10)||dbms_utility.format_error_backtrace);
END;
好了, 輕松了不少了吧~~
下面繼續奉上 Oracle的自動全庫導出腳本,還帶打包壓縮哦:
::備份文件夾 路徑 和 WinRAR 路徑 不需要引號 echo off ::文件名前綴 set pnm=NAG_Back_ ::備份文件夾 路徑 set pth=D:\OracleBackUp ::WinRAR 路徑 set rth=C:\Program Files\WinRaR ::自動檢測/創建備份文件夾 if not exist "%pth%" ( md "%pth%" ) echo ****************%date%,數據備份計划**************** >>%pth%\%pnm%explog.log set pth=%pth%\%pnm% echo %time%,處理老的備份文件 >>%pth%explog.log if exist "%rth%\rar" do ( del "%pth%6.rar" ren "%pth%5.rar" %pnm%6.rar ren "%pth%4.rar" %pnm%5.rar ren "%pth%3.rar" %pnm%4.rar ren "%pth%2.rar" %pnm%3.rar ren "%pth%1.rar" %pnm%2.rar ren "%pth%0.rar" %pnm%1.rar ) else ( del "%pth%6.dmp" ren "%pth%5.dmp" %pnm%6.dmp ren "%pth%4.dmp" %pnm%5.dmp ren "%pth%3.dmp" %pnm%4.dmp ren "%pth%2.dmp" %pnm%3.dmp ren "%pth%1.dmp" %pnm%2.dmp ren "%pth%0.dmp" %pnm%1.dmp ) echo %time%,開始備份數據庫 >>"%pth%explog.log" ::導出參數 exp username/password owner=username file="%pth%0.dmp" log="%pth%0.log" if exist "%rth%\rar" do ( echo %time%,開始壓縮備份文件 >>"%pth%explog.log" "%rth%\rar" a -df "%pth%0.rar" "%pth%0.dmp" "%pth%0.log" ) echo %time%,完成數據庫備份 >>"%pth%explog.log" echo. >>"%pth%explog.log"
