2013-04-10 95 views
1

我正面臨一個關於Scriptella中Oracle Sql查詢的問題。我的意圖是 - 我必須從PRODUCT_PRICE表中獲取從PRODUCT表中獲取的每一行(使用where子句確定)的一些列數據,然後如果從PRODUCT_PRICE獲取的數據不包含任何內容或null,那麼我必須插入一個對應於產品&商店標識的價格值的新列,或者如果存在對應於商品&商店標識的行,那麼我必須更新價格。Oracle SQL&scriptella:如何根據選擇標準進行條件插入或更新?

下面的代碼應該清楚這我所描述的邏輯 -

<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表中。此外,如果存在一行相同的產品& store_id,我必須更新唯一價格。但是,當在第二個查詢中獲取的resulset不包含任何內容時,那麼條件爲「rownum == 0」的腳本不起作用。那麼在Oracle中如何實現這一點?在MySQL或SyBase數據庫中,我知道有一種語法叫做「if exists(select ....)/ then something/else something」,但我在Oracle數據庫中找不到任何東西。如何根據Oracle數據庫中的select標準實現這種條件插入或更新,因爲我們的項目基於Oracle?

P.S. - 這裏的「價格」變量已經在第一次查詢之前找到。我只把代碼的相關部分。

回答

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來連接兩個表。當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> 

我認爲這種方法可以通過合併成甚至進一步優化,所以一切都可以在一個Oracle的語句來完成,但我會離開它飢渴的心靈。

+0

Awsome EJBOY !!! – user1838450 2013-04-10 17:07:09

+0

謝謝你這個問題。 3年多來,我並沒有沉重的SQL。對我來說這是一個很好的做法! – ejboy 2013-04-10 18:07:03