由於您用作to_char()
的第一個參數的值未包含在單引號中,因此會發布您發佈的錯誤:
select to_date(01-jan-12,'dd-mon-yy') from dual;
ORA-00904: "JAN": invalid identifier
因爲沒有報價,jan
在您的地址表中解釋爲標識,並有(大概)沒有列呼叫JAN
。使用2位數年份也是不好的做法,並且您必須(從真正的舊數據中)使用RR
通常比YY
更好。月份名稱也受NLS設置的影響,因此使用月份數字比名稱更安全;如果你真的想要名字to_char()
函數有第三個參數來控制語言。
您正在以相當複雜的方式執行此操作,並且您依賴的地址表有足夠的行數。通過day
而不是DAY
指定您希望小寫字母的日期名稱,然後將其設爲大寫,然後剝離字符串的位 - 您首先指定的位! - 只獲取日期名稱,然後再比較假設(再次)NLS設置會爲您提供英文日期名稱......無謂地令人費解。正如您要求固定的字符串文字upper()
所示,您可以(並且)以大寫形式提供。
而不是
WHERE upper(regexp_substr(TO_CHAR(dates,'day-mon-yy'),'([[:alpha:]])+'))=upper('FRIDAY');
,你可以做任何這些或其他變化:
WHERE regexp_substr(TO_CHAR(dates,'DAY-mon-
y'),'([[:alpha:]])+')=upper('FRIDAY');
WHERE TO_CHAR(dates,'DAY')='FRIDAY ';
WHERE TRIM(TO_CHAR(dates,'DAY'))=upper('FRIDAY');
WHERE TO_CHAR(dates,'FMDAY','NLS_DATE_LANGUAGE=ENGLISH')='FRIDAY';
您可避免通過使用分層查詢,對dual
表依託地址表:
SELECT next_day(date '2012-01-01' - 1, 'FRIDAY') + (7 * (level - 1))
FROM dual
CONNECT BY next_day(date '2012-01-01' - 1, 'FRIDAY') + (7 * (level - 1))
<= date '2012-03-31';
使用next_day
也依賴於關於NLS設置的,所以除非你能隨時控制會議日期的語言,它可能是安全的(如果有點低效率)來獲取所有的日期,然後在NLS-獨立的方式進行篩選:
SELECT dates, to_char(dates, 'FMDAY')
FROM (
SELECT date '2012-01-01' + level - 1 AS dates
FROM dual
CONNECT BY level <= date '2012-03-31' - date '2012-01-01'
)
WHERE to_char(dates, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH') = 'FRIDAY';
DATES TO_CHAR(DATES,'FMDAY')
--------- ------------------------------------
06-JAN-12 FRIDAY
13-JAN-12 FRIDAY
20-JAN-12 FRIDAY
27-JAN-12 FRIDAY
03-FEB-12 FRIDAY
10-FEB-12 FRIDAY
17-FEB-12 FRIDAY
24-FEB-12 FRIDAY
02-MAR-12 FRIDAY
09-MAR-12 FRIDAY
16-MAR-12 FRIDAY
23-MAR-12 FRIDAY
30-MAR-12 FRIDAY
13 rows selected.
作爲@mathguy在評論中指出,雖然next_day()
是NLS敏感,你可以使用第二個參數的表達,所以不是硬編碼天名,你可以這樣做:
next_day(date '2012-01-01' - 1, to_char(date '1999-12-31', 'FMDAY'))
,其中1999- 12-31可以是已知的任何星期五的日期;如果您不介意選擇列表中的表達式和連接條款不同(並且實際上,您 - 我也不應該!),則可以減少該檢查的計算成本:
SELECT dates, to_char(dates, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH')
FROM (
SELECT next_day(date '2012-01-01' - 1,
to_char(date '1999-12-31', 'FMDAY')) + (7 * (level - 1)) AS dates
FROM dual
CONNECT BY level <= 1 + (date '2012-03-31' - next_day(date '2012-01-01' - 1,
to_char(date '1999-12-31', 'FMDAY')))/7
);
無論會話的日期語言如何,它都獲得與上面相同的13行。如果您希望輸出也採用會話語言,只需刪除覆蓋的第三個參數to_char()
。
請閱讀[問] – OldProgrammer
什麼是您的問題/問題/錯誤?您所展示的內容在日期字符串周圍需要單引號,但是...無論如何,似乎相當複雜,地址表的相關內容是什麼? –
非常感謝你,我現在忘了單引號,它工作正常 –