最近使用Datax同步进行定时数据同步,并在同步完之后进行回调sql进行统计操作。对应的ORACLE表结构如下:
create table DATA_STAT_DAY (
DATA_DATE DATE,
ID VARCHAR2(2),
NAME VARCHAR2(2),
CLASSNO VARCHAR2(2),
SCORES NUMBER(16,0)
);
CREATE UNIQUE INDEX IDX_DATA_STAT_DAY ON DATA_STAT_DAY(DATA_DATE, ID, NAME, CLASSNO);
回调对应的SQL如下:
MERGE INTO DATA_STAT_DAY a
USING (
SELECT
DATA_DATE,'0000' AS ID,NAME,CLASSNO, SUM(SCORES) SCORES
FROM
DATA_STAT_DAY
WHERE ID % 2 = 0
GROUP BY DATA_DATE,NAME,CLASSNO
) b
ON (a.DATA_DATE = b.DATA_DATE and a.ID = b.ID and a.NAME = b.NAME and a.CLASSNO = b.CLASSNO)
WHEN MATCHED THEN
UPDATE SET a.SCORES = b.SCORES
WHEN NOT MATCHED THEN
INSERT INTO (a.DATA_DATE,a.ID,a.NAME,a.CLASSNO,a.SCORES)
VALUES (b.DATA_DATE,b.ID,b.NAME,b.CLASSNO,b.SCORES)
回调SQL执行过程中,触发了 ORA-00001: unique constaint violated 的错误,其中USING部分的数据没有重复的,并且表中也没有和USING表中重复的,但是这里面的NAME和CLASSNO字段是有部分字段为NULL,ID部分有重复的值,然后这就导致了MERGE INTO的USING 关联的ON条件的时候判断为没关联上。但是在插入的时候,唯一索引判断重复了,所以对应的USING的数据集的ON部分的字段不能有为NULL的,否则会报唯一索引冲突的问题。
SELECT M.MGT_ORG_CODE,
LPAD(' ', LEVEL * 2, ' ') || M.MGT_ORG_NAME AS MGT_ORG_NAME,
M.PRNT_MGT_ORG_CODE,
SYS_CONNECT_BY_PATH(M.MGT_ORG_CODE, '>') AS CODE_PATH,
REGEXP_SUBSTR(SYS_CONNECT_BY_PATH(M.MGT_ORG_CODE, '>'),'[^>]+',1,1,'i') AS MGT_ORG_C1,
REGEXP_SUBSTR(SYS_CONNECT_BY_PATH(M.MGT_ORG_CODE, '>'),'[^>]+',1,2,'i') AS MGT_ORG_C2,
REGEXP_SUBSTR(SYS_CONNECT_BY_PATH(M.MGT_ORG_CODE, '>'),'[^>]+',1,3,'i') AS MGT_ORG_C3,
REGEXP_SUBSTR(SYS_CONNECT_BY_PATH(M.MGT_ORG_CODE, '>'),'[^>]+',1,4,'i') AS MGT_ORG_C4,
REGEXP_SUBSTR(SYS_CONNECT_BY_PATH(M.MGT_ORG_CODE, '>'),'[^>]+',1,5,'i') AS MGT_ORG_C5,
REGEXP_SUBSTR(SYS_CONNECT_BY_PATH(M.MGT_ORG_CODE, '>'),'[^>]+',1,6,'i') AS MGT_ORG_C6,
CONNECT_BY_ROOT(M.MGT_ORG_CODE) AS ROOT_CODE_VAL,
CONNECT_BY_ISLEAF AS ISLEAF,
M.DIST_LV,
'0' || (LEVEL + 1) AS MGT_LEVEL
FROM (SELECT T.MGT_ORG_CODE,
T.DIST_LV,
T.PRNT_MGT_ORG_CODE,
T.MGT_ORG_NAME
FROM M_MGT_ORG T
WHERE T.MGT_ORG_TYPE = 'corp'
AND T.VALID_FLAG = '02') M
START WITH M.DIST_LV = '02'
CONNECT BY NOCYCLE PRIOR M.MGT_ORG_CODE = M.PRNT_MGT_ORG_CODE
ORDER BY M.MGT_ORG_CODE
START WITH:指定起始节点的条件
CONNECT BY:指定父子行的条件关系
PRIOR:查询父行的限定符,格式:prior column1=column2 or column1=prior column2
NOCYCLE:若数据表中存在循环行,那么不添加此关键字会报错,添加关键字后,便不会报错,但循环的两行只会显示其中的第一条
循环行:该行只有一个子行,而且子行又是该行的祖先行
CONNECT_BY_ISCYCLE:前置条件:在使用了NOCYCLE之后才能使用此关键字,用于表示是否是循环行,0表示否,1表示是
CONNECT_BY_ISLEAF:是否是叶子节点,0表示否,1表示是
LEVEL:level伪列,表示层级,值越小层级越高,level=1为层级最高节点
CONNECT_BY_ROOT: 可以获取树形查询根记录的字段,start with开始的地方被视为根节点。
SYS_CONNECT_BY_PATH:从start with开始的地方开始遍历,并记下其遍历到的节点,start with开始的地方被视为根节点,将遍历到的路径根据函数中的分隔符,组成一个新的字符串。