如何跳过唯一约束冲突
How to skip unique constraint violation
如果我有 bulk insert
作为交易的一部分,像这样:
cmdTxt.Clear();
cmdTxt.Append(" INSERT INTO sc1pen ");
cmdTxt.Append(" SELECT action_month,action_year,200,emp_num,penalty_action , ");
cmdTxt.Append(" 'APPLY ' || penalty_reason || ' day ' , 0 , 0 ");
cmdTxt.Append(" FROM sc2pen WHERE sal_year = ? and sal_month = ? and penalty_type = 1 and pay_type = 0 ");
myIfxCmd.CommandText = cmdTxt.ToString();
myIfxCmd.Parameters.Clear();
myIfxCmd.Parameters.Add("sal_year", IfxType.Integer);
myIfxCmd.Parameters.Add("sal_month", IfxType.Integer);
myIfxCmd.Parameters[0].Value = penaltyDt.Rows[0]["sal_year"];
myIfxCmd.Parameters[1].Value = penaltyDt.Rows[0]["sal_month"];
myIfxCmd.ExecuteNonQuery();
如果 unique constraint violated
在此插入过程中如何避免回滚整个事务,我希望跳过导致此唯一约束异常的行并恢复插入过程。
猜测问题中两个表的模式是什么有点困难,但我们可以做出一些猜测并针对这些猜测测试代码。
半可信的模式
CREATE TEMP TABLE sc1pen
(
action_month INTEGER NOT NULL,
action_year INTEGER NOT NULL,
unidentified_1 INTEGER NOT NULL,
emp_num INTEGER NOT NULL,
penalty_action INTEGER NOT NULL,
penalty_string VARCHAR(30) NOT NULL,
unidentified_2 INTEGER NOT NULL,
unidentified_3 INTEGER NOT NULL
);
CREATE TEMP TABLE sc2pen
(
action_month INTEGER NOT NULL,
action_year INTEGER NOT NULL,
unidentified_1 INTEGER NOT NULL,
emp_num INTEGER NOT NULL,
penalty_action INTEGER NOT NULL,
penalty_string VARCHAR(30) NOT NULL,
penalty_reason VARCHAR(30) NOT NULL,
unidentified_2 INTEGER NOT NULL,
unidentified_3 INTEGER NOT NULL,
sal_year INTEGER NOT NULL,
sal_month INTEGER NOT NULL,
penalty_type INTEGER NOT NULL,
pay_type INTEGER NOT NULL
);
INSERT 语句的翻译
这是问题中 INSERT 语句的翻译。
INSERT INTO sc1pen
SELECT action_month, action_year, 200 AS unidentified_1, emp_num, penalty_action,
'APPLY ' || penalty_reason || ' day ' AS penalty_string,
0 AS unidentified_2, 0 AS unidentified_3
FROM sc2pen
WHERE sal_year = 2016 AND sal_month = 4 AND penalty_type = 1 AND pay_type = 0;
因为我使用的是命令行工具而不是嵌入式 SQL 或类似工具,所以我不得不用值替换问号 — sal_year
为 2016,[=14 为 4 =].
可能的 MERGE 语句
MERGE INTO sc1pen AS dst
USING (
SELECT action_month, action_year, 200 AS unidentified_1, emp_num, penalty_action,
'APPLY ' || penalty_reason || ' day ' AS penalty_string,
0 AS unidentified_2, 0 AS unidentified_3
FROM sc2pen
WHERE sal_year = 2016 AND sal_month = 4 AND penalty_type = 1 AND pay_type = 0
) AS src
ON dst.action_month = src.action_month AND
dst.action_year = src.action_year AND
dst.emp_num = src.emp_num
WHEN NOT MATCHED THEN INSERT VALUES(src.action_month, src.action_year,
src.unidentified_1, src.emp_num, src.penalty_action,
src.penalty_string, src.unidentified_2, src.unidentified_3)
;
这主要是 'read the manual' 在 MERGE 声明中。
ON
条款似乎半可信;由于表中没有主键标识,我们必须猜测连接条件应该是什么。
如果我有 bulk insert
作为交易的一部分,像这样:
cmdTxt.Clear();
cmdTxt.Append(" INSERT INTO sc1pen ");
cmdTxt.Append(" SELECT action_month,action_year,200,emp_num,penalty_action , ");
cmdTxt.Append(" 'APPLY ' || penalty_reason || ' day ' , 0 , 0 ");
cmdTxt.Append(" FROM sc2pen WHERE sal_year = ? and sal_month = ? and penalty_type = 1 and pay_type = 0 ");
myIfxCmd.CommandText = cmdTxt.ToString();
myIfxCmd.Parameters.Clear();
myIfxCmd.Parameters.Add("sal_year", IfxType.Integer);
myIfxCmd.Parameters.Add("sal_month", IfxType.Integer);
myIfxCmd.Parameters[0].Value = penaltyDt.Rows[0]["sal_year"];
myIfxCmd.Parameters[1].Value = penaltyDt.Rows[0]["sal_month"];
myIfxCmd.ExecuteNonQuery();
如果 unique constraint violated
在此插入过程中如何避免回滚整个事务,我希望跳过导致此唯一约束异常的行并恢复插入过程。
猜测问题中两个表的模式是什么有点困难,但我们可以做出一些猜测并针对这些猜测测试代码。
半可信的模式
CREATE TEMP TABLE sc1pen
(
action_month INTEGER NOT NULL,
action_year INTEGER NOT NULL,
unidentified_1 INTEGER NOT NULL,
emp_num INTEGER NOT NULL,
penalty_action INTEGER NOT NULL,
penalty_string VARCHAR(30) NOT NULL,
unidentified_2 INTEGER NOT NULL,
unidentified_3 INTEGER NOT NULL
);
CREATE TEMP TABLE sc2pen
(
action_month INTEGER NOT NULL,
action_year INTEGER NOT NULL,
unidentified_1 INTEGER NOT NULL,
emp_num INTEGER NOT NULL,
penalty_action INTEGER NOT NULL,
penalty_string VARCHAR(30) NOT NULL,
penalty_reason VARCHAR(30) NOT NULL,
unidentified_2 INTEGER NOT NULL,
unidentified_3 INTEGER NOT NULL,
sal_year INTEGER NOT NULL,
sal_month INTEGER NOT NULL,
penalty_type INTEGER NOT NULL,
pay_type INTEGER NOT NULL
);
INSERT 语句的翻译
这是问题中 INSERT 语句的翻译。
INSERT INTO sc1pen
SELECT action_month, action_year, 200 AS unidentified_1, emp_num, penalty_action,
'APPLY ' || penalty_reason || ' day ' AS penalty_string,
0 AS unidentified_2, 0 AS unidentified_3
FROM sc2pen
WHERE sal_year = 2016 AND sal_month = 4 AND penalty_type = 1 AND pay_type = 0;
因为我使用的是命令行工具而不是嵌入式 SQL 或类似工具,所以我不得不用值替换问号 — sal_year
为 2016,[=14 为 4 =].
可能的 MERGE 语句
MERGE INTO sc1pen AS dst
USING (
SELECT action_month, action_year, 200 AS unidentified_1, emp_num, penalty_action,
'APPLY ' || penalty_reason || ' day ' AS penalty_string,
0 AS unidentified_2, 0 AS unidentified_3
FROM sc2pen
WHERE sal_year = 2016 AND sal_month = 4 AND penalty_type = 1 AND pay_type = 0
) AS src
ON dst.action_month = src.action_month AND
dst.action_year = src.action_year AND
dst.emp_num = src.emp_num
WHEN NOT MATCHED THEN INSERT VALUES(src.action_month, src.action_year,
src.unidentified_1, src.emp_num, src.penalty_action,
src.penalty_string, src.unidentified_2, src.unidentified_3)
;
这主要是 'read the manual' 在 MERGE 声明中。
ON
条款似乎半可信;由于表中没有主键标识,我们必须猜测连接条件应该是什么。