我对PL / SQL很陌生,我必须小心一点。我必须做一些非常相似的功能。我简化了这个问题。
我有2个表(在本例中称为TABLE1,TABLE2),它们有一些数据。我必须修剪,验证数据并将其插入其他表格。
TABLE1 - >表3 表2 - >表4
TABLE1有一些订单,而TABLE2每个订单有几个仓位。正如我说它简化所以我没有发布像异常或打开/关闭游标等的东西。在Atm它的工作原理是这样但我不认为这个结构是在“最佳实践”附近,但我没有找到
表示网络上任何涉及此问题的PL / SQL代码,但它必须是非常常见的。COMMIT可能在外部循环的末尾,我想,也许它甚至在整个函数之后。
所以你能告诉我它是否可以这样或完全愚蠢,我应该/可以改变什么以及为什么。我不想习惯于'糟糕'的编码风格,所以我想以正确的方式学习它,而我是初学者。
继承简化代码:
BEGIN
SAVEPOINT SAVE_Stufe_5;
LOOP
SAVEPOINT SAVE_LOOP;
FETCH CURSOR1 INTO RECORD1;
EXIT WHEN CURSOR1%NOTFOUND OR CURSOR1%NOTFOUND IS NULL;
vError := 0;
RECORD1 := CURSOR1;
-- DATAVALIDATION (vError will be the Errorcode)
IF (vError = 0) THEN
retcode := InsertTABLE3(RECORD1);
IF (retcode != DATABASE_OK) THEN
ROLLBACK TO SAVE_LOOP;
END IF;
END IF;
LOOP
FETCH CURSOR2 INTO CURSOR2;
EXIT WHEN CURSOR2%NOTFOUND OR CURSOR2%NOTFOUND IS NULL OR vError != 0 OR retcode != DATABASE_OK;
RECORD2 := CURSOR2;
-- DATAVALIDATION (vError will be the Errorcode)
IF (vError = 0) THEN
retcode := InsertTABLE4(RECORD2);
IF (retcode = DATABASE_OK) THEN
UPDATE TABLE2
SET TABLE2.Status = 20
WHERE TABLE2.ID = CURSOR2.ID;
ELSE
ROLLBACK TO SAVE_LOOP;
END IF;
END IF;
END LOOP;
IF (vError = 0) THEN
UPDATE TABLE1
SET TABLE1.Status = 20
WHERE TABLE1.ID = CURSOR1.ID
ELSE
ROLLBACK TO SAVE_LOOP;
UPDATE TABLE1
SET TABLE1.Status = vError
WHERE TABLE1.ID = CURSOR1.ID
UPDATE TABLE2
SET TABLE2.Status = vError
WHERE TABLE2.ID = CURSOR2.ID
END IF;
END LOOP;
END;
小更新:
我设法做了基于验证的设置,但我真的不知道如何将我的数据放到另一个表中。我尝试了一个插入选择,其中包含修剪,但只插入一行。如果我按照建议使用隐式游标我仍然需要循环,我不会循环游标但是SELECT INTO只要隐式游标只有一行。
我想我真的需要一个片段或一些链接来帮助我。这是我尝试的简化版本:
INSERT INTO TABLE3
(
val1,
val2,
val3
)
SELECT TRIM(val1),
TRIM(val2),
TRIM(val3),
FROM TABLE1
WHERE STATUS = 10
AND (TRIM(PK1) || TRIM(PK2)) NOT IN (SELECT (TABLE3.PK1 || TABLE3.PK2) FROM TABLE3);
答案 0 :(得分:0)
一般来说,通过在SQL中循环来做事情是不好的。与基于集合的解决方案相比,这样的循环将非常慢。而不是所有这些循环,最好使用单个insert
或merge
语句将表1中的所有表复制到表3中 - 如果您的验证很复杂并且需要,则可能会使用一些语句一些中间步骤。
您希望做的大多数类型的修剪和数据验证都可以像这样处理。几乎从不需要嵌套循环。有例外,但它们很少见。那些不熟悉SQL的人倾向于使用循环,因为这是我们从其他语言中所知道的。不久前我就是那个类别。但是要真正使用语言的力量,你必须超越它。
除了这一点之外,如果我们对表格一无所知或您正在进行何种验证,则不能给出太多具体的帮助。
何时commit
还要依赖于您的具体设计以及您要完成的任务。