Home » SQL & PL/SQL » SQL & PL/SQL » Need Static SQL (Oracle 10g)
Need Static SQL [message #604054] Mon, 23 December 2013 06:36 Go to next message
sss111ind
Messages: 634
Registered: April 2012
Location: India
Senior Member

Hi All,

As dynamic sql is never good thing .How can I achieve in static sql.
CREATE OR REPLACE
PROCEDURE test_proc(
    p_type  IN VARCHAR2,
    p_value IN VARCHAR2)
IS
TYPE c1 IS REF CURSOR;
    cur_emp c1;
    rec_emp emp%rowtype;
    l_str VARCHAR2(1000):='select * from emp where ';
  BEGIN
    IF p_type   ='JOB' THEN
      l_str    :=l_str|| 'JOB = :p_value ';
    elsif p_type='DEPTNO' THEN
      l_str    :=l_str|| 'DEPTNO = :p_value ';
    elsif p_type='MGR' THEN
      l_str    :=l_str|| 'MGR = :p_value ';
    ELSE
      NULL;
    END IF;
    dbms_output.put_line(l_str);
    OPEN cur_emp FOR l_str USING p_value;
    loop
      fetch cur_emp INTO rec_emp;
    exit
  WHEN cur_emp%notfound;
    dbms_output.put_line(rec_emp.ename);
  END loop;
  CLOSE cur_emp;
END; 


exec test_proc ('DEPTNO','10');

Re: Need Static SQL [message #604056 is a reply to message #604054] Mon, 23 December 2013 06:47 Go to previous messageGo to next message
ThomasG
Messages: 3211
Registered: April 2005
Location: Heilbronn, Germany
Senior Member
With some pretty simple and/or for example:
select * from emp 
 where (p_type = 'JOB'    and job    = p_value)
    or (p_type = 'DEPTNO' and debtno = p_value)
    or (p_type = 'MGR'    and mgr    = p_value)
Re: Need Static SQL [message #604057 is a reply to message #604056] Mon, 23 December 2013 06:49 Go to previous messageGo to next message
sss111ind
Messages: 634
Registered: April 2012
Location: India
Senior Member

Good example, but if there are more than 1 million records then is it worth of doing that.
Re: Need Static SQL [message #604062 is a reply to message #604057] Mon, 23 December 2013 07:02 Go to previous messageGo to next message
ThomasG
Messages: 3211
Registered: April 2005
Location: Heilbronn, Germany
Senior Member
Yes.
Re: Need Static SQL [message #604115 is a reply to message #604057] Tue, 24 December 2013 04:07 Go to previous messageGo to next message
martijn
Messages: 286
Registered: December 2006
Location: Netherlands
Senior Member
Why would that not be a good idea?
Re: Need Static SQL [message #604794 is a reply to message #604115] Sat, 04 January 2014 02:28 Go to previous messageGo to next message
sss111ind
Messages: 634
Registered: April 2012
Location: India
Senior Member

Hi All,

Which one is better performance wise the above one or this one
CREATE OR REPLACE
PROCEDURE test_proc(
    p_type  IN VARCHAR2,
    p_value IN VARCHAR2)
IS
cur_emp sys_refcursor;
rec_emp emp%rowtype;
  BEGIN
  decide_type(p_type ,p_value ,cur_emp);      
    loop
      fetch cur_emp INTO rec_emp;
    exit
  WHEN cur_emp%notfound;
    dbms_output.put_line(rec_emp.ename);
  END loop;
  CLOSE cur_emp;
END; 


CREATE OR REPLACE PROCEDURE decide_type(p_type IN VARCHAR2,p_value in varchar2,rec_emp out  sys_refcursor)
is
BEGIN
  IF p_type   ='JOB' THEN
      OPEN rec_emp for select * from emp where JOB = p_value ;
    elsif p_type='DEPTNO' THEN
      OPEN rec_emp for select * from emp where deptno = p_value ;
    elsif p_type='MGR' THEN
      OPEN rec_emp for select * from emp where mgr = p_value ;
    ELSE
      OPEN rec_emp for select * from emp where 1=2;
    END IF;
end;

exec test_proc ('DEPTNO','10');
Re: Need Static SQL [message #604824 is a reply to message #604794] Sat, 04 January 2014 05:54 Go to previous messageGo to next message
Littlefoot
Messages: 21808
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
Run both solutions, compare them and you'll know.
Re: Need Static SQL [message #604832 is a reply to message #604824] Sat, 04 January 2014 06:19 Go to previous messageGo to next message
sss111ind
Messages: 634
Registered: April 2012
Location: India
Senior Member

Sure I will test that. But What is good for your point of view. Please let me know.

[Updated on: Sat, 04 January 2014 06:20]

Report message to a moderator

Re: Need Static SQL [message #604839 is a reply to message #604832] Sat, 04 January 2014 07:46 Go to previous message
Kevin Meade
Messages: 2103
Registered: December 1999
Location: Connecticut USA
Senior Member
It is hard to say what is best solution, and different versions of the database will likely give differing performance due to different optimizations and transformations they know how to do. For example, theoretically the query already provided:

select * from emp 
 where (p_type = 'JOB'    and job    = p_value)
    or (p_type = 'DEPTNO' and debtno = p_value)
    or (p_type = 'MGR'    and mgr    = p_value)

Could be transformed by the database into a "manually partitioned view" so to speak. This was common back in the day but had to be specifically coded by the developer. Today Oracle knows how to do this automatically.

select * from emp 
 where (p_type = 'JOB'    and job    = p_value)
union all
select * from emp 
 where (p_type = 'DEPTNO' and debtno = p_value)
union all
select * from emp 
 where (p_type = 'MGR'    and mgr    = p_value)

After the query was transformed to this form, the database would at runtime check the value of the parameter against each of the constants and essentially "remove" i.e. not execute those parts where the parameter=constant failed. This essentially turns the three part query into a one part query as only the surviving sub-query would actually be executed. This is a form or query leg pruning covered by the generalized label of short circuiting. For example, if the value of p_type was JOB then only the sub-query referencing 'JOB' would be executed. The other two would be short-circuited.

So the OR query can be the same as using only the correct single component query once shirt circuiting is applied. But the database has to decide that the transform is legal for your query first.

The answer to your question "which is better" could be DOES NOT MATTER because Oracle will change it anway. Oracle will figure out the best thing to do and do it.

Kevin

[Updated on: Sat, 04 January 2014 07:48]

Report message to a moderator

Previous Topic: QUERY FOR HOW TO ACCESS NEXT ROW WHILE IN CURRENT ROW
Next Topic: ORA-00054: resource busy and acquire with NOWAIT specified or timeout
Goto Forum:
  


Current Time: Fri Apr 26 16:05:40 CDT 2024