1 --定義包中函數的純度級別 2 create or replace package purityTest is 3 type dept_typ is table of dept%rowtype index by binary_integer; 4 dept_tab dept_typ; 5 procedure newdept( 6 p_deptno dept.deptno%type, 7 p_dname dept.dname%type, 8 p_loc dept.loc%type 9 ); 10 function getraisedsalary (p_empno emp.empno%type) 11 return number; 12 pragma restrict_references(newdept,WNPS); 13 pragma restrict_references(getraisedsalary,WNDS); 14 end puritytest; 15 wnds:不能修改數據庫數據, 即禁止DML操做 16 wnps:不能修改包變量 17 rnds: 不能讀取數據庫,禁止執行select操做 18 rnps: 不能將包變量賦給其餘值 19 --包權限 20 grant execute on scott.puritytest to userb; 21 22 23 Oracle內部提供的在數據庫內部和應用程序間通訊的方式有兩種 24 --DBMS_PIPE管道權限賦予scott 25 grant execute on dbms_pipe to scott; 26 --管道在不一樣模式中傳遞消息 27 create or replace procedure sen_pipe_message(pipename varchar2,message 28 varchar2) is flag int; 29 begin flag:=dbms_pipe.create_pipe(pipename); --建立管道 30 if flag=0 then --若是建立管道成功 31 dbms_pipe.pack_message(message); --將消息存到本地緩衝區 32 flag:=dbms_pipe.send_message(pipename); 33 --將本地緩衝區中的消息發送到管道 34 end if; 35 end; 36 37 -- 從管道中接受消息 38 create or replace procedure receive_pipe_message 39 (pipename varchar2,message out varchar2) 40 is flag int; 41 begin 42 flag:=dbms_pipe.receive_message(pipename); 43 if flag=0 then 44 dbms_pipe.unpack_message(message); 45 flag:=dbms_pipe.remove_pipe(pipename); 46 end if; 47 end; 48 49 --scott 50 begin 51 sen_pipe_message('pipe_demo','向管道中發送一條消息'); 52 end; 53 grant execute on scott.receive_pipe_message to userb; 54 --userb 55 declare 56 v_message varchar2(100); 57 begin 58 scott.receive_pipe_message('pipe_demo',v_message); 59 dbms_output.put_line(v_message); 60 end; 61 62 63 --DBMS_ALTER包 64 grant execute on dbms_alert to scott; 65 多個會話能夠併發執行同一個報警,每一個會話發佈報警時會阻塞其餘會話 66 發佈報警, 直到報警被提交, 事務會以序列的方式發生. 67 --產生報警示例 68 declare 69 v_alertname varchar2(30) :='alert_demo'; 70 begin 71 dbms_alert.signal(v_alertname,'這是一個報警消息!'); 72 commit; 73 end; 74 75 --等待報警示例,用兩個會話測試 76 declare 77 v_alertname varchar2(30) :='alert_demo'; --報警名稱 78 v_status integer; --等待狀態 79 v_msg varchar2(200); --報警消息 80 begin 81 --註冊報警, 指定名字 82 dbms_alert.register(v_alertname); 83 --監聽報警,等待報警發生 84 dbms_alert.waitone(v_alertname,v_msg,v_status ); 85 --若是不返回0,則表示報警失敗 86 if v_status !=0 87 then 88 dbms_output.put_line('error'); 89 end if; 90 dbms_output.put_line(v_msg); 91 end; 92 93 94 DBMS_JOB:安排和管理做業隊列。經過做業隊列,可讓Oracle數據庫按期執行特定的任務。 95 當使用DBMS_JOB管理做業的時候,必須確保設置了初始化參數JOB_QUEUE_PROCESSES(不能爲0)。 96 ALTER SYSTEM SET job_queue_processes=39 SCOPE=SPFILE; --DBA 97 select job,next_date,next_sec,INTERVAL,what from user_jobs where job=23;--查詢job信息 98 99 1、 SUBMIT 100 該過程用於創建一個新的做業,當創建做業的時候,須要經過設置相應的參數來告訴Oracle要執行的內容, 101 要執行的時間,要執行任務的間隔。 102 103 DBMS_JOB.SUBMIT( 104 JOB OUT BINARY_INTERGER, --用於指定做業編號 105 WHAT IN VARCHAR2, --用於指定做業要執行的操做 106 NEXT_DATE IN DATE DEFAULT SYSDATE, --用於指定該操做的下一次運行的日期 107 INTERVAL IN VARCHAR2 DEFAULT ‘NULL’, --用於指定該操做的時間間隔 108 NO_PARSE IN BOOLEAN DEFAULT FALSE, --用於指定是否須要解析與做業相關的過程 109 INSTANCE IN BINARY_INTEGER DEFAULT ANY_INSTANCE, --用於指定哪一個例程能夠運行做業? 110 FORCE IN BOOLEAN DEFAULT FALSE --用於指定是否強制運行與做業相關的例程 111 ); 112 113 114 創建Oracle做業的例子: 115 DECLARE 116 JOBNO NUMBER; --經過查看該變量能夠獲得返回的做業編號 117 BEGIN 118 DBMS_JOB.SUBMIT(JOBNO,'PRC_SENDTOGX;',SYSDATE,'SYSDATE+1'); --執行工信局提供數據的腳本程序 119 END; 120 121 interval參數值 122 天天午夜12點: 'TRUNC(SYSDATE + 1)' 123 天天早上8點30分 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)' 124 每星期二中午12點 'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24' 125 每月第一天的午夜12點 'TRUNC(LAST_DAY(SYSDATE ) + 1)' 126 每一個季度最後一天的晚上11點 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24' 127 每分鐘執行一次 'SYSDATE+1/1440' 128 129 2、 REMOVE 130 這個過程的做用是用於刪除做業隊列當中的特定的做業,它的語法以下: 131 DBMS_JOB.REMOVE(JOB IN BINARY_INTEGER); 132 下面是一個刪除做業的例子: 133 首先查看DBA_JOBS表,看錶裏面有哪些任務正在執行着? 134 SELECT * FROM DBA_JOBS; 135 能夠看到裏面的JOB就是咱們要刪除的做業的編號,LOG_USER是建立該任務的人。 136 SQL> EXEC DBMS_JOB.REMOVE(467); 137 SQL>COMMIT; 138 這樣就能把已經創建的做業刪除了。 139 140 3、 CHANGE 141 該過程改變與做業相關的全部的信息,其中包括做業的操做內容,做業運行的時間以及運行時間間隔信息等等。語法以下: 142 DBMS_JOB.CHANGE( 143 JOB IN BINARY_INTEGER, 144 WHAT IN VARCHAR2, 145 NEXT_DATE, 146 INTERVAL IN VARCHAR2, 147 INSTANCE IN BINARY_INTEGER DEFAULT NULL, 148 FORCE IN BOOLEAN DEFAULT FALSE 149 ); 150 151 例子: 152 SQL>EXEC DBMS_JOB.CHANGE(2,NULL,NULL,’SYSDATE+2’); 153 SQL>COMMIT; 154 155 4、 WHAT 156 WHAT用來改變做業要執行的操做,例如: 157 SQL>EXEC DBMS_JOB.WHAT(268,’BEIGN FUNCTION(8);END;’); 158 159 5、 NEXT_DATE 160 用來改變做業的下次運行日期 161 SQL>EXEC DBMS_JOB.NEXT_DATE(‘478’,’SYSDATE+2’); 162 163 6、 INTERVAL 164 該過程用來改變做業的運行時間間隔,下面的運行時間間隔修改成每分鐘執行一次: 165 SQL>exec dbms_job.interval(478,’SYSDATE+1/24/60 166 167 7、BROKEN 168 該過程用於給該做業打上中斷標誌,能夠在DBA_JOBS表裏面觀察該做業的BROKEN標誌知否爲中斷。例子: 169 SQL>EXEC DBMS_JOB.BROKEN(478,TRUE); 170 SQL>COMMIT; 171 172 8、RUN 173 該過程用來執行該做業,例子: 174 SQL>EXEC DBMS_RN(478); 175 SQL>COMMIT; 176 177 1、 如何中止一個做業? 178 SQL>DBMS_JOBS.BROKEN(2,TRUE); 179 SQL>COMMIT; 180 181 2、如何啓動一個做業? 182 SQL>DBMS_JOBS.BROKEN(2,FALSE); 183 SQL>COMMIT; 184 185 3、 如何計算一個過程運行的時間(DATE和TimeStamp)? 186 187 能夠在過程的開始設置一個時間,而後在過程的結尾處設置一個時間,而後兩個時間的時間差能夠計算出該過程運行的時間。經過實踐發現使用SYSESTAMP來計算時間比較準確一些: 188 189 SELECT to_char(systimestamp,'yyyy-mm-dd hh24:mi:ss:ff4') FROM dual; 190 191 DBMS_SCHEDULER [ˈskɛdʒʊələ] Oracle調度 192 BEGIN 193 DBMS_SCHEDULER.CREATE_JOB ( 194 job_name => 'job_do_main_rtt', 195 job_type => 'STORED_PROCEDURE', 196 job_action => 'com_job.docachezmondate', 197 start_date => sysdate, 198 repeat_interval => 'FREQ=SECONDLY;INTERVAL=1', 199 comments => '每3秒彙總主界面的統計數據' 200 ); 201 END; 202 203 begin 204 dbms_scheduler.create_job( 205 job_name => , 206 job_type => , 207 jog_action => , 208 number_of_arguments => , 209 start_date => , 210 repeat_interval => , 211 end_date => , 212 job_class => , 213 enabled => , 214 auto_drop => , 215 comments => 216 ); 217 end; 218 219 參數介紹: 220 job_name:job名字 221 job_type:job類型,支持三種類型: 222 1)PLSQL_BLOCK——PL/SQL語句塊; 223 2)STORED_PROCEDURE——存儲過程; 224 3)EXECUTABLE——外部程序(外部程序能夠是一個shell腳本,也能夠是操做系統級別的指令)。 225 job_action:根據job_type的不一樣,job_action有相對應的內容。 226 number_of_arguments:參數個數。 227 start_date:執行開始時間。 228 repeat_interval:指定job執行頻率(如每分鐘執行一次、天天執行一次等)。 229 end_date:執行結束時間。 230 job_class:jobclass的名字。 231 enabled:指定是否自動激活job,爲true表明自動激活,false表明不激活。 232 auto_drop:執行完是否自動drop 233 comments:對於job的簡單說明 234 235 236 FREQ 關鍵字用來指定間隔的時間週期,可選參數有:YEARLY(年), MONTHLY(月), WEEKLY(周), DAILY(日), HOURLY(時), MINUTELY(分), SECONDLY(秒)等單位。 237 238 INTERVAL 關鍵字用來指定間隔的頻繁,可指定的值的範圍從1-999。 239 240 BYHOUR 指定一天中的小時。可指定的值的範圍從1-24。16,17,18就表示天天下午的四、5、6點。 241 BYDAY 關鍵字用來指定每週的哪天運行。 242 BYMONTHDAY 關鍵字用來指定每個月中的哪一天。-1 表示每個月最後一天。 243 BYMONTH 關鍵字用來指定每一年的月份。 244 BYDATE 指定日期。0310就表示3月10日。 245 246 例如: 247 運行每星期五。(全部這三個例子是等價的。) 248 FREQ=DAILY; BYDAY=FRI; 249 FREQ=WEEKLY; BYDAY=FRI; 250 FREQ=YEARLY; BYDAY=FRI; 251 252 設置任務隔一週運行一次,而且僅在周5運行: 253 FREQ=WEEKLY; INTERVAL=2; BYDAY=FRI; 254 255 在每個月的最後一天運行 256 FREQ=MONTHLY; BYMONTHDAY=-1; 257 258 三月十日開。(兩個例子是等價的) 259 FREQ=YEARLY; BYMONTH=MAR; BYMONTHDAY=10; 260 FREQ=YEARLY; BYDATE=0310; 261 262 設置任務每10隔天運行: 263 REPEAT_INTERVAL => 'FREQ=DAILY; INTERVAL=10'; 264 265 設置任務在天天的下午四、5、6點時運行: 266 REPEAT_INTERVAL => 'FREQ=DAILY; BYHOUR=16,17,18'; 267 268 設置任務在每個月29日運行: 269 REPEAT_INTERVAL => 'FREQ=MONTHLY; BYMONTHDAY=29'; 270 271 設置任務在每一年的最後一個周5運行: 272 REPEAT_INTERVAL => 'FREQ=YEARLY; BYDAY=-1FRI'; 273 274 設置任務每隔50個小時運行: 275 REPEAT_INTERVAL => 'FREQ=HOURLY; INTERVAL=50'; 276 277 repeat_interval => 'FREQ=HOURLY; INTERVAL=2' 278 每隔2小時運行一次job 279 280 repeat_interval => 'FREQ=DAILY' 281 天天運行一次job 282 283 repeat_interval => 'FREQ=WEEKLY; BYDAY=MON,WED,FRI" 284 每週的1,3,5運行job 285 286 repeat_interval => 'FREQ=YEARLY; BYMONTH=MAR,JUN,SEP,DEC; BYMONTHDAY=30; 287 每一年的3,6,9,12月的30號運行job 288 289 290 對job的各類操做查詢: 291 select owner, job_name, state from dba_scheduler_jobs; 292 select job_name, state from user_scheduler_jobs; 293 294 注意:相應的查詢都須要有相對應的權限。 295 運行:dbms_scheduler.run_job('job_name'); 296 中止:dbms_scheduler.stop_job('job_name'); 297 刪除:dbms_scheduler.drop_job('job_name') 298 299 300 /* 301 ** 建立一個存儲過程,輸出當前系統時間 302 */ 303 create or replace procedure My_Time 304 is 305 begin 306 dbms_output.put_line(to_char(sysdate, 'yyyy-mm-hh HH24:MI:SS')); 307 end; 308 309 /* 310 ** 建立一個job來調用以上存儲過程 311 */ 312 declare 313 n_JobExist integer; --標記job是否存在 314 s_Job_Name varchar2(32) := 'My_Job'; 315 begin 316 n_JobExist := 0; 317 --查詢My_Job是否存在,若是存在則先drop掉 318 begin 319 select 1 into n_JobExist from user_scheduler_jobs 320 where job_name = upper(s_Job_Name); 321 exception 322 when NO_DATA_FOUND then 323 NULL; 324 end; 325 if (n_JobExist = 1) then 326 sys.dbms_scheduler.drop_job(s_Job_Name); 327 end if; 328 --建立My_Job 329 sys.dbms_scheduler.create_job( 330 job_name => s_Job_Name, 331 job_type => 'plsql_block', 332 --要調用的存儲過程 333 job_action => 'begin My_Time; end;', 334 repeat_interval => 'freq=MINUTELY;interval=1', 335 start_date => sysdate, 336 --end_date => sysdate + 3/(24*60), 337 job_class => 'DEFAULT_JOB_CLASS', 338 auto_drop => false, 339 enabled => true 340 ); 341 end;