我們有一個表格,其日期以YYYYMMDD格式存儲爲VARCHAR2(它是我們無法控制的遺留數據表格,格式爲:)。我們在表格上只有SELECT特權(不可能寫程序/功能)。Oracle - 嵌入式視圖 - 外部WHERE條件在線應用
需要從表中選擇日期> sysdate的所有行。
我們對有效格式和附加檢查應用正則表達式檢查,以確保該日在給定的月份內有效。所有這些都很棒!我們的內聯視圖選擇確保只選擇具有有效日期字符串的記錄。
但是,當我們申請條件檢查> SYSDATE作爲外部條款 - 我們得到即使內嵌視圖選擇確保沒有這樣的記錄挑選特定的月份錯誤無效的日期。
看起來好像查詢執行是在應用內聯視圖條件之前從外部子句應用條件。欣賞對此行爲的任何評論;而且,我們如何確保只有在符合條件的情況下才能應用來自外部的條件?
數據,並用查詢:
CREATE TABLE TEST_DATA_TABLE
(
DATESTRING VARCHAR2(20 BYTE)
);
插入3行與值:
19960322 --Valid Date in past
19831131 --Invalid Date 11/31
20180224 --Valid Date > SYSDATE
有效數據的選擇: (where子句1保證格式和第2條保證了一個月有效日期):
SELECT datestring AS i_dob
FROM test_data_table
WHERE REGEXP_LIKE (TRIM (datestring),
'(19|20)\d\d(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])')
AND TRIM (datestring) <=
TO_CHAR (
LAST_DAY (
TO_DATE (SUBSTR (TRIM (datestring), 1, 6) || '01',
'YYYYMMDD')),
'YYYYMMDD')
上面的查詢工作正常,返回有效的行與VAL ID日期字符串,
要選擇具有日期字符串> SYSDATE記錄,上述數據被用於內聯和我們如下應用條件> SYSDATE。
SELECT i_dob
FROM (
SELECT datestring AS i_dob
FROM test_data_table
WHERE REGEXP_LIKE (TRIM (datestring),
'(19|20)\d\d(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])')
AND TRIM (datestring) <=
TO_CHAR (
LAST_DAY (
TO_DATE (SUBSTR (TRIM (datestring), 1, 6) || '01',
'YYYYMMDD')),
'YYYYMMDD')
) X
WHERE TO_DATE (X.I_DOB, 'YYYYMMDD') > SYSDATE
它開始拋出錯誤:ORA-01839: date not valid for month specified
看起來像之前應用條件的所有內嵌視圖條件進行檢查。
好的,這是一個有趣的問題 - 感謝發佈它!目前爲止的兩個觀察結果(我會繼續尋找......)** FIRST **:您可以檢查'X.I_DOB> TO_CHAR(SYSDATE,'YYYYMMDD')',而不是'WHERE'子句。當然,這不會回答你的問題(也許你需要其他計算的日期,你真的需要將它轉換爲日期);只是指出這個特定的查詢有一個解決方法。 – mathguy
** SECOND **展望提示;我認爲'/ * + ORDERED_PREDICATES * /'應該可以工作,事實上,如果將兩個WHERE子句合併爲一個子查詢(無子查詢),但使用子查詢 - 外部查詢結構則不行。如果我能夠找出正確的提示(我認爲'NO_QUERY_TRANSFORMATION'應該可以工作,但它沒有或者我沒有正確使用它),我會回寫。 – mathguy