WHERE (UPPER(a.Login_Name) = UPPER('%' || :Login_Name || '%') OR :Login_Name IS NULL)
... должно быть:
WHERE (:Login_Name IS NULL OR UPPER(a.Login_Name) = UPPER('%' || :Login_Name || '%'))
Вы хотите проверить переменную связывания FIRST - в противном случае вы выполняете сравнение данных, прежде чем узнаете, что все равно хотите. Вы получаете наихудшую возможную производительность из запроса.
Далее, если вы собираетесь запускать UPPER для нескольких столбцов - используйте Факторинг подзапроса, чтобы он выполнялся первым:
WITH upper_a AS (
SELECT a.pk,
UPPER(a.login_name) 'login_name',
UPPER(a.display_name) 'display_name',
UPPER(a.email_address) 'email_address',
UPPER(b.institution_desc) 'institution_desc'
FROM a)
SELECT *
FROM A a
JOIN upper_a ua ON ua.pk = a.pk
WHERE :Login_Name IS NULL OR ua.login_name = v_login_name
Oracle плохо работает WHERE (параметр равен NULL ИЛИ t.col = параметр), и вы ничего не получите, используя переменные связывания для параметров с необязательными значениями. То, что вы действительно хотите использовать, это переменные CONTEXT (доступно с 9i).