資料複製_Stream
本例子實現DML的捕獲,應用,佇列,沒有涉及傳播,規則等。
作業系統版本:
Linux net95 2.6.18-164.el5xen #1 SMP Thu Sep 3 04:47:32 EDT 2009 i686 i686 i386 GNU/Linux
Oracle版本:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
--**********************1.1,準備-資料來源*******************
conn system/obss;
create tablespace stream_tbs
datafile 'c:\stream_tbs_01.dbf' size 10m;
create user hr identified by hr default tablespace stream_tbs;
grant resource,connect to hr;
connect hr/hr;
CREATE TABLE employees(
employee_id NUMBER(6),
first_name VARCHAR2(20),
department_id NUMBER(4));
insert into employees values(1,'Mike',1);
insert into employees values(2,'John',1);
insert into employees values(3,'Jack',2);
commit;
CREATE UNIQUE INDEX employees_id_pk ON employees (employee_id);
ALTER TABLE employees ADD (CONSTRAINT employees_id_pk PRIMARY KEY (employee_id));
--*********************1.2,準備-目的地******************************
conn system/obss;
create tablespace stream_new_tbs
datafile 'c:\stream_new_tbs_01.dbf' size 10m;
create user hr_new identified by hr_new default tablespace stream_new_tbs;
grant resource,connect to hr_new;
connect hr_new/hr_new
CREATE TABLE employees_all(
employee_id NUMBER(6),
first_name VARCHAR2(20),
department_id NUMBER(4),
timestamp date);
CREATE UNIQUE INDEX employees_all_id_pk ON employees_all (employee_id);
ALTER TABLE employees_all ADD (CONSTRAINT employees_all_id_pk PRIMARY KEY (employee_id));
--*********************1.3,準備-捕獲與應用者************************
conn system/obss;
create tablespace stream_queue_tbs
datafile 'c:\stream_queue_tbs_01.dbf' size 10m;
GRANT DBA TO strmadmin IDENTIFIED BY strmadmin;
--ACCEPT streams_tbs PROMPT 'Enter Streams administrator tablespace on cpap.net: '
ALTER USER strmadmin DEFAULT TABLESPACE stream_queue_tbs
QUOTA UNLIMITED ON stream_queue_tbs;
--授予stream 管理許可權
connect sys/obss as sysdba;
BEGIN
DBMS_STREAMS_AUTH.GRANT_ADMIN_PRIVILEGE(
grantee => 'strmadmin',
grant_privileges => true);
END;
/
connect system/obss;
GRANT ALL ON hr_new.employees_all TO STRMADMIN;
-- 建立佇列(anydata queue):streams_queue,佇列表:streams_queue_table
conn strmadmin/strmadmin;
BEGIN
DBMS_STREAMS_ADM.SET_UP_QUEUE(
queue_table => 'strmadmin.streams_queue_table',
queue_name => 'strmadmin.streams_queue');
END;
/
--*************************2,捕獲與應用***********************************
CONNECT strmadmin/strmadmin;
--配置捕獲過程
BEGIN
DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => 'hr.employees',
streams_type => 'capture',
streams_name => 'capture_emp',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => false,
inclusion_rule => true);
END;
/
--設定 hr.employees例項化 scn(如果不在同一個資料庫,需要例項化)
DECLARE
iscn NUMBER; -- Variable to hold instantiation SCN value
BEGIN
iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();
DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN(
source_object_name => 'hr.employees',
source_database_name => 'ora10',
instantiation_scn => iscn);
END;
/
--create dml handler
CREATE OR REPLACE PROCEDURE emp_dml_handler(in_any IN ANYDATA) IS
lcr SYS.LCR$_ROW_RECORD;
rc PLS_INTEGER;
command VARCHAR2(30);
old_values SYS.LCR$_ROW_LIST;
BEGIN
-- Access the LCR
rc := in_any.GETOBJECT(lcr);
-- Get the object command type
command := lcr.GET_COMMAND_TYPE();
--Set the object_owner
lcr.SET_OBJECT_OWNER('HR_NEW');
-- Set the object_name in the row LCR
lcr.SET_OBJECT_NAME('EMPLOYEES_ALL');
-- Check for DELETE command on the hr.employees table
IF command = '+++DELETE' THEN
-- Set the command_type in the row LCR to INSERT
lcr.SET_COMMAND_TYPE('INSERT');
-- Get the old values in the row LCR
old_values := lcr.GET_VALUES('old');
-- Set the old values in the row LCR to the new values in the row LCR
lcr.SET_VALUES('new', old_values);
-- Set the old values in the row LCR to NULL
lcr.SET_VALUES('old', NULL);
-- Add a SYSDATE value for the timestamp column
lcr.ADD_COLUMN('new', 'TIMESTAMP', ANYDATA.ConvertDate(SYSDATE));
-- Apply the row LCR as an INSERT into the hr.emp_del table
lcr.EXECUTE(true);
elsIF command = 'DELETE' THEN
-- Set the command_type in the row LCR to INSERT
lcr.SET_COMMAND_TYPE('UPDATE');
-- Add a SYSDATE value for the timestamp column
lcr.ADD_COLUMN('new', 'TIMESTAMP', ANYDATA.ConvertDate(SYSDATE));
-- Apply the row LCR as an INSERT into the hr.emp_del table
lcr.EXECUTE(true);
-- elsIF command = 'DELETE' THEN
-- update hr_new.employees_all set timestamp=sysdate where employee_id=(lcr.get_value('old','EMPLOYEE_ID') ).getNumber();
-- commit;
else --insert,update
lcr.execute(true);
END IF;
END;
/
--set dml_handler for source table:INSERT/UPDATE/DELETE
BEGIN
DBMS_APPLY_ADM.SET_DML_HANDLER(
object_name => 'hr.employees',
object_type => 'TABLE',
operation_name => 'INSERT',
error_handler => false,
user_procedure => 'strmadmin.emp_dml_handler',
apply_database_link => NULL,
apply_name => NULL);
END;
/
BEGIN
DBMS_APPLY_ADM.SET_DML_HANDLER(
object_name => 'hr.employees',
object_type => 'TABLE',
operation_name => 'UPDATE',
error_handler => false,
user_procedure => 'strmadmin.emp_dml_handler',
apply_database_link => NULL,
apply_name => NULL);
END;
/
BEGIN
DBMS_APPLY_ADM.SET_DML_HANDLER(
object_name => 'hr.employees',
object_type => 'TABLE',
operation_name => 'DELETE',
error_handler => false,
user_procedure => 'strmadmin.emp_dml_handler',
apply_database_link => NULL,
apply_name => NULL);
END;
/
--建立佇列的訊息消費者(在佇列中放入訊息前必須設定消費者)
BEGIN
DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => 'hr.employees',
streams_type => 'dequeue',
streams_name => 'hr',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => false,
inclusion_rule => true);
END;
/
--配置應用過程
DECLARE
emp_rule_name_dml VARCHAR2(30);
emp_rule_name_ddl VARCHAR2(30);
BEGIN
DBMS_STREAMS_ADM.ADD_TABLE_RULES(
table_name => 'hr.employees',
streams_type => 'apply',
streams_name => 'apply_emp',
queue_name => 'strmadmin.streams_queue',
include_dml => true,
include_ddl => false,
source_database => 'ora10',
dml_rule_name => emp_rule_name_dml,
ddl_rule_name => emp_rule_name_ddl);
DBMS_APPLY_ADM.SET_ENQUEUE_DESTINATION(
rule_name => emp_rule_name_dml,
destination_queue_name => 'strmadmin.streams_queue');
END;
/
-- 建立消費訊息的過程
CREATE OR REPLACE PROCEDURE emp_dq (consumer IN VARCHAR2) AS
msg ANYDATA;
row_lcr SYS.LCR$_ROW_RECORD;
num_var pls_integer;
more_messages BOOLEAN := true;
navigation VARCHAR2(30);
BEGIN
navigation := 'FIRST MESSAGE';
WHILE (more_messages) LOOP
BEGIN
DBMS_STREAMS_MESSAGING.DEQUEUE(
queue_name => 'strmadmin.streams_queue',
streams_name => consumer,
payload => msg,
navigation => navigation,
wait => DBMS_STREAMS_MESSAGING.NO_WAIT);
IF msg.GETTYPENAME() = 'SYS.LCR$_ROW_RECORD' THEN
num_var := msg.GetObject(row_lcr);
DBMS_OUTPUT.PUT_LINE(row_lcr.GET_COMMAND_TYPE || ' row LCR dequeued');
END IF;
navigation := 'NEXT MESSAGE';
COMMIT;
EXCEPTION WHEN SYS.DBMS_STREAMS_MESSAGING.ENDOFCURTRANS THEN
navigation := 'NEXT TRANSACTION';
WHEN DBMS_STREAMS_MESSAGING.NOMOREMSGS THEN
more_messages := false;
DBMS_OUTPUT.PUT_LINE('No more messages.');
WHEN OTHERS THEN
RAISE;
END;
END LOOP;
END;
/
--啟動應用過程
BEGIN
DBMS_APPLY_ADM.SET_PARAMETER(
apply_name => 'apply_emp',
parameter => 'disable_on_error',
value => 'n');
END;
/
BEGIN
DBMS_APPLY_ADM.START_APPLY(
apply_name => 'apply_emp');
END;
/
--啟動捕獲過程
BEGIN
DBMS_CAPTURE_ADM.START_CAPTURE(
capture_name => 'capture_emp');
END;
/
--*************************3,驗證*************************************
--檢查無效物件
conn system/obss;
select * from dba_objects where owner in ('HR','HR_NEW','STRMADMIN') and status<>'VALID';
--驗證規則上下文
CONNECT strmadmin/strmadmin;
SELECT RULE_OWNER, RULE_NAME FROM DBA_STREAMS_RULES
WHERE STREAMS_NAME = 'APPLY_EMP' AND
STREAMS_TYPE = 'APPLY' AND
SCHEMA_NAME = 'HR' AND
OBJECT_NAME = 'EMPLOYEES' AND
RULE_TYPE = 'DML'
ORDER BY RULE_NAME;
COLUMN RULE_OWNER HEADING 'Rule Owner' FORMAT A15
COLUMN DESTINATION_QUEUE_NAME HEADING 'Destination Queue' FORMAT A30
SELECT RULE_OWNER, DESTINATION_QUEUE_NAME
FROM DBA_APPLY_ENQUEUE
WHERE RULE_NAME =any(SELECT RULE_NAME FROM DBA_STREAMS_RULES
WHERE STREAMS_NAME = 'APPLY_EMP' AND
STREAMS_TYPE = 'APPLY' AND
SCHEMA_NAME = 'HR' AND
OBJECT_NAME = 'EMPLOYEES' AND
RULE_TYPE = 'DML')
ORDER BY DESTINATION_QUEUE_NAME;
--在源表進行dml操作
connect hr/hr;
insert into employees values(4,'Mike',1);
commit;
update employees set first_name='AAA';
commit;
delete from employees where employee_id=3;
commit;
--在目標表檢查結果:
CONNECT strmadmin/strmadmin;
SELECT employee_id, first_name, timestamp
FROM hr_new.employees_all ORDER BY employee_id;
SELECT MSG_ID, MSG_STATE, CONSUMER_NAME
FROM AQ$STREAMS_QUEUE_TABLE ORDER BY MSG_ID;
--dequeue message:
SET SERVEROUTPUT ON SIZE 100000
EXEC emp_dq('HR');
--***************clear site***************
conn system/obss;
drop user hr cascade;
drop user hr_new cascade;
drop user strmadmin cascade;
drop tablespace stream_tbs including contents and datafiles;
drop tablespace stream_new_tbs including contents and datafiles;
drop tablespace stream_queue_tbs including contents and datafiles;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/18922393/viewspace-696838/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一次通過stream複製解決資料單向複製的案例
- oracle stream之schema級複製Oracle
- DM7資料複製之資料庫級複製資料庫
- 資料共享(淺複製)與資料獨立(深複製)
- 資料庫複製(一)–複製介紹資料庫
- 資料庫複製資料庫
- 複製資料庫資料庫
- Day 7.5 資料型別總結 + 複製 淺複製 深複製資料型別
- Redis的資料複製Redis
- MySQL複製資料表MySql
- 資料複製_GoldenGateGo
- DM7資料複製之模式級複製模式
- ORACLE10g Stream表級複製配置Oracle
- Oracle 10g stream 一對多複製Oracle 10g
- Oracle Stream(3)--Stream與高階複製和邏輯Dataguard的比較Oracle
- 資料庫主從複製資料庫
- 資料複製策略綜述
- Oracle活動資料庫複製Oracle資料庫
- 資料備份與複製
- RMAN複製資料庫(十)資料庫
- RMAN複製資料庫(九)資料庫
- RMAN複製資料庫(八)資料庫
- RMAN複製資料庫(七)資料庫
- RMAN複製資料庫(六)資料庫
- RMAN複製資料庫(五)資料庫
- RMAN複製資料庫(四)資料庫
- RMAN複製資料庫(三)資料庫
- RMAN複製資料庫(二)資料庫
- RMAN複製資料庫(一)資料庫
- 使用RMAN複製資料庫資料庫
- 使用OEM複製資料庫資料庫
- 複製和資料庫映象資料庫
- 手動複製資料庫資料庫
- 資料複製_物化檢視
- oracle rman複製資料庫Oracle資料庫
- 複製資料庫步驟資料庫
- SqlBulkCopy 複製批量插入資料SQL
- 使用Java Stream API中DistinctBy刪除重複資料JavaAPI