处理唯一约束错误并尝试使用循环自动生成唯一值最多 n 次
Posted
技术标签:
【中文标题】处理唯一约束错误并尝试使用循环自动生成唯一值最多 n 次【英文标题】:Handling unique constraint error and trying to auto generate a unique value upto n times using a loop 【发布时间】:2018-09-06 23:53:28 【问题描述】:我正在尝试将自动生成的值插入到表中。如果存在唯一约束错误,我想获取一个新值并将最新值插入表中。我想在抛出唯一约束错误之前尝试生成唯一值最多 10 次。
这是我目前所拥有的。
BEGIN
autoGenValue := x
FOR i in 1..10 LOOP
BEGIN
INSERT INTO mainTbl(A,
B,
C)
VALUES(autoGenValue,
b,
c )
EXCEPTION
WHEN DUP_VAL_ON_INDEX
THEN
SELECT lpad(NVL(MAX(SUBSTR(A, -2)), '00')+1,4,'0')
INTO maxSeq
FROM RecvTbl
SELECT car_id||maxSeq
INTO autoGenValue
FROM DUAL;
WHEN OTHERS THEN
EXIT;
END;
END LOOP;
UPDATE RecvTbl
SET A = autoGenValue
WHERE A = x;
END;
COMMIT;
x
是最初计算的自动生成值,我尝试将其插入mainTbl
。如果存在唯一约束错误,我将遵循一些必需的逻辑(此处简化)来获取所需的唯一值。我尝试了 10 次(如果需要)。当没有唯一约束错误时退出并更新recvTbl
的值,因为我需要它以供将来计算。
通过我的代码,我注意到在插入mainTbl
后该值正在递增,即使没有唯一约束错误并且插入recvTbl
中的值是递增值而不是@ 中的值987654327@.
任何想法我做错了什么?
【问题讨论】:
你真正做错的是没有使用序列。这可能是一个有趣的练习,但这不是你应该投入生产的东西。它无法扩展,也无法在多用户环境中工作。 我没有使用序列,因为用于生成 autoGenValue 的 car_id 前缀每天都在变化。并且 max seq 每天从 0001 开始。 car_id 对于两种不同的格式也有两种不同的类型,但生成的所有 ID 都放在同一个表中。考虑到我选择这种方式的一切。我在这里提出问题时简化了所有逻辑。 那你应该使用代码控制表。 【参考方案1】:问题是你没有成功退出.....
如果存在除 DUP_VAL_ON_INDEX 以外的任何错误,则退出循环,但如果插入成功,则继续循环。
所以下一次循环时你会得到一个 DUP_VAL_ON_INDEX 错误并递增。
您可以使用类似下面的内容(未经测试)来设置成功变量,然后在它为真时立即退出循环。
BEGIN
autoGenValue := x;
v_success := false;
FOR i in 1..10 LOOP
BEGIN
INSERT INTO mainTbl(A,
B,
C)
VALUES(autoGenValue,
b,
c ) ;
v_success := true;
EXCEPTION
WHEN DUP_VAL_ON_INDEX
THEN
SELECT lpad(NVL(MAX(SUBSTR(A, -2)), '00')+1,4,'0')
INTO maxSeq
FROM RecvTbl
SELECT car_id||maxSeq
INTO autoGenValue
FROM DUAL;
WHEN OTHERS THEN
EXIT;
END;
if v_success = true then
exit;
end if;
END LOOP;
UPDATE RecvTbl
SET A = autoGenValue
WHERE A = x;
END;
COMMIT;
【讨论】:
是的,问题是没有 EXIT 成功。我的印象是“当其他人”会包括其他例外情况。为什么你认为它在第二次迭代后退出了循环?我注意到 RecvTbl 中的值只是 MainTbl 中值的 +1。我希望它在 10 次迭代后退出,因此该值应该是 MainTbl 中的值的 +10。以上是关于处理唯一约束错误并尝试使用循环自动生成唯一值最多 n 次的主要内容,如果未能解决你的问题,请参考以下文章