У нас есть таблица, где даты хранятся как VARCHAR2 (Это устаревшая таблица данных, на которую мы не имеем контроля!) в формате YYYYMMDD. У нас есть только привилегия SELECT в таблице (Невозможно написать процедуру/функции).Oracle - Inline View - Внешнее условие WHERE, примененное inline
Необходимо выбрать все строки из таблицы, где дата -> 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
Действительный выбор данных: (где положение 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')
Выше запрос работает нормально и возвращает допустимые строки wit h строка действительной даты,
Чтобы выбрать записи, имеющие строку даты> SYSDATE, данные выше используются inline, и мы применяем условие> 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 **: вместо предложения WHERE, как у вас есть, вы можете проверить для X.I_DOB TO_CHAR (SYSDATE, 'YYYYMMDD') '.Конечно, это не отвечает на ваш вопрос (и, возможно, вам нужна дата для других вычислений, где вам действительно нужно преобразовать ее в дату); просто указывая, что для этого конкретного запроса существует обходное решение. – mathguy
** ВТОРОЙ ** В поисках намеков; Я думал, что '/ * + ORDERED_PREDICATES * /' должен работать, и это действительно так, если вы объединяете два предложения WHERE в один (без подзапроса), но с подчиненной структурой внешнего запроса это не так. Я напишу, если я смогу найти правильный намек на это (я думал, что «NO_QUERY_TRANSFORMATION» должен работать, но это не так, или я не использовал его правильно). – mathguy