Oracle试图通过加入非索引表来更新表

时间:2019-02-27 17:58:53

标签: oracle

我试图寻找与我的问题类似的示例,但无法重现成功的解决方案。

我有2个表,即Controller和Actions。

“动作”表具有“步骤”,“脚本”,“描述”,“ Wait_Until”和“ Ref_Code”列。

Controller表只能通过Ref_Code联接到Action表上。

“动作”表不能具有PK,因为对于每个Ref_Code,都有一个要采取的步骤。

尝试使用合并语句更新Controller表时出现错误:

ORA-30926:无法在源表中获得稳定的行集

我的合并语句如下:

MERGE INTO DSTETL.SHB_FTPS_CONTROLLER ftpsc
     USING (SELECT DISTINCT FTPSC.SESSION_ID,
                            FTPSC.ORDER_DATE,
                            sa.step,
                            sa.next_step,
                            LAST_ACTION_TMSTMP,
                            SA.ACTION_SCRIPT,
                            sa.ref_code,
                            SA.WAIT_UNTIL
              FROM DSTETL.SHB_FTPS_CONTROLLER ftpsc, DSTETL.SHB_ACTIONS sa
             WHERE     SA.REF_CODE = FTPSC.REF_CODE
                   AND SA.STEP > ftpsc.curr_step
                   AND sa.step = ftpsc.next_step) v1
        ON (v1.REF_CODE = FTPSC.REF_CODE)
WHEN MATCHED
THEN
   UPDATE SET FTPSC.LAST_ACTION_TMSTMP = CURRENT_TIMESTAMP,
              ftpsc.next_step = v1.next_step,
              ftpsc.curr_step = v1.STEP,
              ftpsc.action_script = v1.action_script
           WHERE CURRENT_TIMESTAMP >= v1.LAST_ACTION_TMSTMP + v1.WAIT_UNTIL;

COMMIT;

我也尝试使用普通更新来执行此操作,但是我得到了ORA-01732:此视图上的数据操作操作不合法。

UPDATE (SELECT FTPSC.SESSION_ID,
                        FTPSC.ORDER_DATE,
                        FTPSC.CURR_STEP,
                        FTPSC.NEXT_STEP,
                        FTPSC.ACTION_SCRIPT,
                        sa.step,                                    --New Step
                        sa.next_step AS "NNS",                 --New Next Step
                        FTPSC.LAST_ACTION_TMSTMP,
                        SA.ACTION_SCRIPT AS "NAS",         --New action script
                        sa.ref_code,
                        SA.WAIT_UNTIL
          FROM    DSTETL.SHB_FTPS_CONTROLLER ftpsc
               LEFT JOIN
                  DSTETL.SHB_ACTIONS sa
               ON     SA.REF_CODE = FTPSC.REF_CODE
                  AND SA.STEP > ftpsc.curr_step
                  AND sa.step = ftpsc.next_step) t
   SET t.curr_step = t.step,
       t.LAST_ACTION_TMSTMP = CURRENT_TIMESTAMP,
       t.next_step = t."NNS",
       t.action_script = t."NAS";

       COMMIT;

任何建议将不胜感激,我已经理解这是因为Action表具有多个Ref_Code,但是REF_CODE || STEP是唯一的。和输出:

SELECT DISTINCT FTPSC.SESSION_ID,
                                FTPSC.ORDER_DATE,
                                sa.step,
                                sa.next_step,
                                LAST_ACTION_TMSTMP,
                                SA.ACTION_SCRIPT,
                                sa.ref_code,
                                SA.WAIT_UNTIL
                  FROM DSTETL.SHB_FTPS_CONTROLLER ftpsc, DSTETL.SHB_ACTIONS sa
                 WHERE     SA.REF_CODE = FTPSC.REF_CODE
                       AND SA.STEP > ftpsc.curr_step
                       AND sa.step = ftpsc.next_step;

这就是我希望Controller表更新的方式。

谢谢。

1 个答案:

答案 0 :(得分:0)

听起来您想要做的是:使用Actions表中匹配的“下一步”详细信息更新Controller表中的每一行。但是您的Merge语句正在查询Controller表两次,这使事情变得混乱。

这是您要做什么吗?

MERGE INTO DSTETL.SHB_FTPS_CONTROLLER ftpsc
     USING (SELECT 
                    step,
                    next_step,
                    ACTION_SCRIPT,
                    ref_code,
                    WAIT_UNTIL
              FROM DSTETL.SHB_ACTIONS
             ) sa
        ON (sa.REF_CODE = FTPSC.REF_CODE)
WHEN MATCHED
THEN
   UPDATE SET FTPSC.LAST_ACTION_TMSTMP = CURRENT_TIMESTAMP,
              ftpsc.next_step = sa.next_step,
              ftpsc.curr_step = sa.STEP,
              ftpsc.action_script = sa.action_script
         WHERE CURRENT_TIMESTAMP >= ftpsc.LAST_ACTION_TMSTMP + sa.WAIT_UNTIL
           AND SA.STEP > ftpsc.curr_step
           AND sa.step = ftpsc.next_step;

编辑:更新的查询

EDIT2:因此,在原始查询中的USING部分中,您正在选择要更新的Controller表中的行...但是您从未将这些行从MERGE INTO部分连接到Controller表中以进行匹配他们起来。使用相同的别名“ ftpsc”只是不太清楚它们是查询中的两个独立对象,还是要更新的对象。

说实话,我真的不明白为什么Oracle不允许您更新USING..ON子句中出现的列。 It apparently works fine in SQL Server