【问题标题】:PL/SQL - Update multiple rows in the target table from one row in the source table [duplicate]PL / SQL - 从源表中的一行更新目标表中的多行[重复]
【发布时间】:2015-06-19 14:46:25
【问题描述】:

我正在使用合并语句合并两个表,其中源表中的一行可能会更新目标表中的多行。

有点像这样

MERGE TABLE1 A
USING (SELECT EMP_CODE, DAYS_OFF FROM TABLE2) B
ON (A.ID = B.EMP_CODE)
WHEN MATCHED THEN
UPDATE SET A.DAYS_OFF = B.DAYS_OFF;

但是,当我尝试这个时,我得到SQL Error: ORA-30926: unable to get a stable set of rows in the source tables

有没有其他方法可以做到这一点?

【问题讨论】:

  • 向我们展示你的完整存储过程
  • @jWeaver 我面临的问题与您提到的帖子中的问题不同。我的问题是我不能确保 ON (A.ID = B.EMP_CODE) 只返回一行。
  • 您能分享两个表中的示例数据吗?
  • @jWeaver 我明白这对我来说似乎不合作,但我真的不能。有没有其他方法可以帮助我澄清问题?
  • @jWeaver 我已经尝试过您提到的帖子中提出的第一个解决方案,但现在它抛出“SQL 错误:ORA-01445: cannot select ROWID from, or sample, a join view without a key-保留表”

标签: sql oracle oracle10g sql-merge


【解决方案1】:

我收到 SQL 错误:ORA-30926:无法在 源表

因为,您的源表可能包含重复值。

您可能需要再添加一列来唯一标识每一行。

CREATE TABLE source_table (
    col1 NUMBER,
    col2 VARCHAR2(10),
    col3 VARCHAR2(10)
);

INSERT INTO source_table (col1, col2, col3) VALUES (1, 'a', 'w');
INSERT INTO source_table (col1, col2, col3) VALUES (1, 'b', 'x');
INSERT INTO source_table (col1, col2, col3) VALUES (2, 'c', 'y');
INSERT INTO source_table (col1, col2, col3) VALUES (3, 'c', 'z');

COMMIT;

CREATE TABLE target_table (
    col1 NUMBER,
    col2 VARCHAR2(10),
    col3 VARCHAR2(10)
);

INSERT INTO target_table (col1, col2, col3) VALUES (1, 'b', 'z');
INSERT INTO target_table (col1, col2, col3) VALUES (3, 'd', 'w');

COMMIT;

现在我们要合并两个表。

MERGE INTO target_table trg
USING (--Actually we can simply write source_table for this example but I want to write Select:)
       SELECT col1, col2, col3
       FROM source_table 
      ) src 
ON (trg.col1 = src.col1)
WHEN MATCHED THEN UPDATE SET --Don't forget you cannot update columns that included in ON clause
    trg.col2 = src.col2,
    trg.col3 = src.col3
WHEN NOT MATCHED THEN INSERT
    (
        col1,
        col2,
        col3
    )
    VALUES
    (
        src.col1,
        src.col2,
        src.col3
    );

COMMIT;

解决方案

MERGE INTO target_table trg
USING source_table src --Now I simply write the table name:)
ON (
    trg.col1 = src.col1 AND
    trg.col2 = src.col2
   )
WHEN MATCHED THEN UPDATE SET --Don't forget you cannot update columns that included in ON clause
    trg.col3 = src.col3
WHEN NOT MATCHED THEN INSERT
    (
        col1,
        col2,
        col3
    )
    VALUES
    (
        src.col1,
        src.col2,
        src.col3
    );

COMMIT;

Read more

【讨论】:

    【解决方案2】:

    该错误意味着 Oracle 无法为 A 中的每条记录获取一组仅与该记录匹配的记录(例如,一组导致多对多关系的记录)。

    您需要做的是在目标表中检查具有相同“ID”的重复项

    SQL> list                
      1  MERGE INTO  TABLE1 A
      2   USING (SELECT * FROM TABLE2) B
      3   ON (A.ID = B.EMP_CODE)
      4   WHEN MATCHED THEN
      5  UPDATE SET A.DAYS_OFF = B.DAYS_OFF
      6*
    SQL> r
      1  MERGE INTO  TABLE1 A
      2   USING (SELECT * FROM TABLE2) B
      3   ON (A.ID = B.EMP_CODE)
      4   WHEN MATCHED THEN
      5  UPDATE SET A.DAYS_OFF = B.DAYS_OFF
      6*
    MERGE INTO  TABLE1 A
    *
    ERROR at line 1:
    ORA-30926: unable to get a stable set of rows in the source tables
    
    SQL> select id, count(0) from table1 group by id;
    
            ID   COUNT(0)
    ---------- ----------
             1          2
    
    SQL> delete from table1 t1 where t1.rowid not in (select max(rowid) from table1 t2 where t2.id = t1.id);
    
    1 row deleted.
    
    SQL> commit;
    
    Commit complete.
    
    SQL> MERGE INTO  TABLE1 A
     USING (SELECT * FROM TABLE2) B
     ON (A.ID = B.EMP_CODE)
     WHEN MATCHED THEN
    UPDATE SET A.DAYS_OFF = B.DAYS_OFF  2    3    4    5  ; 
    
    2 rows merged.
    
    SQL> commit;
    
    Commit complete.
    

    【讨论】:

      猜你喜欢
      • 2019-10-07
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 2017-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多