Reputation: 11
DECLARE FILTER_DATA CURSOR WITH RETURN FOR
SELECT C_ID, C_NAME
FROM DB2ADMIN.COURSES
WHERE C_ID = PARM_ID AND AND C_NAME = PARM_NAME
A procedure contains this cursor and the cursor have AND
operator in WHERE
clause, but I want to make this operator dynamic based on procedure parameter.
So that the cursor return resultset on the basis of either AND
or OR
operator.
Thanks in advance!
Upvotes: 0
Views: 251
Reputation: 12314
Use dynamic sql.
begin
...
DECLARE FILTER_DATA CURSOR WITH RETURN FOR s1;
CASE PARM_FLAG
WHEN 1 THEN
PREPARE S1 FROM 'SELECT C_ID, C_NAME FROM DB2ADMIN.COURSES WHERE C_ID = ? AND C_NAME = ?';
ELSE
PREPARE S1 FROM 'SELECT C_ID, C_NAME FROM DB2ADMIN.COURSES WHERE C_ID = ? OR C_NAME = ?';
END CASE;
OPEN FILTER_DATA USING PARM_ID, PARM_NAME;
end@
If you expect NULL
parameter input, you may do something like this for each statement:
PREPARE S1 FROM 'SELECT C_ID, C_NAME FROM DB2ADMIN.COURSES WHERE '
||case when PARM_ID is null then 'cast(? as int) is null' else 'C_ID = ?' end
||' AND '
||case when PARM_NAME is null then 'cast(? as varchar(1)) is null' else 'C_NAME = ?' end;
Upvotes: 1
Reputation: 18408
Don't.
Prepare/use a distinct SQL statement for each possible case/predicate (each possible kind of where clause) and pick the one to use based on the user input you're getting.
Technically, it is acceptable to write stuff like
WHERE :PARM_ID IS NULL OR ID = :PARM_ID
or
WHERE (:CASE = 'OR' AND (C_1 OR C_2)) OR (:CASE = 'AND' AND (C_1 AND C_2))
but you stand very little chance that it will also be acceptable performance-wise. (You have a near guarantee of a full table scan for each single invocation.)
Upvotes: 1