什麼是DBLINK? dblink(Database Link)資料庫鏈接顧名思義就是資料庫的鏈接 ,就像電話線一樣,是一個通道,當我們要跨本地資料庫,訪問另外一個資料庫表中的數據時,本地資料庫中就必須要創建遠程資料庫的dblink,通過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資料庫的定時任務,在每天的某個時刻自動去執行我們所寫的存儲過程,這樣就相對來說比較完美了。
結束語:為了不讓生活留下遺憾和後悔,我們應該儘可能抓住一切改變生活的機會。
可愛博主:AlanLee
博客地址:http://www.cnblogs.com/AlanLee
本文出自博客園,歡迎大家加入博客園。