PL/SQL 合并语句
PL/SQL Merge statement
我希望使用 PL/SQL 的 MERGE 语句在我的维度 table 中实现一种类型 2 缓慢变化的维度行为。它适用于更新现有值和插入新值。我希望通过不仅更新现有值而且使用更新值创建不同的行同时保留具有 "outdated" 值的行来扩展此功能。
简而言之,可以这样做吗?
MERGE INTO A
USING B
ON (A.ID = B.ID)
WHEN MATCHED THEN
UPDATE END_DATE ON THE EXISTING ROW;
INSERT UPDATED VALUES IN A NEW ROW;
WHEN NOT MATCHED THEN
INSERT A NEW ROW WITH NEW VALUES;
先谢谢大家了。
您需要 运行 两个语句而不是此处的 1 个。
(在你的伪代码中)
UPDATE END_DATE IN A WHERE A.ID = something_from_B
INSERT new VALUES IN A
无论如何都需要插入。因此无需检查该行是否存在(并且仅在该行存在时更新)。只是 end_date 所有匹配 B 的记录。这将 end_date 0 到 n 行。然后将所有内容插入在一起,而不必担心该记录是否已经过期。
如果您想要事务原子性,请将其放在 BEGIN...END;
中。
简而言之 - 没有。 MERGE 语句提供了在未找到匹配数据时进行 INSERT 和在找到匹配数据时进行 UPDATE 的选项。如果找到匹配数据,它不会为 "update-and-insert" 提供选项。
祝你好运。
据我了解,您编写了一个伪代码。所以我也可以在伪代码中提出一个想法:
MERGE INTO A
USING (select * from B1 union all
select * from B2) B
ON (A.ID = B.ID)
WHEN MATCHED THEN
UPDATE END_DATE ON THE EXISTING ROW FROM B1;
WHEN NOT MATCHED THEN
INSERT A NEW ROW WITH NEW VALUES FROM B2;
如果要将更新的行作为新行插入,可以基于 B
生成子查询,其中将包含 "updated rows",但这些行必须被 [=22= 视为新行] 引擎(如果没有关于你的表的详细信息,就不可能说如何去做)。在我的查询中 B1
是 "rows to update",B2
是 "updated rows which have to look as new"。如果您这样做,将插入更新的行。
另外,不能保证在您的情况下可以实施。
如果您确实在做 2 类维度并想使用合并,是的,它可以完成,但不是非常简单。实际上,如果您需要在 USING 子句中使用内联视图来比较您的数据,该视图具有一个列,指示它是插入还是更新。该字段连接到一个缓慢变化的维度 table,该维度决定是否发生插入或更新。
这篇博客 post 非常详细地描述了这项技术并且对我们很有用,尽管我们使用散列来确定不确定性而不是逐列比较。
Load Slowly Changing Dimension Type 2 using Oracle Merge Statement
我希望使用 PL/SQL 的 MERGE 语句在我的维度 table 中实现一种类型 2 缓慢变化的维度行为。它适用于更新现有值和插入新值。我希望通过不仅更新现有值而且使用更新值创建不同的行同时保留具有 "outdated" 值的行来扩展此功能。
简而言之,可以这样做吗?
MERGE INTO A
USING B
ON (A.ID = B.ID)
WHEN MATCHED THEN
UPDATE END_DATE ON THE EXISTING ROW;
INSERT UPDATED VALUES IN A NEW ROW;
WHEN NOT MATCHED THEN
INSERT A NEW ROW WITH NEW VALUES;
先谢谢大家了。
您需要 运行 两个语句而不是此处的 1 个。
(在你的伪代码中)
UPDATE END_DATE IN A WHERE A.ID = something_from_B
INSERT new VALUES IN A
无论如何都需要插入。因此无需检查该行是否存在(并且仅在该行存在时更新)。只是 end_date 所有匹配 B 的记录。这将 end_date 0 到 n 行。然后将所有内容插入在一起,而不必担心该记录是否已经过期。
如果您想要事务原子性,请将其放在 BEGIN...END;
中。
简而言之 - 没有。 MERGE 语句提供了在未找到匹配数据时进行 INSERT 和在找到匹配数据时进行 UPDATE 的选项。如果找到匹配数据,它不会为 "update-and-insert" 提供选项。
祝你好运。
据我了解,您编写了一个伪代码。所以我也可以在伪代码中提出一个想法:
MERGE INTO A
USING (select * from B1 union all
select * from B2) B
ON (A.ID = B.ID)
WHEN MATCHED THEN
UPDATE END_DATE ON THE EXISTING ROW FROM B1;
WHEN NOT MATCHED THEN
INSERT A NEW ROW WITH NEW VALUES FROM B2;
如果要将更新的行作为新行插入,可以基于 B
生成子查询,其中将包含 "updated rows",但这些行必须被 [=22= 视为新行] 引擎(如果没有关于你的表的详细信息,就不可能说如何去做)。在我的查询中 B1
是 "rows to update",B2
是 "updated rows which have to look as new"。如果您这样做,将插入更新的行。
另外,不能保证在您的情况下可以实施。
如果您确实在做 2 类维度并想使用合并,是的,它可以完成,但不是非常简单。实际上,如果您需要在 USING 子句中使用内联视图来比较您的数据,该视图具有一个列,指示它是插入还是更新。该字段连接到一个缓慢变化的维度 table,该维度决定是否发生插入或更新。
这篇博客 post 非常详细地描述了这项技术并且对我们很有用,尽管我们使用散列来确定不确定性而不是逐列比较。
Load Slowly Changing Dimension Type 2 using Oracle Merge Statement