Dynamically changing the WHERE clause, without
actually changing it ....
What does that mean by that ?
You may have an application, which allows the user to select on
slightly different criteria. Normally, this would mean that you will need two or more WHERE
clauses or that you will have to dynamically create and modify the WHERE clause. Here is a
third method.
In this example, we want to allow the user to select on job,
exact hiredate, hiredate greater than a value or salary in any
combination.
For example all employees of a particular job with a hiredate
equal to a certain date ....
SELECT * FROM emp
WHERE (job = 'SALESMAN')
AND (TO_CHAR(hiredate,'YYYYMMDD') = '19810220');
... or all employees with with a particular job who are have a
hiredate over a certain date and have a particular salary
SELECT * FROM emp
WHERE (job = 'SALESMAN')
AND (TO_CHAR(hiredate,'YYYYMMDD') > '19800101')
AND (sal = 1600);
With these four possibilities we would need 16 WHERE
clauses or some fairly complex code to modify the WHERE clause !
You can avoid all this work by creating arguments to
"ignore" certain criteria. In this case we will have seven criteria: :job, :ignore_job, :hiredate, :ignore_hiredate_exact, :ignore_hiredate_greather,
:sal and :ignore_sal.
The SELECT statement combines each of the "ignore"
arguments with the appropriate test.
SELECT * FROM emp
WHERE (:ignore_job OR job = :job)
AND (:ignore_hiredate_exact OR
TO_CHAR(hiredate,'YYYYMMDD') = :hiredate)
AND (:ignore_hiredate_greather OR
TO_CHAR(hiredate,'YYYYMMDD') > :hiredate)
AND (:ignore_sal OR sal = :sal);
Basically the "ignore" arguments are used as a flag.
You will set the flag to TRUE if the criteria is not used. In Oracle you specify TRUE as 1 = 1 and FALSE as 1
= 0.
If you set :ignore_job to TRUE, it doesn't matter what is in
job. The result will be that all jobs will be selected. If :ignore_job is to FALSE, then only those jobs that
match the :job argument will be included in the result set. The logic TRUE OR
anything will always be TRUE and hence, ignore the selection criteria under that OR
condition - that's the trick !
Let's make a test with SQL*PLUS and Oracle, the
following two SELECT statements will have exactly the same result set. The lines with 1 = 1
in the WHERE clause are simply ignored.
SELECT * FROM emp
WHERE (1 = 1 OR job = 'SALESMAN')
AND (1 = 1 OR TO_CHAR(hiredate,'YYYYMMDD') = '19810220')
AND (1 = 0 OR TO_CHAR(hiredate,'YYYYMMDD') > '19820101')
AND (1 = 1 OR sal = 1600);
SELECT * FROM emp
WHERE (TO_CHAR(hiredate,'YYYYMMDD') > '19820101');
With this wonderful trick, you can "modify" the WHERE
clause without actually changing it !
|