【问题标题】:Oracle trying to update a table by joining a non indexed tableOracle 尝试通过加入非索引表来更新表
【发布时间】:2019-07-21 13:05:43
【问题描述】:

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

我有 2 个表,Controller 和 Actions。

Actions 表包含 Step、Script、Description、Wait_Until 和 Ref_Code 列。

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

Action 表不能有 PK,因为每个 Ref_Code 都有一个要执行的步骤。

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

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;

我希望控制器表如何更新。

提前致谢。

【问题讨论】:

    标签: oracle


    【解决方案1】:

    听起来您想要做的是:使用 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

    【讨论】:

    • 刚试过这个,现在我得到 ORA-38104:ON 子句中引用的列无法更新:“FTPSC”。“NEXT_STEP”
    • 哦,对了 - 我将这些连接条件移到 where 子句中,这样更好吗?
    • 像魅力伴侣一样工作!您介意尝试两次更新 Controller 表来解释您的意思吗?为什么我不能将要更新的列放在“USING”子句中?
    • @AliE - 编辑答案以添加一些细节,希望对您有所帮助
    猜你喜欢
    • 2012-10-18
    • 1970-01-01
    • 2011-05-23
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多