我有一个spring批处理程序,它从一个数据库读取数据,然后处理数据,然后写入Oracle数据库。该批处理程序每天运行一次。如何避免每次运行时添加相同的记录,只从源DB中添加新值?
一种选择是创建唯一索引(或主键,如果可能(取决于您是否允许空值))这将导致Oracle自动拒绝其列违反唯一性的所有行。
其他选项需要一些编程。
[编辑:“默默地”跳过错误]
这就是我的意思:
for cur_r in (select col1, col2
from another_table@db_link)
loop
begin --> you need inner BEGIN-EXCEPTION-END block
insert into new_table (col1, col2)
values (cur_r.col1, cur_r.col2);
exception
when dup_val_on_index then
null;
end;
end loop;
另一个选项使用纯SQL(即没有PL / SQL循环):
insert into new_table (col1, col2)
select col1, col2
from another_table@db_link
where (col1, col2) not in (select col1, col2
from new_table);
此选项甚至不需要唯一索引(这不会有害),因为NOT IN
不会插入其列值已存在于目标表中的行。
听起来你担心多次不处理相同的源记录。如果是这种情况,您可以在源表上添加一个字段,指示数据已被提取。
哦,并且 - 在你的桌子上放一个独特的主键。他们都是。即使是那些你认为不需要它的人。你今天添加的主键是你以后不会说的那句话,“该死的。我希望那张表有一个主键”。 Don't ask me how I know...
祝你好运。
我猜你使用的是RepositoryItemReader作为源代码。如果是这种情况,您可以在源存储库中添加自定义方法,包括使用@Query避免已处理记录的验证条件,然后在RepositoryItemReader中使用该方法。
它会是这样的
@Query("SELECT r FROM Records r WHERE r.isNew = 1")
Collection<Record> findAllNewRecords();
然后像配置读者一样
RepositoryItemReader<Record> recordsReader = new RepositoryItemReader<>();
recordsReader.setRepository(recordsRepository);
recordsReader.setMethodName("findAllNewRecords");
希望能帮助到你
create table T_UNIQUE_VALUE( a number,b number, c varchar2(100));
alter table T_UNIQUE_VALUE ADD CONSTRAINT C_UNIQUE_VALUE UNIQUE (a,b);
定义日志错误表。 Oracle将创建qazxsw poi
err$_table_name
测试一下。
BEGIN
DBMS_ERRLOG.create_error_log(dml_table_name => 'T_UNIQUE_VALUE');
END;
修改spring注释。
execut 2 times
insert into T_UNIQUE_VALUE values(1,1,'a') LOG ERRORS REJECT LIMIT UNLIMITED;
--check table T_UNIQUE_VALUE and err$_T_UNIQUE_VALUE
select * from err$_T_UNIQUE_VALUE; -- 1 row
select * from T_UNIQUE_VALUE; -- 1 row