我有一个表和两个不同的SQL过程(AS400)来插入/更新记录到同一个表。两个SQL程序都具有IF EXISTS条件来处理数据。
IF EXIST (SELECT 1 FROM TABLE WHERE FIELD001 = 'test') THEN
Update table....
ELSE
INSERT INTO TABLE VALUES ('test')...
ENDIF;
但我的表格中仍有重复的记录与mili秒差异。
Ex.1st record is --> 2017-07-24-04.21.47.485832
2nd record is --> 2017-07-24-04.21.47.487468
这些表可以交互式和批量插入/更新。无论如何,重复记录怎么可能...?请专家提供一些可能性,在何时/何时/如何插入重复记录。
而且我也不想用UNIQUE INDEX,PRIMARY KEY等解决这个问题...... 对不起,我没有附上任何编码。
谢谢, Loganathan。
在这里添加代码,,,
我之前提到的表格将以各种方式插入/更新,但我们确认这些记录是使用以下单个程序从单个会话以交互方式插入的。
表中的原始记录。
9243548 CUSTYPE 2017-07-10-16.53.09.825860 2017-07-10-16.53.09.825860
9243548 ROYALTY 2017-07-10-16.53.09.485832 2017-07-10-16.53.09.485832
9243548 ROYALTY 2017-07-10-16.53.09.487468 2017-07-10-16.53.09.487468
致电计划:
if v_res_spec_sts <> '' then
if (v_res_spec_sts <> v_current_res_spec_sts
or v_current_res_spec_sts IS NULL) then
call SPCASPECSV (p_resvnum, c_Royalty, v_res_spec_sts,
p_updateUser, p_updateProgram) ;
end if;
end if;
程序:
IF EXISTS (SELECT 1 FROM CASPECLPF WHERE RSRES# = P_RSRES#
AND RSCOND = P_RSCOND) THEN
UPDATE CASPECLPF SET
RSSSTS = COALESCE(P_RSSSTS, RSSSTS)
,RSSLCM = TODAYMONTH
,RSSLCD = TODAYDAY
,RSSLCY = TODAYYEAR
,RSSLCU = COALESCE(P_RSSLCU, RSSLCU)
,RSSLCP = COALESCE(P_RSSLCP, RSSLCP)
WHERE RSRES# = P_RSRES# AND RSCOND = P_RSCOND;
ELSE
INSERT INTO CASPECLPF
(
RSRES#
,RSCOND
,RSSSTS
,RSSLCM
,RSSLCD
,RSSLCY
,RSSLCU
,RSSLCP
)
VALUES
(
COALESCE(P_RSRES#, 0)
,COALESCE(P_RSCOND, ' ')
,COALESCE(P_RSSSTS, ' ')
,TODAYMONTH
,TODAYDAY
,TODAYYEAR
,COALESCE(P_RSSLCU, ' ')
,COALESCE(P_RSSLCP, ' ')
);
END IF;
答案 0 :(得分:0)
确保它们不在不同的会话中,即插入一个会话而不进行提交,然后第二个会话显然不会找到第一个会话中插入的记录。
如果不是这样,请提供代码。
答案 1 :(得分:0)
因为它不重复。
如果您定义了主键或唯一键,系统将阻止第二个进程在2017-07-24-04.21.47.487468处写入记录。
当第二个流程在2017-07-24-04.21.47.485500检查记录时,一个不存在。但是当第二个进程插入记录时,第一个进程也插入了一条记录。
即使使用主键,存在检查和插入也是两个独立的操作。您仍然需要监控插件上的重复键并正确处理。
MERGE
语句通常适用于此类&#34; upsert&#34; (UPDATE or INSERT
)运作。但是,即使使用原子合并,第二个进程也可以在存在检查和存储之间插入记录。插入。您必须使用* RR(可重复读取)的锁定级别,它基本上锁定整个表,以确保没有进程可以在存在检查和插入之间添加记录。
如果进程间隔微秒,则锁定整个表会受到伤害。
您确实需要定义主键,或至少是唯一的主键。