如果在游标中未找到 table 中的 NULL 值
NULL values in a table if they're not found in a cursor
我正在尝试:
- 创建一个游标,获取商店中所有商品的当前价格。
- 我通过使用 MERGE 语句批量收集游标和循环更新插入 STORE_INVENTORY table.
- 现在我想将 STORE_INVENTORY table 中不在游标中的 PRICE 列清零。
第 3 步如何完成?我已经可以执行步骤 1 和 2,因为我已经更新或插入了从光标中拉出的项目。
这是一些示例数据:
有 3 个源 table 由外部方更新。我的objective就是把这三个数据源合并成一个单一的table.
来源TABLES
ITEM_DESCRIPTION
ITEM_ID | TYPE
0 | Kitchen
1 | Bath
ITEM_MANIFEST
ITEM_ID | ORIGIN
0 | USA
1 | CHINA
ITEM_PRICE
ITEM_ID | PRICE
0 | 3.99
1 | 2.99
目的地TABLE
STORE_INVENTORY
ITEM_ID | TYPE | ORIGIN | PRICE
0 | Kitchen | CHINA | 3.99
8 | Bath | USA | 2.99
因此,在我执行 SQL 程序后,源 table 将被更新到 STORE_INVENTORY 中,并且所有不在源 table 中的项目都有价格无效。我知道如何进行 Upsert 部分,但我不知道如何取消 STORE_INVENTORY table.
中已经存在的项目的价格
预期输出
STORE_INVENTORY
0 | Kitchen | USA | 3.99
1 | Bath | China | 2.99
8 | Bath | USA | NULL
我从这个例子中知道,如果 ITEM_ID 不在 SOURCE_TABLES 中的任何一个中,我就可以查找然后将其取消,但是如果有更复杂的逻辑来确定从源 table 中提取哪些项目? (这就是我想使用游标的原因)我想知道我是否可以与游标中不存在的内容进行比较?
正如所怀疑的那样,这只需要一个 MERGE 语句:
create table item_description
as
select 0 item_id, 'Kitchen' type from dual union all
select 1 item_id, 'Bath' type from dual;
create table item_manifest
as
select 0 item_id, 'USA' origin from dual union all
select 1 item_id, 'CHINA' origin from dual;
create table item_price
as
select 0 item_id, 3.99 price from dual union all
select 1 item_id, 2.99 price from dual;
create table store_inventory
as
select 0 item_id, 'Kitchen' type, 'CHINA' origin, 3.99 price from dual union all
select 8 item_id, 'Bath' type, 'USA' origin, 2.99 price from dual;
select * from store_inventory;
ITEM_ID TYPE ORIGIN PRICE
---------- ------- ------ ----------
0 Kitchen CHINA 3.99
8 Bath USA 2.99
merge into store_inventory tgt
using (select coalesce(id.item_id, si.item_id) item_id,
coalesce(id.type, si.type) type,
coalesce(im.origin, si.origin) origin,
ip.price
from item_description id
inner join item_manifest im on (id.item_id = im.item_id)
inner join item_price ip on (id.item_id = ip.item_id)
full outer join store_inventory si on (si.item_id = id.item_id)) src
on (src.item_id = tgt.item_id)
when matched then
update set tgt.type = src.type,
tgt.origin = src.origin,
tgt.price = src.price
when not matched then
insert (tgt.item_id, tgt.type, tgt.origin, tgt.price)
values (src.item_id, src.type, src.origin, src.price);
commit;
select * from store_inventory;
ITEM_ID TYPE ORIGIN PRICE
---------- ------- ------ ----------
0 Kitchen USA 3.99
8 Bath USA
1 Bath CHINA 2.99
我所做的只是首先编写 select 语句,该语句从源 tables 生成 item_id、类型、产地和价格的连接列表。
一旦我有了它,就只是对 store_inventory 进行完全外部连接的情况,以确保显示所有行,无论是新行还是现有行。
然后我对 item_id、type 和 origin 列进行了合并,这样即使该行仅存在于 store_inventory table 中,我们仍会看到这些详细信息已填充,但我保留了源行中的价格 - 如果它不存在,则为空。
然后只需将该查询的结果合并回 store_inventory table。
如果您对如何将 merge/update/insert 行放入 table 有疑问,请查看是否可以先编写一个 select 语句来生成您想要的结果。通常只需将该语句插入相关的 merge/update/insert 语句即可。
我正在尝试:
- 创建一个游标,获取商店中所有商品的当前价格。
- 我通过使用 MERGE 语句批量收集游标和循环更新插入 STORE_INVENTORY table.
- 现在我想将 STORE_INVENTORY table 中不在游标中的 PRICE 列清零。
第 3 步如何完成?我已经可以执行步骤 1 和 2,因为我已经更新或插入了从光标中拉出的项目。
这是一些示例数据:
有 3 个源 table 由外部方更新。我的objective就是把这三个数据源合并成一个单一的table.
来源TABLES
ITEM_DESCRIPTION
ITEM_ID | TYPE
0 | Kitchen
1 | Bath
ITEM_MANIFEST
ITEM_ID | ORIGIN
0 | USA
1 | CHINA
ITEM_PRICE
ITEM_ID | PRICE
0 | 3.99
1 | 2.99
目的地TABLE
STORE_INVENTORY
ITEM_ID | TYPE | ORIGIN | PRICE
0 | Kitchen | CHINA | 3.99
8 | Bath | USA | 2.99
因此,在我执行 SQL 程序后,源 table 将被更新到 STORE_INVENTORY 中,并且所有不在源 table 中的项目都有价格无效。我知道如何进行 Upsert 部分,但我不知道如何取消 STORE_INVENTORY table.
中已经存在的项目的价格预期输出
STORE_INVENTORY
0 | Kitchen | USA | 3.99
1 | Bath | China | 2.99
8 | Bath | USA | NULL
我从这个例子中知道,如果 ITEM_ID 不在 SOURCE_TABLES 中的任何一个中,我就可以查找然后将其取消,但是如果有更复杂的逻辑来确定从源 table 中提取哪些项目? (这就是我想使用游标的原因)我想知道我是否可以与游标中不存在的内容进行比较?
正如所怀疑的那样,这只需要一个 MERGE 语句:
create table item_description
as
select 0 item_id, 'Kitchen' type from dual union all
select 1 item_id, 'Bath' type from dual;
create table item_manifest
as
select 0 item_id, 'USA' origin from dual union all
select 1 item_id, 'CHINA' origin from dual;
create table item_price
as
select 0 item_id, 3.99 price from dual union all
select 1 item_id, 2.99 price from dual;
create table store_inventory
as
select 0 item_id, 'Kitchen' type, 'CHINA' origin, 3.99 price from dual union all
select 8 item_id, 'Bath' type, 'USA' origin, 2.99 price from dual;
select * from store_inventory;
ITEM_ID TYPE ORIGIN PRICE
---------- ------- ------ ----------
0 Kitchen CHINA 3.99
8 Bath USA 2.99
merge into store_inventory tgt
using (select coalesce(id.item_id, si.item_id) item_id,
coalesce(id.type, si.type) type,
coalesce(im.origin, si.origin) origin,
ip.price
from item_description id
inner join item_manifest im on (id.item_id = im.item_id)
inner join item_price ip on (id.item_id = ip.item_id)
full outer join store_inventory si on (si.item_id = id.item_id)) src
on (src.item_id = tgt.item_id)
when matched then
update set tgt.type = src.type,
tgt.origin = src.origin,
tgt.price = src.price
when not matched then
insert (tgt.item_id, tgt.type, tgt.origin, tgt.price)
values (src.item_id, src.type, src.origin, src.price);
commit;
select * from store_inventory;
ITEM_ID TYPE ORIGIN PRICE
---------- ------- ------ ----------
0 Kitchen USA 3.99
8 Bath USA
1 Bath CHINA 2.99
我所做的只是首先编写 select 语句,该语句从源 tables 生成 item_id、类型、产地和价格的连接列表。
一旦我有了它,就只是对 store_inventory 进行完全外部连接的情况,以确保显示所有行,无论是新行还是现有行。
然后我对 item_id、type 和 origin 列进行了合并,这样即使该行仅存在于 store_inventory table 中,我们仍会看到这些详细信息已填充,但我保留了源行中的价格 - 如果它不存在,则为空。
然后只需将该查询的结果合并回 store_inventory table。
如果您对如何将 merge/update/insert 行放入 table 有疑问,请查看是否可以先编写一个 select 语句来生成您想要的结果。通常只需将该语句插入相关的 merge/update/insert 语句即可。