2016-07-05 152 views
0

首先,感謝您花時間閱讀本文,我對MSSQL的大多數版本都有相當豐富的經驗,但與Oracle和PL SQL沒有多大關係。Oracle 11x新手 - 簡單但真誠...

我的問題是這樣的: 我在MSSQK2k12中有一個SSRS報告,它正在調用Oracle 11x數據庫上的存儲過程。有幾個參數在where子句中使用,我需要再添加一個參數(簡單的Y/N),它將在where子句中添加額外的過濾器,在報告提示符處有效地說'你想看看全部零件? (Y/N)。 'Y'答案將使得proc幾乎全面開放,包括沒有庫存的部件,手頭零件,但已經售出,零件不再有效。 'N'響應將通過需要可用庫存的過濾器,當前有效的零件類別等。 我曾嘗試過六種看似不錯的解決方案,但無濟於事。我已經問過一位準專業人士(他精通PLSQL)的建議,他所得到的'DECODE'加法沒有做任何事情。我想請求不需要幾個月學習的建議/協助,因爲我只有幾天的時間才能完成。請注意,原來的SP不是我的工作,我從前輩那裏繼承了下去/無法完成。存儲過程(Scrubbed)附加

CREATE OR REPLACE PROCEDURE ORACLE_PROD.RPT_LIKE_PARTS_TEST (
    p_Pos1 IN varchar2 
    , p_Description IN varchar2 
    , p_StartPos IN varchar2 
    , p_StartPosValue IN varchar2 
    , p_ViewAll IN varchar2 --ADDED to allow filtered return for data 
    , p_recordset OUT SYS_REFCURSOR) 
AS 
BEGIN 

OPEN p_recordset FOR 
    SELECT T1.ITEM 
    , T1.REVISION 
    , T1.DESCRIPTION 
    , T2.CCN 
    , T2.DELETED 
    , T2.OBSOLETED 
    , T2.FINGOOD 
    , T2.ABC 
    , T3.MAS_LOC 
    , T3.LOCATION 
    , (T3.OH_QTY - T3.COM_QTY) - T3.RESV_QTY as Avail_QTY 
    , T1.USER_NUM1 
    , case when T2.HALT<>' ' then 'Y' else NULL end as Halt 
    , T4.DESCRIPTION as T4_Description 
    , det.OH_QTY as Det_OH_QTY 
    , det.COM_QTY as Det_COM_QTY 
    , DECODE(det.INSP_STAT,'3','Passed Inpection' ,DECODE det.INSP_STAT,'1','Waiting Inspection' ,' ')) as Inspect_Descr 
    , T3.RESV_QTY 

    from ITEM T1 
    LEFT OUTER JOIN ITEM_CCN T2 
     ON T1.ITEM=T2.ITEM 
     and T1.REVISION=T2.REVISION 
    LEFT OUTER JOIN ITEM_LOC T3 
     on T2.CCN=T3.CCN 
     and T2.ITEM=T3.ITEM 
     and T2.REVISION=T3.REVISION 
    LEFT OUTER JOIN HALT T4 
     on T2.HALT=T4.HALT 
     and T2.CCN=T4.CCN 
    LEFT OUTER JOIN ITEM_DET det 
     on T3.CCN=det.CCN 
     and T3.ITEM=det.ITEM 
     and T3.REVISION=det.REVISION 
     and T3.MAS_LOC=det.MAS_LOC 
     and T3.LOCATION=det.LOCATION 
where T2.OBSOLETED is null 
    --** all commented parts are attempted adds 
    --&&&and CASE (p_ViewAll) 
    --&&& when 'N' 
    --&&& THEN --T2.HALT = DECODE(T2.HALT,'DSGN', 'XXX',' ','XXX',T2.HALT) 
    -- and 
    --&&& (T2.HALT != 'DSGN' and (((T3.OH_QTY - T3.COM_QTY) - T3.RESV_QTY))> 0 
    --and T2.HALT <> 'DSGN' and T3.mas_loc <>'99' and T3.mas_loc <>' ' 

    --&&&WHEN 'Y' 
    --&&& THEN 
    and T2.HALT <>'DSGN' 
    --&&&ELSE NULL-- or T3.mas_loc <> '') 
    --&&&END 
    --** 
     /*and T2.HALT = decode(p_ViewAll,'Y', 
          DECODE(T2.HALT,'DSGN', T2.HALT), 
          DECODE(T2.HALT,'DSGN', T2.HALT)   

          --DECODE(T2.HALT,'DSGN', 'XXX',' ','XXX',T2.HALT), 
          --DECODE(T2.HALT,'DSGN', 'XXX', T2.HALT)        
        ) 
     and (p_ViewAll != 'Y' or T3.mas_loc not in ('99',' '))*/ 
--** 



    AND UPPER(TRIM(T1.ITEM)) LIKE (CASE WHEN LENGTH(TRIM(p_pos1)) > 0 THEN UPPER(TRIM(p_pos1) || '%') ELSE UPPER(TRIM(T1.ITEM))END) 
    AND UPPER(T1.DESCRIPTION) LIKE (CASE WHEN LENGTH(p_Description) > 0 THEN UPPER(('%' || p_Description || '%')) ELSE UPPER(UPPER(T1.DESCRIPTION))END) 
    AND 
      (CASE WHEN TO_NUMBER(NVL(TRIM(p_StartPos),'0')) > 0 THEN SUBSTR(TRIM(T1.ITEM),TO_NUMBER(TRIM(p_StartPos)),NVL(LENGTH(UPPER(TRIM(p_StartPosValue))),'0')) 
        ELSE 'False' 
      END) 

      = 

      (CASE WHEN TO_NUMBER(NVL(TRIM(p_StartPos),'0')) > 0 THEN NVL(UPPER(TRIM(p_StartPosValue)),'') 
        ELSE 'False' 
      END) 
ORDER BY T1.ITEM 
, T1.revision desc 
; 
END RPT_LIKE_PARTS_TEST; 
/
+0

你可以採取簡單的出路,只是有與他們之間的聯合兩個SELECT語句。所以你的第一個傢伙的where子句將運行where子句的開放部分,並且您的指標='Y',而where子句中的第二個查詢將是您的指標='N' –

回答

1

您必須使用UNION而不是解碼。在UNION的一邊,你必須用外部連接來處理參數Y,而其他的將會像你已經編碼一樣。

或者你需要使用PLSQL的if/else,因爲用戶只能通過其中的一個參數。

說實話,這個問題並不是特定於Oracle和SQL的。

+0

感謝您的回覆,請你解釋一下「在UNION的一邊你必須用外部連接來處理參數Y」......上面提到的另一個很好的答案,因爲它的解決方案不起作用,儘管它很有意義.... – Joe

+0

謝謝,這爲問題的性質提供了一個寶貴的見解(除了缺乏實踐經驗)之外,最終的解決方案是將您的建議與此處提供的其他建議混合使用。兩者一起工作很好。非常感謝 ! – Joe

1

所以與工會全部或聯合的解決方案可能看起來像這樣

/* Formatted on 7/5/2016 1:50:34 PM (QP5 v5.256.13226.35510) */ 
SELECT T1.ITEM, 
     T1.REVISION, 
     T1.DESCRIPTION, 
     T2.CCN, 
     T2.DELETED, 
     T2.OBSOLETED, 
     T2.FINGOOD, 
     T2.ABC, 
     T3.MAS_LOC, 
     T3.LOCATION, 
     (T3.OH_QTY - T3.COM_QTY) - T3.RESV_QTY AS Avail_QTY, 
     T1.USER_NUM1, 
     CASE WHEN T2.HALT <> ' ' THEN 'Y' ELSE NULL END AS Halt, 
     T4.DESCRIPTION AS T4_Description, 
     det.OH_QTY AS Det_OH_QTY, 
     det.COM_QTY AS Det_COM_QTY, 
     DECODE (det.INSP_STAT, '3', 'Passed Inpection', DECODE det.INSP_STAT,'1','Waiting Inspection' ,' ')) as Inspect_Descr 
    , T3.RESV_QTY 

    from ITEM T1 
    LEFT OUTER JOIN ITEM_CCN T2 
     ON T1.ITEM=T2.ITEM 
     and T1.REVISION=T2.REVISION 
    LEFT OUTER JOIN ITEM_LOC T3 
     on T2.CCN=T3.CCN 
     and T2.ITEM=T3.ITEM 
     and T2.REVISION=T3.REVISION 
    LEFT OUTER JOIN HALT T4 
     on T2.HALT=T4.HALT 
     and T2.CCN=T4.CCN 
    LEFT OUTER JOIN ITEM_DET det 
     on T3.CCN=det.CCN 
     and T3.ITEM=det.ITEM 
     and T3.REVISION=det.REVISION 
     and T3.MAS_LOC=det.MAS_LOC 
     and T3.LOCATION=det.LOCATION 
where T2.OBSOLETED is null and p_ViewAll = 'Y' 
UNION ALL 

SELECT T1.ITEM 
    , T1.REVISION 
    , T1.DESCRIPTION 
    , T2.CCN 
    , T2.DELETED 
    , T2.OBSOLETED 
    , T2.FINGOOD 
    , T2.ABC 
    , T3.MAS_LOC 
    , T3.LOCATION 
    , (T3.OH_QTY - T3.COM_QTY) - T3.RESV_QTY as Avail_QTY 
    , T1.USER_NUM1 
    , case when T2.HALT<>' ' then 'Y' else NULL end as Halt 
    , T4.DESCRIPTION as T4_Description 
    , det.OH_QTY as Det_OH_QTY 
    , det.COM_QTY as Det_COM_QTY 
    , DECODE(det.INSP_STAT,'3','Passed Inpection' ,DECODE det.INSP_STAT,'1','Waiting Inspection' ,' ')) as Inspect_Descr 
    , T3.RESV_QTY 

    from ITEM T1 
    LEFT OUTER JOIN ITEM_CCN T2 
     ON T1.ITEM=T2.ITEM 
     and T1.REVISION=T2.REVISION 
    LEFT OUTER JOIN ITEM_LOC T3 
     on T2.CCN=T3.CCN 
     and T2.ITEM=T3.ITEM 
     and T2.REVISION=T3.REVISION 
    LEFT OUTER JOIN HALT T4 
     on T2.HALT=T4.HALT 
     and T2.CCN=T4.CCN 
    LEFT OUTER JOIN ITEM_DET det 
     on T3.CCN=det.CCN 
     and T3.ITEM=det.ITEM 
     and T3.REVISION=det.REVISION 
     and T3.MAS_LOC=det.MAS_LOC 
     and T3.LOCATION=det.LOCATION 
where T2.OBSOLETED is null and p_ViewAll = 'N' 
and myfilterstuff = 'whatever' 
+0

謝謝,這爲問題的性質提供了一個寶貴的見解(除了缺乏實際操作經驗)之外,最終的解決方案是您的建議和此處提供的其他建議的混合體。兩者一起工作很好。非常感謝 ! – Joe