/ / PL / SQL - Aggiorna più righe nella tabella di destinazione da una riga nella tabella di origine [duplicato] - sql, oracle, oracle10g, sql-merge

PL / SQL - Aggiorna più righe nella tabella di destinazione da una riga nella tabella di origine [duplicato] - sql, oracle, oracle10g, sql-merge

Sto usando un'istruzione di unione per unire due tabelle in cui una riga nella tabella di origine può aggiornare più righe nella tabella di destinazione.

Va un po 'così

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;

Tuttavia, quando provo questo, ottengo SQL Error: ORA-30926: unable to get a stable set of rows in the source tables

C'è un altro modo in cui posso farlo?

risposte:

1 per risposta № 1

ottengo l'errore SQL: ORA-30926: impossibile ottenere un set stabile di righe nel file tabelle di origine

Perché, la tabella di origine contiene probabilmente valori duplicati.

Probabilmente dovrai aggiungere un'altra colonna per identificare in modo univoco ogni riga.

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;

Ora uniamo due tabelle.

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;

Soluzione

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;

Leggi di più


1 per risposta № 2

Questo errore indica che Oracle non può ottenere per ogni record in A, un set di record che corrisponde solo a questo (es. Un set di record che porta a una relazione molti-a-molti).

Quello che devi fare è controllare nella tabella di destinazione gli elementi duplicati con lo stesso "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.