DBVis/PL SQL: IF EXIST - 如果可能如何正确构建

DBVis/PL SQL: IF EXIST - how to structure correctly if possible

使用 DBVis SQL 指挥官(因为我在这段代码中使用 "begin" 和 "end",我相信这段代码是以 PL SQL 方式执行的)我正在尝试执行我编写的 sql 脚本作为我的新 "cleaning trigger"

我正在尝试在此脚本中使用 IF EXISTS 语句来仅在特定列确实包含数据(已批准或拒绝)时实现清理

此脚本旨在不使用插入(到其他表)语句(如果使用它们,即使没有数据可插入,它们也会以不希望的方式在其他表上触发其他触发器)除非某列中确实有(不为空)数据:

begin

IF EXISTS (SELECT * 
        FROM HUB_SEGMENTS 
        where APP_OR_REJECT = 'APPROVED' or APP_OR_REJECT = 'REJECTED')
        THEN
INSERT INTO
 HUB_APPROVED (HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE)
         SELECT 
         HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE 
         FROM 
         HUB_SEGMENTS WHERE APP_OR_REJECT = 'APPROVED';

INSERT INTO
 HUB_REJECTED (HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE)
         SELECT 
         HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE 
         FROM 
         HUB_SEGMENTS WHERE APP_OR_REJECT = 'REJECTED';     

DELETE
FROM
    "TESTDEMO".HUB_SEGMENTS
WHERE
    APP_OR_REJECT = 'APPROVED' or APP_OR_REJECT = 'REJECTED';
    DBMS_OUTPUT.PUT_LINE('Trigger: Insert to action Tables Executed');


ELSE 

    DBMS_OUTPUT.PUT_LINE('Trigger: Insert to action Tables Not Executed');

end;

不幸的是,我在尝试 运行 时收到以下错误消息:

[Code: 6550, SQL State: 65000] ORA-06550: line 33, column 4:PLS-00103: Encountered the symbol ";" when expecting one of the following: if

我很确定这取决于我构建 IF EXIST

的方式

当然,可能是在我的 PL SQL 代码中,在 DBVis SQL commander 中使用 IF EXIST 是不允许的——我还没有看到很多关于这个特定语句的文档来自甲骨文。如果是这样,是否会有另一个 我可以尝试并完成我在这里尝试做的事情的方式吗?

任何指导将不胜感激

你不需要我相信的 if exists 刚转

IF EXISTS (SELECT * 
        FROM HUB_SEGMENTS 
        where APP_OR_REJECT = 'APPROVED' or APP_OR_REJECT = 'REJECTED')
        THEN
INSERT INTO
 HUB_APPROVED (HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE)
         SELECT 
         HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE 
         FROM 
         HUB_SEGMENTS WHERE APP_OR_REJECT = 'APPROVED';

INSERT INTO
 HUB_APPROVED (HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE)
         SELECT 
         HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE 
         FROM 
         HUB_SEGMENTS where (APP_OR_REJECT = 'APPROVED' or APP_OR_REJECT = 'REJECTED');

这是您的代码结构:

BEGIN
    IF EXISTS (SELECT... FROM HUB_SEGMENTS WHERE APP_OR_REJECT = 'APPROVED' or APP_OR_REJECT = 'REJECTED')
        THEN
            INSERT INTO HUB_APPROVED SELECT ... FROM FROM HUB_SEGMENTS WHERE APP_OR_REJECT = 'APPROVED';
            INSERT INTO HUB_REJECTED SELECT ... FROM FROM HUB_SEGMENTS WHERE APP_OR_REJECT = 'REJECTED';
            DELETE FROM HUB_SEGMENTS WHERE APP_OR_REJECT = 'APPROVED' or APP_OR_REJECT = 'REJECTED';
        ELSE
            ...;
END;

您可以很容易地看到缩进在最后一个 END 之前跳过级别:您缺少一个 END IF 来关闭 IF 块。 Oracle 试图告诉您,通过给您对应于最终 end; 的行并说:Encountered the symbol ; when expecting one of the following: if .

BEGIN
    IF EXISTS (SELECT... FROM HUB_SEGMENTS WHERE APP_OR_REJECT IN ('APPROVED', 'REJECTED');
        THEN
            INSERT INTO HUB_APPROVED SELECT ... FROM FROM HUB_SEGMENTS WHERE APP_OR_REJECT = 'APPROVED';
            INSERT INTO HUB_REJECTED SELECT ... FROM FROM HUB_SEGMENTS WHERE APP_OR_REJECT = 'REJECTED';
            DELETE FROM HUB_SEGMENTS WHERE APP_OR_REJECT IN ('APPROVED', 'REJECTED');
        ELSE
            ...;
    END IF;             --> here
END;

奖励:您可以使用 IN 代替这些 ORed 条件。

旁注:如果性能无关紧要,那么,正如@zip 所建议的那样,不要理会 IF 块。可以直接运行两个INSERTDELETE语句一前一后。如果 HUB_SEGMENTS 中没有符合搜索条件的数据,则无论如何都不会插入或删除任何内容。

感谢有用的评论 - 如果我使用非 oracle SQL(可能?),这些评论会起作用。不幸的是 运行 PL/SQL DBVis 上指向 oracle 数据库的 "exists" 脚本导致错误 - Exists 在 PL/SQL 脚本中不起作用(但应该在单个 SQL 显然是陈述)。

我发现结合 IF 使用变量解决了我的问题:


Declare 
        v_count NUMBER;

BEGIN


select COUNT(*)
        INTO v_count
        FROM HUB_SEGMENTS
        WHERE APP_OR_REJECT is not null; --for each row where %new.columnname is not new --=> this would be far less "expensive" sql query, need to figure out how to syntax this 

IF v_count >0
        THEN

                 INSERT INTO
                 HUB_APPROVED (HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE)
                 SELECT 
                 HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE 
                 FROM 
                 HUB_SEGMENTS WHERE APP_OR_REJECT = 'APPROVED';


        INSERT INTO 
         HUB_REJECTED (HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE)
         SELECT 
         HUB_SEGMENTS_GUID, TID, SEGMENT, ID, ROLE, UPDATED_BY, APP_OR_REJECT, UPDATED_DATE 
         FROM 
         HUB_SEGMENTS WHERE APP_OR_REJECT = 'REJECTED';     

DELETE
FROM
    "TESTDEMO".HUB_SEGMENTS
WHERE
    APP_OR_REJECT = 'APPROVED' or APP_OR_REJECT = 'REJECTED';

    DBMS_OUTPUT.PUT_LINE('Trigger: Insert to action Tables Executed');

ELSE 
    DBMS_OUTPUT.PUT_LINE('Trigger: Insert to action Tables NOT executed');    

END IF;


end;

这成功地实现了我试图实现的目标(除非特定列中确实有数据,否则不会执行 Insert/Delete 语句,以避免奇怪地意外触发其他触发器)

一位同事告诉我,按照 "for each row where %new.columnname is not new =>..." 的方式做一些事情会 cpu 密集 sql 查询少得多,但我需要弄清楚如何语法这个。现在,上面的代码在 PL/SQL 中工作,指向 DBVis 中的 oracle 数据库。

如果我找到 "for each row..." 方法,我会 post 在这里作为评论