2010-07-22 9 views
0

這可能不像應該那麼複雜,但Business Objects似乎對使用類型與SQL Developer的方式非常非常嚴格。這裏是有問題的一塊聲明:PL/SQL問題:通過業務對象選擇時不是有效的月份錯誤報告

ship_date between '01' || '-' || w_current_ora_month || '-' || to_char(to_date(w_last_day, 'DD-MON-RR HH:MI:SS AM'), 'yy') and to_char(to_date(w_last_day, 'DD-MON-RR HH:MI:SS AM')) 

w_current_ora_month VARCHAR2(3)通過填充:

SELECT to_char(sysdate, 'MON') 
    INTO w_current_ora_month 
    FROM dual; 

w.last_day日期是通過填充:

SELECT trunc(LAST_DAY('01' || '-' || w_current_ora_month || '-' || to_char(w_year))) 
    into w_last_day 
    from dual 

我爲什麼從Business Objects中獲取無效月錯誤?我已經發現Business對象在類型方面很嚴格,所以我想知道我在這裏做錯了什麼。所有這些在SQL開發人員中都可以正常工作,但我不得不一遍又一遍地調整這個語句,以便在Business Objects使用它時嘗試使用它。

+0

上半場串聯產生'01 -JUL-09',而下半場產生'31 -JUL-09' 數據類型爲DATE。 – jlrolin 2010-07-22 20:27:14

回答

6

你依靠從字符串到日期的隱式轉換,這總是一個壞主意。

如果您必須轉換爲字符串,然後返回日期,請始終使用to_date和日期掩碼。否則,您將依賴於NLS變量,這些變量可以在會話中更改(幾乎可以肯定是您的問題的原因)。

但是,在這種情況下,您不必。你的條件可以簡化爲:

ship_date between trunc(sysdate,'MON') and last_day(trunc(sysdate)) 

由於@APC指出,如果你的字段包含時間成分,你會希望通過一個月的最後一天結束時得到的一切。這可以實現多種方式:

ship_date between trunc(sysdate,'MON') 
       and last_day(trunc(sysdate))+(86399/86400) 

ship_date between trunc(sysdate,'MON') 
       and add_months(trunc(sysdate,'MON'),1)-(1/86400) 

ship_date >= trunc(sysdate,'MON') 
    and ship_date < add_months(trunc(sysdate,'MON'),1) 

我傾向於選擇的最後一個版本,因爲它會繼續工作,如果你決定到外地更改爲TIMESTAMP的道路。

+0

建議的解決方法絕對是處理這些事情的最佳方式。請注意,如果SHIP_DATE包含時間組件記錄,則查詢應使用'last_day(trunc(sysdate))+(86399/86400)' – APC 2010-07-23 10:53:58