Oracle 流stream将删除的数据保存

Oracle 流stream将删除的数据保存


--实验的目的是捕获hr.employees表的删除行,将删除行插入到emp_del表中。
--设置初始化参数

AQ_TM_PROCESSES=1
COMPATIBLE=9.2.0
LOG_PARALLELISM=1


--查看数据库的名称,我的为ora9,将以下的ora9全部替换为你的数据库名称
--数据库为归档模式
--建立表emp_del,用于存放EMPLOYEES的删除数据

conn hr/hr
CREATE TABLE emp_del( employee_id    NUMBER(6), first_name     VARCHAR2(20), last_name      VARCHAR2(25), email          VARCHAR2(25), phone_number   VARCHAR2(20), hire_date      DATE, job_id         VARCHAR2(10), salary         NUMBER(8,2), commission_pct NUMBER(2,2), manager_id     NUMBER(6), department_id  NUMBER(4),timestamp      DATE);CREATE UNIQUE INDEX emp_del_id_pk ON emp_del (employee_id);ALTER TABLE emp_del ADD (CONSTRAINT emp_del_id_pk PRIMARY KEY (employee_id));


--建立管理用户,设定默认表空间,授权

conn / as sysdba
drop user strmadmin cascade;
GRANT CONNECT, RESOURCE, SELECT_CATALOG_ROLE TO strmadmin IDENTIFIED BY strmadmin;
ALTER USER strmadmin DEFAULT TABLESPACE users;GRANT ALL ON hr.emp_del  TO strmadmin;GRANT EXECUTE ON DBMS_APPLY_ADM        TO strmadmin;
GRANT EXECUTE ON DBMS_AQ               TO strmadmin;
GRANT EXECUTE ON DBMS_AQADM            TO strmadmin;
GRANT EXECUTE ON DBMS_CAPTURE_ADM      TO strmadmin;
GRANT EXECUTE ON DBMS_FLASHBACK        TO strmadmin;
GRANT EXECUTE ON DBMS_STREAMS_ADM      TO strmadmin;BEGIN DBMS_RULE_ADM.GRANT_SYSTEM_PRIVILEGE(privilege    => DBMS_RULE_ADM.CREATE_RULE_SET_OBJ, grantee      => 'strmadmin', grant_option => FALSE);
END;
/BEGIN DBMS_RULE_ADM.GRANT_SYSTEM_PRIVILEGE(privilege    => DBMS_RULE_ADM.CREATE_RULE_OBJ, grantee      => 'strmadmin', grant_option => FALSE);
END;
/

--建立流队列,名称叫streams_queue ,用于存储捕获的变化

CONNECT strmadmin/strmadmin
EXEC DBMS_STREAMS_ADM.SET_UP_QUEUE();

--配置logmnr使用的表空间,我们就用tools

conn / as sysdba
EXECUTE DBMS_LOGMNR_D.SET_TABLESPACE('TOOLS');

--增强日志的模式

ALTER TABLE hr.employees  ADD SUPPLEMENTAL LOG GROUP log_group_employees_pk(employee_id) ALWAYS;


--配置捕获程序

CONNECT strmadmin/strmadmin
BEGINDBMS_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);
END;
/


--设置scn

DECLAREiscn  NUMBER;         -- Variable to hold instantiation SCN value
BEGINiscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN(source_object_name    => 'hr.employees',source_database_name  => 'ora9',instantiation_scn     => iscn);
END;
/

--配置叫emp_agent的代理程序

BEGINDBMS_AQADM.DROP_AQ_AGENT(agent_name => 'emp_agent');
END;
/BEGINDBMS_AQADM.CREATE_AQ_AGENT(agent_name => 'emp_agent');DBMS_AQADM.ENABLE_DB_ACCESS(agent_name  => 'emp_agent',db_username => 'strmadmin');
END;
/

--建立队列订户

DECLAREsubscriber SYS.AQ$_AGENT;
BEGINsubscriber :=  SYS.AQ$_AGENT('emp_agent', NULL, NULL);  SYS.DBMS_AQADM.ADD_SUBSCRIBER(queue_name          =>  'strmadmin.streams_queue',subscriber                  =>  subscriber,rule                =>  NULL,transformation      =>  NULL);
END;
/

--建立存储过程enq_row_lcr 

CREATE OR REPLACE PROCEDURE enq_row_lcr(in_any IN SYS.ANYDATA) ISenqopt       DBMS_AQ.ENQUEUE_OPTIONS_T;mprop        DBMS_AQ.MESSAGE_PROPERTIES_T;recipients   DBMS_AQ.AQ$_RECIPIENT_LIST_T;enq_eventid  RAW(16);
BEGINmprop.SENDER_ID := SYS.AQ$_AGENT(name     => 'emp_agent',address  => NULL,protocol => NULL);recipients(1) := SYS.AQ$_AGENT(name     => 'emp_agent',address  => NULL,protocol => NULL);mprop.RECIPIENT_LIST := recipients;DBMS_AQ.ENQUEUE(queue_name         => 'strmadmin.streams_queue',enqueue_options    => enqopt,message_properties => mprop,payload            => in_any,msgid              => enq_eventid);
END;
/

--建立DML处理存储过程

CREATE OR REPLACE PROCEDURE emp_dml_handler(in_any IN SYS.ANYDATA) ISlcr          SYS.LCR$_ROW_RECORD;rc           PLS_INTEGER;command      VARCHAR2(10);old_values   SYS.LCR$_ROW_LIST;
BEGIN-- Re-enqueue the row LCR for explicit dequeue by another applicationenq_row_lcr(in_any);-- Access the LCRrc := in_any.GETOBJECT(lcr);-- Get the object command typecommand := lcr.GET_COMMAND_TYPE();-- Check for DELETE command on the hr.employees tableIF command = 'DELETE' THEN-- Set the command_type in the row LCR to INSERTlcr.SET_COMMAND_TYPE('INSERT');-- Set the object_name in the row LCR to EMP_DELlcr.SET_OBJECT_NAME('EMP_DEL');-- Get the old values in the row LCRold_values := lcr.GET_VALUES('old');-- Set the old values in the row LCR to the new values in the row LCRlcr.SET_VALUES('new', old_values);-- Set the old values in the row LCR to NULLlcr.SET_VALUES('old', NULL);-- Add a SYSDATE value for the timestamp columnlcr.ADD_COLUMN('new', 'TIMESTAMP', SYS.AnyData.ConvertDate(SYSDATE));--  Apply the row LCR as an INSERT into the EMP_DEL tablelcr.EXECUTE(true);END IF;
END;
/

--配置DML管理者,为hr.employees

BEGINDBMS_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);
END;
/BEGINDBMS_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);
END;
/BEGINDBMS_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);
END;
/

--建立存储过程为出列和再入列事件

CREATE OR REPLACE PROCEDURE emp_dq (consumer IN VARCHAR2) ASdeqopt       DBMS_AQ.DEQUEUE_OPTIONS_T;mprop        DBMS_AQ.MESSAGE_PROPERTIES_T;msgid        RAW(16);payload      SYS.AnyData;new_messages BOOLEAN := TRUE;row_lcr      SYS.LCR$_ROW_RECORD;tc           pls_integer;next_trans   EXCEPTION;no_messages  EXCEPTION; pragma exception_init (next_trans, -25235);pragma exception_init (no_messages, -25228);
BEGINdeqopt.consumer_name := consumer;deqopt.wait := 1;WHILE (new_messages) LOOPBEGINDBMS_AQ.DEQUEUE(queue_name          =>  'strmadmin.streams_queue',dequeue_options     =>  deqopt,message_properties  =>  mprop,payload             =>  payload,msgid               =>  msgid);COMMIT;deqopt.navigation := DBMS_AQ.NEXT;IF (payload.GetTypeName = 'SYS.LCR$_ROW_RECORD') THENtc := payload.GetObject(row_lcr);   DBMS_OUTPUT.PUT_LINE(row_lcr.GET_COMMAND_TYPE || ' row LCR dequeued');END IF;                       EXCEPTIONWHEN next_trans THENdeqopt.navigation := DBMS_AQ.NEXT_TRANSACTION;WHEN no_messages THENnew_messages  := FALSE;DBMS_OUTPUT.PUT_LINE('No more events');END;END LOOP; 
END;
/

--配置应用程序

BEGINDBMS_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 => 'ora9');
END;
/

--启动应用程序

BEGINDBMS_APPLY_ADM.SET_PARAMETER(apply_name  => 'apply_emp', parameter   => 'disable_on_error', value       => 'n');
END;
/BEGINDBMS_APPLY_ADM.START_APPLY(apply_name  => 'apply_emp');
END;
/

--启动捕获程序

BEGINDBMS_CAPTURE_ADM.START_CAPTURE(capture_name  => 'capture_emp');
END;
/--对hr.employees进行插入,删除和修改
conn hr/hr
INSERT INTO hr.employees values(207, 'JOHN', 'SMITH', 'JSMITH@MYCOMPANY.COM', NULL, '07-JUN-94', 'AC_ACCOUNT', 777, NULL, NULL, 110);
COMMIT;UPDATE hr.employees SET salary=5999 WHERE employee_id=206;
COMMIT;DELETE FROM hr.employees WHERE employee_id=207;
COMMIT;CONNECT strmadmin/strmadmin
SELECT * FROM hr.emp_del;SELECT MSG_ID, MSG_STATE, CONSUMER_NAME FROM AQ$STREAMS_QUEUE_TABLE;EXEC emp_dq('emp_agent');SELECT MSG_ID, MSG_STATE, CONSUMER_NAME FROM AQ$STREAMS_QUEUE_TABLE;

--显示应用程序的错误

COLUMN APPLY_NAME HEADING 'Apply|Process|Name' FORMAT A8
COLUMN SOURCE_DATABASE HEADING 'Source|Database' FORMAT A8
COLUMN LOCAL_TRANSACTION_ID HEADING 'Local|Transaction|ID' FORMAT A11
COLUMN ERROR_MESSAGE HEADING 'Error Message' FORMAT A50SELECT APPLY_NAME, SOURCE_DATABASE, LOCAL_TRANSACTION_ID, ERROR_MESSAGEFROM DBA_APPLY_ERROR;


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/327299.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【教程向】从零开始创建浏览器插件(三)解决 Chrome 扩展中弹出页面、背景脚本、内容脚本之间通信的问题

第三步:解决 Chrome 扩展中弹出页面、背景脚本、内容脚本之间通信的问题 Chrome 扩展开发中,弹出页面(Popup)、背景脚本(Background Script)、内容脚本(Content Script)各自拥有独立…

微信小程序知识点归纳(一)

前言:适用于有一定基础的前端开发同学,完成从网页开发到小程序开发的知识转换。 先立框架,后砌墙壁 回顾:了解微信小程序开发流程-CSDN博客 初始页面结构,三部分pages、utils、配置,分别存放页面、工具类…

OpenAI Whisper 语音转文本实验

为了实现语音方式与大语言模型的对话,需要使用语音识别(Voice2Text)和语音输出(Text2Voice)。感觉这项技术已比较成熟了,国内也有许多的机构开发这项技术,但是像寻找一个方便测试的技术居然还不…

使用Vue调用ColaAI Plus大模型,实现聊天(简陋版)

首先去百度文心注册申请自己的api 官网地址&#xff1a;LuckyCola 注册点开个人中心 查看这个文档自己申请一个ColaAI Plus定制增强大模型API | LuckyColahttps://luckycola.com.cn/public/docs/shares/api/colaAi.html来到vue的页面 写个样式 <template><Header …

C++ | Leetcode C++题解之第79题单词搜索

题目&#xff1a; 题解&#xff1a; class Solution { public:bool exist(vector<vector<char>>& board, string word) {rows board.size();cols board[0].size();for(int i 0; i < rows; i) {for(int j 0; j < cols; j) {if (dfs(board, word, i, …

dnf手游攻略,新手入坑必备!

一、角色创建策略 在DNF手游中&#xff0c;角色创建是玩家初入游戏的首要步骤。为最大化游戏体验和收益&#xff0c;新手玩家通常建议创建三个角色&#xff1a;一个主账号和两个副账号。 主账号选择 主账号的选择应基于玩家个人的喜好和对职业的熟悉程度。无论选择哪个职业&a…

Gone框架介绍17 - 创建一个可运行在生产环境的Web项目

gone是可以高效开发Web服务的Golang依赖注入框架 github地址&#xff1a;https://github.com/gone-io/gone 文档原地址&#xff1a;https://goner.fun/zh/guide/auto-gen-priest.html 请帮忙在github上点个 ⭐️吧&#xff0c;这对我很重要 &#xff1b;万分感谢&#xff01;&a…

视频汇聚管理/安防监控系统EasyCVR如何开启和调用验证码登录接口?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。视频汇聚融合管理平台EasyCVR既具备传统安防视…

C语言写扫雷游戏(数组和函数实践)

目录 最后是代码啦&#xff01; 手把手教你用C语言写一个扫雷游戏&#xff01; 1.我们搭建一下这个多文件形式的扫雷游戏文件结构 2.在主函数里面设置一个包含游戏框架的菜单 菜单可以方便游戏玩家选择要进行的动作和不断地进行下一局。 3.switch语句连接不同的结果 菜单可…

AI与边缘设备,光子芯片,AI规划能力,自然语言驱动的AI游戏

1 Archetype AI 发布了一个创新的人工智能平台 —— Newton 这是一个专门为理解物理世界设计的基础模型。 Newton 设计用于连接实时物理数据&#xff0c;其数据源是全球数十亿传感器的输入&#xff0c;实现了对物理现实的直接解读。 利用从各种传感器&#xff08;如加速度计…

被动防护不如主动出击

自网络的诞生以来&#xff0c;攻击威胁事件不断涌现&#xff0c;网络攻防对抗已然成为信息时代背景下的一场无硝烟的战争。然而&#xff0c;传统的网络防御技术&#xff0c;如防火墙和入侵检测技术&#xff0c;往往局限于一种被动的敌暗我明的防御模式&#xff0c;面对攻击者无…

Windows Qt中支持heic 图片显示

安装vcpkg&#xff1a; git clone https://github.com/microsoft/vcpkg 执行脚本&#xff1a; .\vcpkg\bootstrap-vcpkg.bat 在安装之前如果需要指定vs的编译器&#xff0c; 在如下文件中做更改&#xff0c; 我指定的是用vs2019编译的&#xff1a; D:\vcpkg\vcpkg\triplets 增…

android图标底色问题,debug与release不一致

背景 在android 8&#xff08;sdk 26&#xff09;之前的版本&#xff0c;直接使用图片文件作为图标&#xff0c;开发时比较容易控制图标&#xff0c;但是不同的安卓定制版本就不容易统一图标风格了。 在android 8及之后的版本&#xff0c;图标对应的是ic_launcher.xml&#x…

VC 编程开发中的 封装类 :log日志类 和SQL server 操作类 源代码

VC 编程开发中的 封装类 &#xff1a;日志类 和SQL server 操作类 源代码 在VC&#xff08;Visual C&#xff09;开发中&#xff0c;日志文件输出是一个至关重要的环节&#xff0c;它对于程序调试、问题排查以及系统监控等方面都具有不可替代的作用。以下是对日志文件输出在VC开…

网站localhost和127.0.0.1可以访问,本地ip不可访问解决方案

部署了一个网站, 使用localhost和127.0.0.1加端口号可以访问, 但是使用本机的ip地址加端口号却不行. 原因可能有多种. 可能的原因: 1 首先要确认是否localhost对应的端口是通的(直接网址访问), 以及你无法访问的那个本机ip是否正确(使用ping测试)&#xff1b; 2 检查本机的防火…

好题总结汇总

好题总结汇总 总结一些做完很有收获的题。 一、经典问题 DP的结合 1、题意&#xff1a; 给定 n n n 种颜色的球的数量 a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1​,a2​,...,an​&#xff0c;选出一些不同种类的球(也就是在n种球中选球的任意情况)&#xff0c;将球…

企业如何通过云服务器实现全球连通运营

如果说互联网是一座桥&#xff0c;连接起了全球各地的信息&#xff0c;那云服务器就如同一座高速公路&#xff0c;帮助企业轻松实现跨国家、跨时区的全球运营。 这个听起来像科幻电影的情节其实已经成为了我们现实生活的一部分。现在就来具体看一下如何做到这一点吧。 其一&…

【Linux】Linux——Centos7安装

【Linux】Linux——Centos7安装 新建虚拟机 选择自定义安装下一步 硬件兼容性使用默认最高即可&#xff0c;下一步 选择稍后安装操作系统&#xff0c;下一步 选择客户机操作系统为 Linux &#xff0c;并选择下方版本为所安装 Linux 镜像同版本&#xff0c;下一步 虚拟机名称与…

idea-自我常见配置

1. 主题配置 2. 显示方法分隔符 Editor->General->Appearance 3. 忽略大小写提示 Editor->General->Code Completion 4. 自动导包 Editor->general->Auto Import 5. 取消单行显示Tabs Editor->General->Editor Tabs 效果如下图&#xff1a; 6. 设置…

idea启动Jsp非maven项目时的一些步骤

文章目录 事前准备eclipse项目举例idea打开eclipse项目安装tomcat配置启动项启动测试 一些小问题到不到servlet 事前准备 非社区版idea【否则启动项无法配置】tomcatmysql eclipse项目举例 idea打开eclipse项目 剩下的全部下一步即可 安装tomcat 自己的文章 Javaweb - t…