среда, 6 августа 2008 г.

Forms. Особенности режима ввода запроса

Режим ввода запроса это то, что делает Forms продуктом с "интуитивно непонятным пользовательским интерфейсом" с одной стороны, и замечательная, очень функциональная особенность с другой стороны.

Разработчику нужно лишь правильно привязать блок с его элементами(полями) к источнику данных(грубо, к таблице и столбцам), а Forms выдает приложение(форму), с отлично реализованной функцией поиска.

В чем же состоит эта реализация.

Для того чтобы выполнить поиск пользователю нужно запомнить и уметь нажимать на две "магические" клавиши [Ввести запрос] и [Выполнить запрос]. В зависимости от выбранной раскладки клавиатуры ими часто бывают F11/Ctrl-F11 или F7/F8 (задаются/меняются на сервере приложений в текстовом файле frmweb.res)

IMHO, именно необходимость запоминания и делает Forms интуитивно непонятным, ибо интуитивно понятным выглядит движение мыши в сторону кнопки с надписью "Найти".

Так какие же горизонты открываются перед пользователем, после того как клавиша [Ввести запрос] нажата либо им, либо заботливой рукой рядом стоящего консультанта.

Для начала отметим, что действия пользователя в режиме ввода запроса сводятся к тому, чтобы вводить шаблоны значений в поля формы. При выполнении запроса, итоговая фраза WHERE будет содержать отдельное условие для каждого поля, в которое вводился шаблон. Отдельные условия будут соединены через логическое AND.
Здесь рассказывается о том, как узнать какой же в итоге запрос выполнялся.

Ниже перечислены возможности режима ввода запроса, начиная с широко известных и продолжая менее именитыми:

1. Шаблон поля не содержит символов % и _ при этом не начинается с < > = != # :
Условие строится по правилу:
WHERE поле = 'шаблон'

Используется когда нужно найти все записи по точному значению поля.

Пример


Поле Тип Шаблон поиска Условие
---------- ------ ------------- --------------------
USER_NAME Строка SYSADMIN WHERE USER_NAME = 'SYSADMIN'
ENTERED_DB Число 234.12 WHERE ENTERED_DB = 234.12
START_DATE Дата 01.07.08 WHERE START_DATE = TO_DATE('01.07.08','DD.MM.RRRR')*

*Формат даты для функции TO_DATE задается параметром FORMS60_USER_DATE_FORMAT и обычно выставляется в 'DD.MM.RRRR'.

2. Шаблон поля содержит символы % и/или _ при этом не начинается с < > = != # :
Условие строится по правилу:
WHERE поле LIKE 'шаблон'

Используется когда нужно найти все записи по заданному шаблону,
где % заменяет любое количество символов, а _ заменяет любой один символ.

Чаще всего используется для поиска по известной подстроке.
Для дат можно хитрым образом задавать диапазоны, в примере ниже показан поиск всех дат за месяц.

Пример

Поле Тип Шаблон поиска Условие
---------- ------ ------------- --------------------
USER_NAME Строка SYS% WHERE USER_NAME LIKE 'SYS%'
ENTERED_DB Число 234.% WHERE ENTERED_DB LIKE '234.%'
START_DATE Дата %.07.2008 WHERE TO_CHAR(START_DATE, 'DD.MM.RRRR' LIKE '%.07.2008')


3. Для чисел и дат работают операторы сравнения
Для этого шаблон должен начинаться с >, >=, <, <=, <>
или для поиска по диапазону значений
#BETWEEN min AND max

Пример

Поле Тип Шаблон поиска Условие
---------- ------ ------------- --------------------
ENTERED_DB Число >234 WHERE ENTERED_DB > 234
ENTERED_DB Число <=0 WHERE ENTERED_DB <= 0
ENTERED_DB Число #BETWEEN 0 AND 10 WHERE ENTERED_DB BETWEEN 0 AND 10
START_DATE Дата <>01.07.2008 WHERE START_DATE <> TO_DATE('01.07.2008','DD.MM.RRRR')

4. Для любых типов данных работает проверка на неопределенные(пустые) значения
Для этого используется один из шаблонов #IS NULL или #IS NOT NULL

Пример

Поле Тип Шаблон поиска Условие
---------- ------ ------------- ----------------------------
START_DATE Дата #IS NULL WHERE START_DATE IS NULL
DESCRIPTION Строка #IS NOT NULL WHERE DESCRIPTION IS NOT NULL

5. Шаблоны, начинающиеся с # в общем случае.
Вообще то, после начального # можно использовать не только BETWEEN или IS [NOT] NULL, но и любой другой текст, подстановка которого сразу после имени поля приведет к правильно построенному условию.

Пример

Поле Шаблон Условие
---------- ------ --------------------
CREATION_DATE #>TRUNC(SYSDATE) WHERE CREATION_DATE > TRUNC(SYSDATE)
CODE #<>RTRIM(CODE) WHERE CODE <> RTRIM(CODE)

Отметим использование функций (TRUNC, RTRIM,...).
Причем функции могут быть не только системными, но и пользовательскими.

6. Венцом возможностей по построению запроса является использование диалога Query/Where.
По своей сути это возможность напрямую написать текст команды SELECT после фразы WHERE.

Для человека понимающего в синтаксисе команды SELECT это дает огромные возможности по формированию запроса и не только.

Но вот из-за этого "и не только" в ОЕБС начиная с версии 11.5.9 эта возможность обрезана, также как и пункт 5 (Использование # в общем случае). Дело в том, что и 5-й, и 6-й пункты позволяют пользователю включать в текст запроса пользовательские функции. А пользовательские функции, начиная с версии СУБД 8i, могут не только читать данные, но и ,окаймленные автономной транзакцией, изменять их.
А это серьезная дыра в безопасности. Ведь технически подкованный пользователь, сговорившись со специалистом службы поддержки, может творить в системе всё что угодно.
Второй будет как бы случайно писать функции, модифицирующие данные, а первый, как бы случайно их вызывать, выполняя невинные запросы в экранной форме.

Пресекается это переменной FORMS60_RESTRICT_ENTER_QUERY, выставляемой в TRUE на сервере приложений.

Подробнее об этом можно почитать в ноте
257788.1 - Enter Query + :a Does Not Open Query/Where Window ORA-1403

P.S. Некая ироничность свойственная этой заметке(да видимо и другим) является,
в первую очередь, состоянием души и никоим образом не призвана нанести моральный урон
любой категории читающих.

Комментариев нет: