Reputation: 299
I have following requirement for writing a query in oracle.
I need to fetch all the records from a Table T1 (it has two date columns D1 and D2)based on two dynamic values V1 and V2. These V1 and V2 are passed dynamically from application. The possible values for V1 are 'Less than' or 'Greater than'. The possible value for V2 is a integer number.
Query i need to write:
If V1 is passed as 'Less than' and V2 is passed as 5, then I need to return all the rows in T1 WHERE D1-D2 < 5.
If V1 passed as 'Greater than' and V2 passed as 8, then I need to return all the rows in T1 WHERE D1-D2 > 8;
I could think that this can be done using a CASE statement in where clause. But not sure how to start.
Any help is greatly appreciated. Thanks
Upvotes: 1
Views: 818
Reputation: 17920
PL/SQL
Solution, not straight forward, but can be customized for complex logics!
Create nested table sql objects
CREATE TYPE MY_RECORD_TYPE IS OBJECT
(
D1 VARCHAR2(100),
D2 VARCHAR2(100),
D3 VARCHAR2(100),
D4 VARCHAR2(100)
);
/
CREATE TYPE MY_TABLE_TYPE IS TABLE OF MY_RECORD_TYPE;
/
Here is the Function that returns a nested table.
create or replace function check_me(v1 varchar2,v2 number)
return MY_TABLE_TYPE
is
v_query varchar2(4000);
my_cur sys_refcursor;
v_record MYTABLE%ROWTYPE; -- Create a local record of table's row type
v_nested MY_TABLE_TYPE := MY_TABLE_TYPE();
I NUMBER;
begin
v_query := 'SELECT * FROM MYTABLE WHERE D1 - D2 ';
IF( UPPER(v1) = UPPER('Less Than')) THEN
v_query := v_query||' > :V2';
ELSE
v_query := v_query||' < :V2';
END IF;
DBMS_OUTPUT.PUT_LINE(v_query);
OPEN my_cur FOR v_query USING V2;
I:=0;
LOOP
FETCH my_cur INTO v_record;
EXIT WHEN my_cur%NOTFOUND;
v_nested.EXTEND(1);
I := I + 1;
/* Copy it into the nested table - Painful!!*/
v_nested(I) := MY_RECORD_TYPE(
v_record.D1,
v_record.d2,
v_record.D3,
v_record.D4
);
END LOOP;
CLOSE my_cur;--CLose the cursor
return v_nested;--return the nested table
end;
/
And you can run as,
select * FROM TABLE(check_me(',',5));
Upvotes: 0
Reputation: 1270401
You could write this as:
select *
from t1
where (v1 = 'Less Than' and D1 - D2 < v2) or
(v1 = 'Greater Than' and D1 - D2 > v2)
A case
statement isn't needed.
Upvotes: 3
Reputation: 3456
Try this:
select *
from T1
where case when V1 = 'LESS THAN' THEN D1 - D2 < V2 ELSE D1 - D2 > V2
This assume if V1 is not LESS THAN the only other value is greater than. If necessary you can use more than one case statement but this should get you started.
Upvotes: 1