Oracle數據庫通過DBLINK實現遠程訪問

什麼是DBLINK?

dblink(Database Link)數據庫鏈接顧名思義就是數據庫的鏈接  ,就像電話線一樣,是一個通道,當我們要跨本地數據庫,訪問另外一個數據庫表中的數據時,本地數據庫中就必須要創建遠程數據庫的dblink,通過dblink本地數據庫可以像訪問本地數據庫一樣訪問遠程數據庫表中的數據。

 

如何使用DBLINK?

場景:假設當前數據庫用戶爲ALANLEE,此時需要通過ALANLEE這個用戶去採集遠程數據庫的數據。

遠程數據庫信息如下:

複製代碼
HSAJ216 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 12.1.3.216)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = hscsserver)
    )
  )
複製代碼

遠程數據庫用戶名:hs_user,密碼:hundsun

 

第一步:查看用戶是否具備創建database link權限

--查看ALANLEE用戶是否具備創建database link權限
select * from user_sys_privs where privilege like upper('%DATABASE LINK%') AND USERNAME='ALANLEE';
select * from user_sys_privs t where t.privilege like upper('%link%');

在數據庫中dblink有這麼一些權限。例如CREATE DATABASE LINK表示所創建的dblink只能是創建者能使用,別的用戶使用不了,CREATE PUBLIC DATABASE LINK表示所創建的dblink所有用戶都可以使用,DROP PUBLIC DATABASE LINK表示刪除公用dblink的權限。

假如查出相關的數據則表示ALANLEE用戶具有相關的權限,如果沒有查出數據則說明ALANLEE用戶沒有相關的權限。

 

第二步:假如用戶不具備相應的權限則需要授權,如果ALANLEE用戶具有類似管理員用戶授權的權限則直接使用當前用戶授權,如果ALANLEE不具備這樣的權限則使用SYS/SYSTEM之類權限更大的數據庫用戶來給ALANLEE用戶授權

--需要授予ALANLEE用戶創建數據庫鏈接權限
grant create public database link to ALANLEE;
--需要授予ALANLEE用戶刪除數據庫鏈接權限
grant drop public database link to ALANLEE; 

這裏我們使用公共的dblink,即所有用戶都可以使用的dblink,可以根據自己的所需去賦予相應的權限,授權成功後可以通過第一步的視圖查看是否授權成功。

 

第三步:通過ALANLEE用戶創建遠程數據庫鏈接(數據庫地址:12.1.3.216 用戶名:hs_user 密碼:hundsun)

drop public database link HSAJ216;
create public database link HSAJ216
connect to hs_user identified by hundsun
using '(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 12.1.3.216)(PORT = 1521)))
(CONNECT_DATA = (SERVICE_NAME = hscsserver)))';

爲了避免一些其他的問題,這裏建議直接使用遠程數據庫的全局監聽實例名作爲database link的名稱,也就是遠程數據庫信息所示的HSAJ216。

 

第四步:查詢已經建立的數據庫遠程鏈接

select owner,object_name from dba_objects where object_type='DATABASE LINK';

如果有自己創建的database link數據則說明創建成功,反之就是不存在。

 

第五步:測試建立的遠程數據庫鏈接

select * from dual@HSAJ216;

如果能查出東西,則遠程訪問便成功了。

如何查詢遠程數據庫某個用戶某個表的數據呢?sql如下:

select * from hs_asset.client@HSAJ216;

如果能查詢出表的數據,那就可以開始去做數據採集的工作了,查詢出相應的數據,插入本地數據庫的表中。

 

最後一步:通過存儲過程採集遠程數據庫的數據並插入到本地的數據庫當中

複製代碼
/**
*從櫃檯同步客戶數據至臨時表
*/
create or replace PROCEDURE SP_SYNC_CUSTOMER_TEMP (UPDATE_TOTAL OUT NUMBER) IS
  INDEX_COUNT NUMBER;
  INDEX_TOTAL NUMBER;
  CURSOR CR IS
    select a.client_id, --客戶編號
           a.branch_no, --分支機構
           a.id_no, --證件號碼
           a.client_name, --客戶姓名
           a.client_status, --客戶狀態
           a.open_date, --開戶日期
           c.fund_account, --資金賬號
           c.main_flag, --主賬標識
           c.asset_prop, --資產屬性
           b.birthday, --生日日期
           b.address, --地址
           b.home_tel, --家庭電話
           b.e_mail, --郵箱
           b.fax, --傳真
           b.mobile_tel, --手機號碼
           b.office_tel, --單位電話
           b.zipcode, --郵政編碼
           b.account_data --開戶規範信息
      from hs_asset.client@HSAJ216 a
     inner join (select client_id,
                        birthday,
                        address,
                        home_tel,
                        e_mail,
                        fax,
                        mobile_tel,
                        office_tel,
                        zipcode,
                        account_data
                   from hs_asset.clientinfo@HSAJ216
                 union all
                 select client_id,
                        '19000101' as birthday,
                        address,
                        contact_tel as home_tel,
                        e_mail,
                        fax,
                        mobile_tel,
                        contact_tel as office_tel,
                        zipcode,
                        'A' as account_data
                   from hs_asset.organinfo@HSAJ216) b
        on a.client_id = b.client_id
     inner join hs_asset.fundaccount@HSAJ216 c
        on a.client_id = c.client_id
     where c.asset_prop = '0';
BEGIN
  insert into t_coll_result (id, CREATE_DATE, REMARK) 
  values (seq_t_coll_result_id.nextval, sysdate, 'START-現在開始執行【SP_SYNC_CUSTOMER_TEMP】清空客戶同步臨時表TEMP_SYNC_CUSTOMER...');
  EXECUTE IMMEDIATE 'TRUNCATE TABLE TEMP_SYNC_CUSTOMER';
  insert into t_coll_result (id, CREATE_DATE, REMARK) 
  values (seq_t_coll_result_id.nextval, sysdate, 'OVER-【SP_SYNC_CUSTOMER_TEMP】清空客戶同步臨時表TEMP_SYNC_CUSTOMER已完成...');

  insert into t_coll_result (id, CREATE_DATE, REMARK) 
  values (seq_t_coll_result_id.nextval, sysdate, 'START-現在開始執行【SP_SYNC_CUSTOMER_TEMP】向客戶同步臨時表導入數據TEMP_SYNC_CUSTOMER...');
  commit;

  INDEX_COUNT := 1;
  INDEX_TOTAL := 0;
  FOR C IN CR LOOP
    --客戶臨時表
    INSERT INTO TEMP_SYNC_CUSTOMER
      (CODE,
       ORGA_ID,
       ID_CARD,
       NAME,
       CLOSE_STATUS,
       ACCOUNT_CREATE_DATE,
       CAPITAL_ACCOUNT,
       BIRTHDAY,
       ADDRESS,
       TEL,
       BINDING_EMAIL,
       BINDING_MOBILE,
       MAIN_FLAG
       )
    VALUES
      (C.client_id, 
      C.branch_no, 
      C.id_no, 
      C.client_name, 
      C.client_status, 
      C.open_date, 
      C.fund_account, 
      C.birthday, 
      C.address, 
      C.home_tel, 
      C.e_mail, 
      C.mobile_tel,
      C.main_flag);
      
    INDEX_COUNT := (INDEX_COUNT + 1);
    INDEX_TOTAL := (INDEX_TOTAL + 1);
    
    IF INDEX_COUNT > 100000 THEN
      COMMIT;
      insert into t_coll_result (id, CREATE_DATE, REMARK) 
      values (seq_t_coll_result_id.nextval, sysdate, '【SP_SYNC_CUSTOMER_TEMP】已向TEMP_SYNC_CUSTOMER導入' || INDEX_TOTAL || '條數據...');
      commit;
      INDEX_COUNT := 1;
    END IF;
  END LOOP;

  insert into t_coll_result (id, CREATE_DATE, REMARK)
  values (seq_t_coll_result_id.nextval, sysdate, 'OVER-【SP_SYNC_CUSTOMER_TEMP】同步客戶臨時表TEMP_SYNC_CUSTOMER已完成,共導入' || INDEX_TOTAL || '條數據...');
  UPDATE_TOTAL := INDEX_TOTAL; 
  COMMIT;
END SP_SYNC_CUSTOMER_TEMP;
複製代碼

當然,我們不可能每次都手動去執行sql,所以可以結合oracle數據庫的定時任務,在每天的某個時刻自動去執行我們所寫的存儲過程,這樣就相對來說比較完美了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章