2011-09-01 48 views
0

我對DB2有點新,並且在開發查詢時遇到問題。我創建了一個用戶定義的函數,該函數返回一個我想要在更大的select語句中加入和選擇的數據表。我正在研究一個敏感的數據庫,所以下面的查詢不是我正在運行的,但它幾乎完全像它(沒有其他10個連接,我必須做大聲笑)。使用用戶定義的函數作爲表的DB2查詢結構

select 
    A.customerId, 
    A.firstname, 
    A.lastname, 
    B.orderId, 
    B.orderDate, 
    F.currentLocationDate, 
    F.currentLocation 
from 
    customer A 
    INNER JOIN order B 
    on A.customerId = B.customerId 
    INNER JOIN table(getShippingHistory(B.customerId)) as F 
    on B.orderId = F.orderId 
where B.orderId = 35 

,如果我沒有運行此查詢這個偉大的工程在where子句(或一些其他的where子句不檢查一個ID)。當我包括在where子句中,我得到以下錯誤:

Error during Prepare 58004(-901)[IBM][CLI Driver][DB2/LINUXX8664] SQL0901N The SQL statement failed because of a non-severe system error. Subsequent SQL statements can be processed. (Reason "Bad Plan; Unresolved QNC found".) SQLSTATE=58004

我已經跟蹤這個問題到事實,我使用的連接標準的參數(B.customerId)之一。我通過用有效的customerId替換B.customerId來驗證了這一事實,並且查詢效果很好。問題是,在調用此查詢時,我不知道customerId。我只知道orderId(在這個例子中)。

任何想法如何重組這個,所以我只能打1個電話來獲取所有的信息?我知道計劃是問題b/c在調用函數之前customerId沒有得到解決。

回答

0

我發現最好的解決方案(給出當前的查詢結構)是使用一個LEFT連接而不是一個INNER連接來強制連接的LEFT部分發生,這將在客戶端將它解析爲一個值進入函數調用。

select 
    A.customerId, 
    A.firstname, 
    A.lastname, 
    B.orderId, 
    B.orderDate, 
    F.currentLocationDate, 
    F.currentLocation 
from 
    customer A 
    INNER JOIN order B 
    on A.customerId = B.customerId 
    LEFT JOIN table(getShippingHistory(B.customerId)) as F 
    on B.orderId = F.orderId 
where B.orderId = 35 
0

所以,如果我理解正確,函數getShippingHistory(customerId)返回一個表。

如果你用一個客戶ID調用它,那麼表格在你的查詢中加入上面沒有任何問題。

但是你必須查詢上面寫的方式,你問DB2調用(符合您的加入,即每b.customerId和那裏的條件)通過查詢返回的每一行的功能。

所以我不確定你期望什麼樣的行爲,因爲你要求的是你的查詢中的每一行的表格,而db2(也不是我)可以弄清楚結果應該是什麼樣子喜歡。

因此,在重構您的查詢時,請考慮如何在涉及多個客戶ID時更改getShippingHistory邏輯。

+0

相反,實際上是「如果你有一個客戶的ID表被加入在查詢上述問題都沒有把它稱爲」。如果我使用客戶ID,它會失敗。它在返回所有ID時工作正常。 – pinkeerach

+0

噢,您在問題中所說的是「我已通過用有效的customerId替換B.customerId來驗證此事實,並且查詢效果很好。」無論如何,我很高興你解決了它。 –

相關問題