最近项目中需要做一个数据同步功能,就是要将一个数据库里面的信息定时的同步到另外一个数据库中,这样的话就需要用到储存过程 触发器 定时器 和dblink.
以前没写过储存过程,恰好利用这次机会练练手,特写此博客,方便以后查阅:
序号 对象名称 类型 说明
1 synBaseDataTemp table 临时表
2 synBaseDataHistory table 同步历史记录
3 synBaseDataTemp_Sequence SEQUENCE 设置字段ID自增
4 tri_synBaseDataTemp TRIGGER 当临时表中有新增记录时,ID自动增加1
5 tri_基础数据表名 TRIGGER 当CCS基础数据表有增 删 改操作时,会自动触发在ECCS基础数据
表增加记录(共32个)
6 baseDataSynProc procedure 将临时表中记录的信息同步到ECCS中,同时将同步记录
增加到synBaseDataHistory中,并将同步的synBaseDataTemp信息删除
创建同步相关表:
[sql] view plaincopy
/*创建表synBaseDataTemp*/
CREATE TABLE synBaseDataTemp
(
id number(15,0) NOT NULL,
condition varchar2(300) not null,
tableName varchar2(40) not null,
operateType varchar2(20) not null,
operateDate date,
failFlag varchar2(1),
failTimes integer,
PRIMARY KEY (id)
);
comment on table synBaseDataTemp is '同步临时表';
comment on column synBaseDataTemp.id is '自增列,主键';
comment on column synBaseDataTemp.condition is '表主键条件';
comment on column synBaseDataTemp.tableName is '表名';
comment on column synBaseDataTemp.operateType is '操作类型';
comment on column synBaseDataTemp.operateDate is '操作时间';
comment on column synBaseDataTemp.failFlag is '失败标志,1失败';
comment on column synBaseDataTemp.failTimes is '失败次数';
/*创建表synHistory*/
CREATE TABLE synBaseDataHistory
(
id number(15,0) NOT NULL,
condition varchar2(300) not null,
tableName varchar2(40) not null,
operateType varchar2(20) not null,
operateDate date,
PRIMARY KEY (id)
);
comment on table synBaseDataHistory is '同步历史记录表';
comment on column synBaseDataHistory.id is '自增列,主键';
comment on column synBaseDataHistory.condition is '表主键条件';
comment on column synBaseDataHistory.tableName is '表名';
comment on column synBaseDataHistory.operateType is '操作类型';
comment on column synBaseDataHistory.operateDate is '操作时间';
/*为表synBaseDataTemp的ID创建自增列*/
--创建自动增长序列
CREATE SEQUENCE synBaseDataTemp_Sequence
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE
CACHE 10;
--创建触发器
CREATE OR REPLACE TRIGGER tri_synBaseDataTemp BEFORE
insert ON synBaseDataTemp FOR EACH ROW
begin
select synBaseDataTemp_Sequence.nextval into:New.id from dual;
end;
为每张表创建触发器,共32张表,以一张表作为实例:
[sql] view plaincopy
</pre><p> </p><pre class="sql" name="code">/*为表GGSYSTEM创建触发器,当有相关操作时,在synBaseDataTemp中存入相关信息*/
CREATE OR REPLACE TRIGGER tri_GGSYSTEM
AFTER INSERT or DELETE or UPDATE --指定触发时机触发
ON GGSYSTEM
REFERENCING NEW as new_value
FOR EACH ROW --说明创建的是行级触发器
BEGIN
--将修改前数据插入到临时表synBaseDataTemp,供存储过程调用。
if inserting then
INSERT INTO synBaseDataTemp
(condition, tableName, operateType, operateDate)
VALUES
('SYSTEMCODE=' || chr(39) || :new_value.systemCode || chr(39),
'GGSYSTEM',
'INSERT',
sysdate);
elsif updating then
INSERT INTO synBaseDataTemp
(condition, tableName, operateType, operateDate)
VALUES
('SYSTEMCODE=' || chr(39) || :new_value.systemCode || chr(39),
'GGSYSTEM',
'UPDATE',
sysdate);
elsif deleting then
INSERT INTO synBaseDataTemp
(condition, tableName, operateType, operateDate)
VALUES
('SYSTEMCODE=' || chr(39) ||
ld.systemCode || chr(39),
'GGSYSTEM',
'DELETE',
sysdate);
end if;
END;
创建触发器后,下面是存储过程:
[sql] view plaincopy
--包头
create or replace package baseDataSyn is
-- Author : zhengfazhen
-- Created : 2011-12-31
procedure baseDataSynProc; --从CCS同步到ECCS
end baseDataSyn;
--包体
CREATE OR REPLACE PACKAGE BODY baseDataSyn is
-- Author : zhengfazhen
-- Created : 2011-12-31
--同步 存储过程
PROCEDURE baseDataSynProc IS
v_id number(15, 0); --临时表ID
condition varchar2(400); --临时表主键条件
tableName varchar2(50); --临时表中存入的表名
operateType varchar2(10); --操作类型:insert update delete
insertSql varchar2(400); --插入sql
updateSql varchar2(2000); --更新sql
deleteSql varchar2(500); --删除sql
synLogSql varchar2(500); --历史记录sql
columStr varchar2(1000); --非主键列名字符串
gguserColum varchar2(500); --GGUSER非主键且除去(password,PASSWORDSETDATE,PASSWORDEXPIREDATE,LOCKSTATUS,UPDATEPWDIND,LOGINERRTIMES)字段
gguserSql varchar2(500); --为gguser赋值默认值SQL
failSql varchar2(500); --异常处理SQL
flag varchar2(1);
--查询临时表中所有记录
cursor c_synTemp is
select c.id, c.condition, c.tablename, c.operatetype, c.operatedate
from synBaseDataTemp c
where 1 = 1
order by operateDate ASC;
c_synTemp_row c_synTemp%rowtype;
--返回非主键列名
cursor c_columName(tableName varchar2) is
select uc.COLUMN_NAME
from user_tab_columns uc
where uc.COLUMN_NAME not in
(select col.column_name
from user_constraints con, user_cons_columns col
where con.constraint_name = col.constraint_name
and con.constraint_type = 'P'
and col.table_name = tableName)
and uc.TABLE_NAME = tableName;
c_row c_columName%rowtype;
BEGIN
for c_synTemp_row in c_synTemp loop
begin
v_id := c_synTemp_row.id;
condition := c_synTemp_row.condition;
tableName := c_synTemp_row.tableName;
operateType := c_synTemp_row.operateType;
flag := '1';
/*拼接返回的非主键列名start*/
for c_row in c_columName(tableName) loop
if flag = '1' then
columStr := c_row.COLUMN_NAME;
flag := '0';
else
columStr := columStr || ',' || c_row.COLUMN_NAME;
end if;
end loop;
/*拼接返回的非主键列名end*/
/*同义词 eccs_表名*/
insertSql := 'insert into eccs_' || tableName ||
' (select * from ' || tableName || ' where ' ||
condition || ')';
updateSql := 'update eccs_' || tableName || ' set
(' || columStr || ')=(select ' || columStr ||
' from ' || tableName || ' where ' || condition ||
') where ' || condition;
deleteSql := 'delete from eccs_' || tableName || ' where ' ||
condition;
synLogSql := 'insert into synBaseDataHistory (select st.id,st.condition,st.tablename,st.operatetype,st.operatedate from synBaseDataTemp st where id=:1)';
failSql := 'update synBaseDataTemp set failFlag=' || chr(39) || '1' ||
chr(39) || 'where id=' || v_id;
/*GGUSER表特殊处理*/
gguserSql := 'update eccs_' || tableName ||
' set LOCKSTATUS=' || chr(39) || '1' || chr(39) ||
', UPDATEPWDIND=' || chr(39) || '1' || chr(39) ||
', LOGINERRTIMES=' || chr(39) || '0' || chr(39) ||
' where ' || condition;
gguserColum := 'USERCNAME,USERTNAME,USERENAME,SEAL,COMPANYCODE,ISSUECOMPANY,ACCOUNTCODE,PHONE,MOBILE,' ||
'ADDRESS,POSTCODE,EMAIL,USERIND,LOGINSYSTEM,CREATORCODE,CREATETIME,UPDATERCODE,' ||
'UPDATETIME,VALIDIND,REMARK,FLAG,SEX,ALIASCNAME,ALIASTNAME,ALIASENAME,UWINITIAL';
if tableName = 'GGUSER' then
updateSql := 'update eccs_' || tableName ||
' set
(' || gguserColum ||
')=(select ' || gguserColum || ' from ' || tableName ||
' where ' || condition || ') where ' || condition;
end if;
if operateType = 'INSERT' then
EXECUTE IMMEDIATE insertSql; --同步数据
if tableName = 'GGUSER' then
EXECUTE IMMEDIATE gguserSql; --赋默认值
end if;
EXECUTE IMMEDIATE synLogSql
USING v_id; --插入历史记录表
delete from synBaseDataTemp where id = v_id; --删除临时表中的信息
commit;
elsif operateType = 'UPDATE' then
EXECUTE IMMEDIATE updateSql;
EXECUTE IMMEDIATE synLogSql
USING v_id;
delete from synBaseDataTemp where id = v_id;
commit;
elsif operateType = 'DELETE' then
EXECUTE IMMEDIATE deleteSql;
EXECUTE IMMEDIATE synLogSql
USING v_id;
delete from synBaseDataTemp where id = v_id;
commit;
end if;
exception when others then
rollback;
EXECUTE IMMEDIATE failSql;--更新异常标志
commit;
end;
end loop;
END baseDataSynProc;
end baseDataSyn;
创建job,定时执行储存过程:
[sql] view plaincopy
BEGIN
DBMS_SCHEDULER.CREATE_JOB(job_name => 'jobsynproc', --job名称,自己设
job_type => 'STORED_PROCEDURE', --类型为存储过程
job_action => 'ccs_synproc', --存储过程名称为proc
start_date => to_date('30-12-2011 00:00:00',
'dd-mm-yyyy hh24:mi:ss'), --开始执行时间
enabled => TRUE, --自动启用
auto_drop => false,
repeat_interval => 'FREQ=Monthly;Interval=1');
END;
在这之前,必须授权用户有增删改的权限,并且创建同义词,以便储存过程能顺利执行:
1.依照DBA用户登录执行sql命令:grant create synonym to 被授权用户;
2.如果你需要对某表可以修改等权限:需执行:grant select,insert,update on monitor_sys_log to 被授权用户;
3.用"被授权用户"登录创建同义词:create synonym monitor_sys_log(同义词名称) for 拥有表用户.monitor_sys_log(表名);
分享到:
相关推荐
第二部分讲述了db2开发工具方面的知识,以及如何更有效地开发存储过程、用户自定义函数和触发器。第三部分讲述了开发者在java ee和.net架构下开发数据应用的最佳实践。同时,在附录a中,针对sql pl与plsql做了集中...
●oracle网络和存储结构 ●安全性 ●sql ●oracle恢复管理器和oracle闪回技术 ●资源管理器 ●oracle自动存储管理 ●oracle调度程序 ●自动工作负荷知识库 ●性能调整 作译者 John Watson就职...
●oracle网络和存储结构 ●安全性 ●sql ●oracle恢复管理器和oracle闪回技术 ●资源管理器 ●oracle自动存储管理 ●oracle调度程序 ●自动工作负荷知识库 ●性能调整 作译者 John Watson就职...
如果你是临时抱佛脚的,这个资源完全适合你去实践: 1 PLSQL 程序设计简介 2 PLSQL块结构和组成元素 3 PLSQL流程控制语句 4 游标 5 异常处理 6 过程与函数 7 程序包的创建和应用 8 触发器
体验数据库的应用→认识Oracle的工作环境、体验Oracle 10g环境中常用工具操作→数据库的创建与管理→数据表的创建与管理→管理视图→SQL编程语言→PL/SQL编程语言→管理PLSQL存储过程与触发器→管理安全性→数据库...
结合开发应用Oracle数据库的实践经验编撰而成的,书中编排的内容次序非常适合于读者学习和把握Oracle的脉络,书中所选择的问题都是在实际开发应用Oracle过程中经常遇到和所要解决的。通过学习解决这些问题的方法,...
Oracle的工作环境、体验Oracle 10g环境中常用工具操作→数据库的创建与管理→数据表的创建与管理→管理视图→SQL编程语言→PL/SQL编程语言→管理PLSQL存储过程与触发器 →管理安全性→数据库安全性→Oracle数据库的...
结合开发应用Oracle数据库的实践经验编撰而成的,书中编排的内容次序非常适合于读者学习和把握Oracle的脉络,书中所选择的问题都是在实际开发应用Oracle过程中经常遇到和所要解决的。通过学习解决这些问题的方法,...
5.7 如何创建存储过程以及创建存储过程的原因 146 5.8 函数的创建和使用 149 5.9 调用PL/SQL程序 151 5.10 本章测验 152 第6章 数据库管理员 153 6.1 了解DBA的工作 154 6.2 执行日常操作 154 6.2.1 体系结构...
实现了项目分析与数据表创建、SQL 语句、视图和存储过程、触发器等部分。通过这次高级数据库应用实验(Oracle)项目的实践,我巩固了 SQL 语法,为之后的 Oracle 数据库的深入学习打下了基础。 这个项目是我大三写的...
7.10.2 存储过程的建立及执行 114 7.10.3 调用存储过程的方法 114 7.10.4 带参数的存储过程 114 7.10.5 删除存储过程 114 7.11 函数 114 7.11.1 创建函数 114 7.12 触发器 114 7.13 树状结构的存储与展示 114 7.13.1...
5.7 如何创建存储过程以及创建存储过程的原因 5.8 函数的创建和使用 5.9 调用PL/SQL程序 5.10 本章 测验 第6章 数据库管理员 6.1 了解DBA的工作 6.2 执行日常操作 6.2.1 体系结构和设计 6.2.2 容量规划 6.2.3 备份...
适用于刚入门oracle的同志,包括表,视图,函数,游标,存储过程的创建,例子简单易懂,注释详细,不要错过!
他撰写了6本有关Oracle技术著作,其中包括清华大学出版社引进并出版的《Oracle Database 11gPL/SQL程序设计》、《Oracle Database11gPL/SQL编程实践》等。 第I部分开发组件 第1章 架构 3 1.1 通用的客户端-服务器 ...
二、课程设计报告提纲 (1) 课程设计的题目、系统的总体功能描述 (2) 需求分析(概括描述、DFD、DD) (3) 数据库概念结构设计(局部E-R图、基本E-R图) (4) 数据库逻辑结构设计(关系模式—列表形式、存储过程、触发器、...
这是本人在实践中收集总结的,有存储过程、序列、游标、触发器、索引及其它一些常用的语句(如日期、over partion by具体使用包括一些例子),还有两本高清这方面的书,一起放在里面,方便大家学习。
本书涉及不同平台上数据的排序、过滤和分组,以及表、视图、联结、子查询、游标、存储过程和触发器等内容,通过本书读者可以系统地学习到sql 的知识和方法。 本书注重实用性,操作性很强,适合于sql 的初学者学习...