PL/SQL - 从源 table 中的一行更新目标 table 中的多行
PL/SQL - Update multiple rows in the target table from one row in the source table
我正在使用合并语句合并两个 table,其中源 table 中的一行可能更新目标 table 中的多行。
有点像这样
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
还有其他方法吗?
该错误意味着 Oracle 无法为 A 中的每条记录获取仅与该记录匹配的一组记录(例如,导致多对多关系的一组记录)。
您需要做的是在目标 table 中检查具有相同 "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.
i get SQL Error: ORA-30926: unable to get a stable set of rows in the
source tables
因为,您的来源 table 可能包含重复值。
您可能需要再添加一列来唯一标识每一行。
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;
现在我们要合并两个 table。
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;
我正在使用合并语句合并两个 table,其中源 table 中的一行可能更新目标 table 中的多行。
有点像这样
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
还有其他方法吗?
该错误意味着 Oracle 无法为 A 中的每条记录获取仅与该记录匹配的一组记录(例如,导致多对多关系的一组记录)。
您需要做的是在目标 table 中检查具有相同 "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.
i get SQL Error: ORA-30926: unable to get a stable set of rows in the source tables
因为,您的来源 table 可能包含重复值。
您可能需要再添加一列来唯一标识每一行。
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;
现在我们要合并两个 table。
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;