我在Scriptella面临一个关于Oracle Sql查询的问题。
我的意图是 - 我必须从PRODUCT_PRICE表中获取从PRODUCT表中获取的每一行(使用where子句确定)的一些列数据,然后如果从PRODUCT_PRICE获取的数据不包含任何内容或为null,那么我必须插入一个新的对应于产品和价值的价格列将id存储到表中,否则如果存在对应于product&amp ;;的行。商店ID,然后我必须更新价格。
以下代码应该清除我所描述的逻辑 -
<query connection-id="db">
select PRODUCT_ID as "product_id1", STORE_ID as "store_id1" from PRODUCT
<query connection-id="db">
select REGULAR_PRICE, PRODUCT_ID as "product_id2", STORE_ID as "store_id2" from PRODUCT_PRICE where PRODUCT_ID=?product_id1 and STORE_ID=?store_id1
<script connection-id="db" if="rownum==0">
insert into PRODUCT_PRICE(REGULAR_PRICE, PRODUCT_ID, STORE_ID) values(?price, product_id1, store_id1)
</script>
<script connection-id="db" if="rownum gt 0">
update REGULAR_PRICE=?price where PRODUCT_ID=?product_id2 and STORE_ID=?store_id2
</script>
</query>
<query>
我的问题是 - 这不起作用!如您所见,如果没有与该产品相对应的数据,我必须将product_id,store_id以及'price'插入到PRODUCT_PRICE表中。商店ID。另外,如果存在一排相同的产品,我只需要更新价格。 STORE_ID。但是当在第二个查询中获取的结果集不包含任何内容时,条件为“rownum == 0”的脚本不起作用。那怎么能在Oracle中实现这个目标呢?
在MySQL或SyBase数据库中,我知道有一种叫做“if exists(select ....)/ then then / else something”的语法,但我在Oracle数据库中找不到任何东西。如何根据Oracle数据库中的选择标准实现此条件插入或更新,因为我们的项目基于Oracle?
P.S。 - 这里“price”变量已在第一个查询之前找到。我只放了代码的相关部分。
答案 0 :(得分:5)
您可以使用count()函数实现它:
<query connection-id="db">
select PRODUCT_ID as "product_id1", STORE_ID as "store_id1" from PRODUCT
<query connection-id="db">
select COUNT(*) as Price_Count from PRODUCT_PRICE where PRODUCT_ID=?product_id1 and STORE_ID=?store_id1
<script connection-id="db" if="Price_Count==0">
insert into PRODUCT_PRICE(REGULAR_PRICE, PRODUCT_ID, STORE_ID) values(?price, product_id1, store_id1)
</script>
<script connection-id="db" if="Price_Count gt 0">
update REGULAR_PRICE=?price where PRODUCT_ID=?product_id1 and STORE_ID=?store_id1
</script>
</query>
<query>
虽然此解决方案应该正常工作,但您可以利用SQL连接的强大功能。以下解决方案仅需要单个查询即可完成此任务。 我将使用左外连接。这个想法是你通过product_id,store_id加入2个表。如果product_price表中没有匹配项,则相应的price属性将为null。想象一下,您有以下输入:
select * from product;
PRODUCT_ID STORE_ID
1 1
2 1
3 1
select * from product_price;
PRODUCT_ID STORE_ID PRICE
2 1 100
2 1 150
3 1 200
这两个表的左外连接看起来像:
select p.product_id, p.store_id , pp.price from product p LEFT OUTER JOIN product_price pp ON p.product_id =pp.product_id and p.store_id =pp.store_id;
PRODUCT_ID STORE_ID PRICE
1 1 null
2 1 100
2 1 150
3 1 200
然后你需要申请分组并按价格计算:
select p.product_id, p.store_id , count(pp.price) as Prices_Count from product p LEFT OUTER JOIN product_price pp ON p.product_id =pp.product_id and p.store_id =pp.store_id group by (p.product_id, p.store_id)
PRODUCT_ID STORE_ID Prices_Count
1 1 0
3 1 1
2 1 2
然后XML变得微不足道,更重要的是它应该更快,因为数据库连接比任何外部客户端更高效。
<query connection-id="db">
select p.product_id, p.store_id , count(pp.REGULAR_PRICE) as Prices_Count from product p LEFT OUTER JOIN product_price pp ON p.product_id =pp.product_id and p.store_id =pp.store_id group by (p.product_id, p.store_id)
<script connection-id="db" if="Prices_Count==0">
insert into PRODUCT_PRICE(REGULAR_PRICE, PRODUCT_ID, STORE_ID) values(?price, product_id, store_id)
</script>
<script connection-id="db" if="Prices_Count gt 0">
update REGULAR_PRICE=?price where PRODUCT_ID=?product_id and STORE_ID=?store_id
</script>
</query>
我认为通过使用MERGE INTO可以进一步优化该方法,因此所有内容都可以在一个Oracle语句中完成,但我会将其留给饥饿的人。