PL / SQL - 更新位置和回滚位置

时间:2012-12-13 13:08:31

标签: sql oracle plsql

我对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);

1 个答案:

答案 0 :(得分:0)

一般来说,通过在SQL中循环来做事情是不好的。与基于集合的解决方案相比,这样的循环将非常慢。而不是所有这些循环,最好使用单个insertmerge语句将表1中的所有表复制到表3中 - 如果您的验证很复杂并且需要,则可能会使用一些语句一些中间步骤。

您希望做的大多数类型的修剪和数据验证都可以像这样处理。几乎从不需要嵌套循环。有例外,但它们很少见。那些不熟悉SQL的人倾向于使用循环,因为这是我们从其他语言中所知道的。不久前我就是那个类别。但是要真正使用语言的力量,你必须超越它。

除了这一点之外,如果我们对表格一无所知或您正在进行何种验证,则不能给出太多具体的帮助。

何时commit还要依赖于您的具体设计以及您要完成的任务。