1. 程式人生 > >【Oracle】UTL_HTTP 傳送http請求,定時任務job+儲存過程PROCEDURE

【Oracle】UTL_HTTP 傳送http請求,定時任務job+儲存過程PROCEDURE

總覺得這種方式心裡用著沒譜,因為對他並不瞭解。比如是否涉及到資源釋放啊,異常捕獲啊,是否能穩定高併發執行啊。大家也可以看一下  幫我優化優化。

首先1·要使用

--開啟Oracle ACL許可權

/* --建立訪問控制檔案(ACL)
begin
  dbms_network_acl_admin.create_acl (       -- 建立訪問控制檔案(ACL)
    acl         => 'utl_http.xml',          -- 檔名稱
    description => 'HTTP Access',           -- 描述
    principal   => 'username',                   -- 授權或者取消授權賬號,大小寫敏感
    is_grant    => TRUE,                    -- 授權還是取消授權
    privilege   => 'connect',               -- 授權或者取消授權的許可權列表
    start_date  => null,                    -- 起始日期
    end_date    => null                     -- 結束日期
  );
 --新增訪問許可權列表項
  dbms_network_acl_admin.add_privilege (    -- 新增訪問許可權列表項
    acl        => 'utl_http.xml',           -- 剛才建立的acl名稱 
    principal  => 'username',                    -- 授權或取消授權使用者
    is_grant   => TRUE,                     -- 與上同 
    privilege  => 'resolve',                -- 許可權列表
    start_date => null,                     
    end_date   => null
  );
 --配置對應ip地址及埠
  dbms_network_acl_admin.assign_acl (       -- 該段命令意思是允許訪問acl名為utl_http.xml下授權的使用者,使用oracle網路訪問包,所允許訪問的目的主機,及其埠範圍。
    acl        => 'utl_http.xml',
    host       => '127.0.0.1',              -- ip地址或者域名,填寫http://localhost:9000/hello與http://localhost:9000/是會報host無效的
                                            -- 且建議使用ip地址或者使用域名,若用localhost,當oracle不是安裝在本機上的情況下,會出現問題
    lower_port => 8889,                     -- 允許訪問的起始埠號
    upper_port => Null                      -- 允許訪問的截止埠號
  );
  commit;
end;

後期再新增 一些指定的host 和 埠 可以使用:
begin
  dbms_network_acl_admin.assign_acl (       -- 該段命令意思是允許訪問acl名為utl_http.xml下授權的使用者,使用oracle網路訪問包,所允許訪問的目的主機,及其埠範圍。
    acl        => 'utl_http.xml',
    host       => '127.0.0.1',              -- ip地址或者域名,錯誤示例:http://127.0.0.1:80
                                            -- 且建議使用ip地址或者使用域名,若用localhost,當oracle不是安裝在本機上的情況下,會出現問題
    lower_port => 80,                     -- 允許訪問的起始埠號
    upper_port => Null                      -- 允許訪問的截止埠號
  );
  commit;
end;

2·編寫PROCEDURE
CREATE OR REPLACE PROCEDURE P_RECEIVE_HTTP
IS
	  V_RESULT VARCHAR2(50);--用於儲存上行介面返回的資料
	  REQ       UTL_HTTP.REQ;
	  RESP      UTL_HTTP.RESP;
	  VALUE     VARCHAR2(1000);
	  P_CONTENT VARCHAR2(1000);
	  V_URL VARCHAR2(200) := 'http://';
	  V_PARAM VARCHAR2(500);
	  CURSOR CUR IS SELECT * from RECEIVE WHERE RECEIVE_STATUS = 0  FOR UPDATE;
	  CUR_RECEIVE RECEIVE%ROWTYPE;
BEGIN
  	  OPEN CUR;
  LOOP
	  EXIT WHEN CUR%NOTFOUND;
	  fetch CUR into CUR_RECEIVE;
    	DBMS_OUTPUT.PUT_LINE(CUR_RECEIVE.Receive_Id);
  		V_PARAM := 'token=0eff44c362b13fa25fc88a412f5512e1='||CUR_RECEIVE.MOBILE_FROM||'='||UTL_URL.ESCAPE(CUR_RECEIVE.RECEIVE_MSG,FALSE,'UTF-8')||'='||TO_CHAR(CUR_RECEIVE.RECEIVE_TIME,'yyyy-MM-dd HH24:mi:ss');
		req := UTL_HTTP.BEGIN_REQUEST (url=> v_url, method => 'POST');
		UTL_HTTP.SET_HEADER (r      =>  req, name   =>  'Content-Type',VALUE  =>  'application/x-www-form-urlencoded;charset=UTF-8');
		UTL_HTTP.SET_HEADER (r      =>   req,name   =>   'Content-Length',VALUE  =>  LENGTH(V_PARAM));
		UTL_HTTP.WRITE_TEXT (r      =>   req,data   =>   V_PARAM);
		resp := UTL_HTTP.GET_RESPONSE(req);
   		 UTL_HTTP.READ_LINE(resp, value, TRUE);
      		    IF INSTR(VALUE,'"code":"0"')> 0 THEN
  				update RECEIVE set RECEIVE_STATUS = 1,REMARK = value where RECEIVE_ID = CUR_RECEIVE.RECEIVE_ID;
			ELSE
  				update RECEIVE set RECEIVE_STATUS = 2,REMARK = value where RECEIVE_ID = CUR_RECEIVE.RECEIVE_ID;
			END IF;
	    UTL_HTTP.END_RESPONSE(resp);
  END LOOP;
  CLOSE CUR;
END P_RECEIVE_HTTP;

3·編寫 job定時任務

 begin
 dbms_scheduler.create_job (
 job_name => 'JOB_CW_RECEIVE_HTTP', --job名
 job_type => 'STORED_PROCEDURE',--job型別
 job_action => 'P_RECEIVE_HTTP', --儲存過程名
 start_date => sysdate,--開始執行時間
 repeat_interval => 'FREQ=MINUTELY; INTERVAL=5', -- 下次執行時間
 comments => '每10分鐘讀取receive表資料 http推送到創維方',--註釋
 auto_drop=>false  --job禁用後是否自動刪除
 );
 end;

4·job相關操作

--查詢
 select * from dba_scheduler_jobs;
--執行
begin
dbms_scheduler.run_job('JOB_CW_RECEIVE_HTTP');
end;
--啟用
begin
dbms_scheduler.enable('JOB_CW_RECEIVE_HTTP');
end;
--禁用
begin
dbms_scheduler.disable('JOB_CW_RECEIVE_HTTP');
end;
--刪除
begin
   dbms_scheduler.drop_job(job_name => 'JOB_CW_RECEIVE_HTTP',force => TRUE);
end;