SQL Injection
Rajeshwaran, Jeyabal, March 07, 2016 - 10:31 am UTC
I'd strongly recommend against this though. Write static queries directly in PL/SQL! This will make your queries much easier to debug, maintain and optimize.
not only easy to debug,maintain and optimize but also free from SQL-Injection.
March 07, 2016 - 1:16 pm UTC
Yep, great point.
want to buid a code in oracle for analytics purpose
swapnil, March 08, 2016 - 6:17 am UTC
as i mention in title i want this type of querries because user just have to change the table name and col name and the query will generate desire output (i am developing for join duplicate summarize which will help me in project) and i know SP doesn't return table as a result so i am trying the same code in function will it work if i used collection in oracle can you give me an idea about this?
March 08, 2016 - 7:12 am UTC
I have to ask - how many tables do you have that users want to dynamically join ? Even if it was quite a few, I'd be inclined to still have several static queries, eg
procedure P is
begin
if p_query_type = 1 then
[join table1,table2]
elseif p_query_type = 1 then
[join table1,table3]
elseif p_query_type = 1 then
[join table2,table3]
etc
end;
I'd almost prefer the repetition rather then the hassles and risks of buiding dynamic SQL with user-provided join keys !
Cheer,
Connor
want to join SP(function) as a generic
swapnil, March 08, 2016 - 8:41 am UTC
i want a join query to build in such a way that user have to do change in call of SP (for eg column name would be change primary key,secondary key )he does not have to go on in the definition of SP. It should be use for generic join purpose and i want the result in table format also please help and thank you
what should i go for to use this kind of querries?
swapnil, March 08, 2016 - 8:55 am UTC
set serveroutput on
create or replace procedure join_example(tab1 varchar2,tab2 varchar2,col1 varchar2,col2 varchar2,pk varchar2,sk varchar2)
as
var1 varchar2(32000);
var2 varchar2(32000);
v_tem VARCHAR2(32000);
v_tem2 VARCHAR2(32000);
v_tem3 VARCHAR2(32000);
v_tem4 VARCHAR2(32000);
v_tem5 VARCHAR2(32000);
t1 varchar2(50);
t2 varchar2(50);
c1 varchar2(50);
c2 varchar2(50);
p_k varchar2(50);
s_k varchar2(50);
begin
t1:=tab1;
t2:=tab2;
c1:=col1;
c2:=col2;
p_k:=pk;
s_k:=sk;
v_tem:='select '||t1||'.'||c1||','||t2||'.'||c2;
v_tem2:='from '||t1;
v_tem3:='inner join '||t2;
v_tem4:='on '||t1||'.'||pk||'='||t2||'.'||sk;
v_tem5:=v_tem||' '||v_tem2||' '||v_tem3||' '||v_tem4;
execute immediate v_tem5 into var1,var2;
dbms_output.put_line(var1 || ',' || var2);
end;
for execution
exec join_example('c_detail1','c_detail2','CUSTOMER_NAME1','city1','CUSTOMER_NAME2','CUSTOMER_NAME2');
i will just put the name of two tables (c_detail1,c_detail2) columns(customer_name1,city1,customer_name2,city2) and the primary keys (CUSTOMER_NAME1,CUSTOMER_NAME2)
this query works fine but it just show be result on screen and has limited rows and if the limit exceed it throw me an error . So to solve this error and want the output in table what should i do .should i go for pipeline table function.And one more question is there any limitation in pipeline function because my data (tables) will be in huge amount.
March 08, 2016 - 9:38 am UTC
What are you actually trying to achieve here? Why are you building this?
Building a fully generic "submit your own query" procedure is tricky, error-prone and likely to contain security holes.
If this is to provide some ad-hoc reporting functionality to your users you're better off using a tool. e.g. interactive reports in APEX, BI Publisher, etc.
If it's part of an app, just write the static queries in the procedure with parameters to choose between them as needed.
plz tell me how to use
swapnil, March 08, 2016 - 10:15 am UTC
could you please tell me how to use apex for my example just an idea i will build a code if its feasible
i dont want this
A reader, March 09, 2016 - 4:32 am UTC
hi experts,
i want to do dynamic stored procedure or function please help me out with my querry
plz elaborate
A reader, March 09, 2016 - 8:58 am UTC
hi experts
thx for giving your time but it doesnot solve mt problem plz give me the solution for what i am asking using apex or any other way
March 09, 2016 - 9:16 am UTC
What exactly are you asking?
A reader, March 09, 2016 - 9:40 am UTC
set serveroutput on
create or replace procedure join_example(tab1 varchar2,tab2 varchar2,col1 varchar2,col2 varchar2,pk varchar2,sk varchar2)
AS
var1 varchar2(32000);
var2 varchar(32000);
v_tem VARCHAR2(32000);
v_tem2 VARCHAR2(32000);
v_tem3 VARCHAR2(32000);
v_tem4 VARCHAR2(32000);
v_tem5 VARCHAR2(32000);
t1 varchar2(50);
t2 varchar2(50);
c1 varchar2(50);
c2 varchar2(50);
p_k varchar2(50);
s_k varchar2(50);
begin
t1:=tab1;
t2:=tab2;
c1:=col1;
c2:=col2;
p_k:=pk;
s_k:=sk;
dbms_output.Put_line('t1='||t1);
dbms_output.Put_line('t2='||t2);
dbms_output.Put_line('c1='||c1);
dbms_output.Put_line('c2='||c2);
dbms_output.Put_line('p_k='||p_k);
dbms_output.Put_line('s_k='||s_k);
v_tem:='select '||t1||'.'||c1||','||t2||'.'||c2;
v_tem2:='from '||t1;
v_tem3:='inner join '||t2;
v_tem4:='on '||t1||'.'||pk||'='||t2||'.'||sk;
v_tem5:=v_tem||' '||v_tem2||' '||v_tem3||' '||v_tem4;
dbms_output.Put_line('saw='||v_tem5);
end;
i am passing the values to procedure as
exec join_example('ORDERS','RETURN','CUSTOMER_NAME','STATUS','ORDER_ID','ORDER_ID');
and output of my querry is fine as it give me
t1=ORDERS
t2=RETURN
c1=CUSTOMER_NAME
c2=STATUS
p_k=ORDER_ID
s_k=ORDER_ID
saw=select ORDERS.CUSTOMER_NAME,RETURN.STATUS from ORDERS inner join RETURN on ORDERS.ORDER_ID=RETURN.ORDER_ID
the value in v_tem5=saw is the exact query i want to run all values are going properly (to verify i use dbms ouput line) just tell me is there any way to execute the query which come in my v_tem5 variable.so that i can run v_tem5 and it generate me the output of join in table format
A reader, March 09, 2016 - 9:42 am UTC
set serveroutput on
create or replace procedure join_example(tab1 varchar2,tab2 varchar2,col1 varchar2,col2 varchar2,pk varchar2,sk varchar2)
AS
var1 varchar2(32000);
var2 varchar(32000);
v_tem VARCHAR2(32000);
v_tem2 VARCHAR2(32000);
v_tem3 VARCHAR2(32000);
v_tem4 VARCHAR2(32000);
v_tem5 VARCHAR2(32000);
t1 varchar2(50);
t2 varchar2(50);
c1 varchar2(50);
c2 varchar2(50);
p_k varchar2(50);
s_k varchar2(50);
begin
t1:=tab1;
t2:=tab2;
c1:=col1;
c2:=col2;
p_k:=pk;
s_k:=sk;
dbms_output.Put_line('t1='||t1);
dbms_output.Put_line('t2='||t2);
dbms_output.Put_line('c1='||c1);
dbms_output.Put_line('c2='||c2);
dbms_output.Put_line('p_k='||p_k);
dbms_output.Put_line('s_k='||s_k);
v_tem:='select '||t1||'.'||c1||','||t2||'.'||c2;
v_tem2:='from '||t1;
v_tem3:='inner join '||t2;
v_tem4:='on '||t1||'.'||pk||'='||t2||'.'||sk;
v_tem5:=v_tem||' '||v_tem2||' '||v_tem3||' '||v_tem4;
dbms_output.Put_line('saw='||v_tem5);
end;
i am passing the values to procedure as
exec join_example('ORDERS','RETURN','CUSTOMER_NAME','STATUS','ORDER_ID','ORDER_ID');
and output of my querry is fine as it give me
t1=ORDERS
t2=RETURN
c1=CUSTOMER_NAME
c2=STATUS
p_k=ORDER_ID
s_k=ORDER_ID
saw=select ORDERS.CUSTOMER_NAME,RETURN.STATUS from ORDERS inner join RETURN on ORDERS.ORDER_ID=RETURN.ORDER_ID
the value in v_tem5=saw is the exact query i want to run all values are going properly (to verify i use dbms ouput line) just tell me is there any way to execute the query which come in my v_tem5 variable.so that i can run v_tem5 and it generate me the output of join in table format
March 10, 2016 - 3:15 am UTC
Just add a refcursor parameter
SQL> set serveroutput on
SQL> create or replace procedure join_example(tab1 varchar2,tab2 varchar2,col1 varchar2,
2 col2 varchar2,pk varchar2,sk varchar2, rc in out sys_refcursor)
3 AS
4 var1 varchar2(32000);
5 var2 varchar(32000);
6 v_tem VARCHAR2(32000);
7 v_tem2 VARCHAR2(32000);
8 v_tem3 VARCHAR2(32000);
9 v_tem4 VARCHAR2(32000);
10 v_tem5 VARCHAR2(32000);
11 t1 varchar2(50);
12 t2 varchar2(50);
13 c1 varchar2(50);
14 c2 varchar2(50);
15 p_k varchar2(50);
16 s_k varchar2(50);
17 begin
18 t1:=tab1;
19 t2:=tab2;
20 c1:=col1;
21 c2:=col2;
22 p_k:=pk;
23 s_k:=sk;
24
25 dbms_output.Put_line('t1='||t1);
26 dbms_output.Put_line('t2='||t2);
27 dbms_output.Put_line('c1='||c1);
28 dbms_output.Put_line('c2='||c2);
29 dbms_output.Put_line('p_k='||p_k);
30 dbms_output.Put_line('s_k='||s_k);
31
32 v_tem:='select '||t1||'.'||c1||','||t2||'.'||c2;
33 v_tem2:='from '||t1;
34 v_tem3:='inner join '||t2;
35 v_tem4:='on '||t1||'.'||pk||'='||t2||'.'||sk;
36 v_tem5:=v_tem||' '||v_tem2||' '||v_tem3||' '||v_tem4;
37
38 dbms_output.Put_line('saw='||v_tem5);
39
40 open rc for v_tem5;
41
42 end;
43 /
Procedure created.
SQL>
SQL> set serverout on
SQL> variable rc refcursor
SQL> exec join_example('t1','t2','col1','x','col1','y',:rc);
t1=t1
t2=t2
c1=col1
c2=x
p_k=col1
s_k=y
saw=select t1.col1,t2.x from t1 inner join t2 on t1.col1=t2.y
PL/SQL procedure successfully completed.
SQL>
want the result in table
A reader, March 10, 2016 - 5:00 am UTC
hi experts
i can generate the query output as this
t1=ORDERS
t2=RETURN
c1=CUSTOMER_NAME
c2=STATUS
p_k=ORDER_ID
s_k=ORDER_ID
saw=select ORDERS.CUSTOMER_NAME,RETURN.STATUS from ORDERS inner join RETURN on ORDERS.ORDER_ID=RETURN.ORDER_ID
my query also give me the same but i want the result of the query which is in "saw" variable run as a normal sql query and generate the output of the query. The 'saw' variable must return be a table of join of in this order table and return table
is it possible to use execute immediate saw and gives me result of the querry plz help
March 10, 2016 - 6:43 am UTC
Sorry - I didnt cut/paste enough. The refcursor lets you FETCH from that result, eg
SQL> set serverout on
SQL> variable rc refcursor
SQL> exec join_example('t1','t2','col1','x','col1','y',:rc);
t1=t1
t2=t2
c1=col1
c2=x
p_k=col1
s_k=y
saw=select t1.col1,t2.x from t1 inner join t2 on t1.col1=t2.y where rownum < 10
PL/SQL procedure successfully completed.
SQL>
SQL> print rc
COL1 X
---------- ----------
575 575
576 576
577 577
578 578
579 579
580 580
581 581
582 582
583 583
9 rows selected.
(I added the rownum < 10 to the procedure to keep the output small)
A reader, March 10, 2016 - 5:18 am UTC
hi experts
i can generate the query output as this
t1=ORDERS
t2=RETURN
c1=CUSTOMER_NAME
c2=STATUS
p_k=ORDER_ID
s_k=ORDER_ID
saw=select ORDERS.CUSTOMER_NAME,RETURN.STATUS from ORDERS inner join RETURN on ORDERS.ORDER_ID=RETURN.ORDER_ID
my query also give me the same but i want the result of the query which is in "saw" variable run as a normal sql query and generate the output of the query. The 'saw' variable must return be a table of join of in this order table and return table
is it possible to use execute immediate saw and gives me result of the query plz help
in other words i want to execute a query which is in variable (in this example the query is join and the variable is "saw") so suggest me other way to achieve my desired result
procedure join_example - SQL Injection
Rajeshwaran, Jeyabal, March 10, 2016 - 7:04 am UTC
With the procedure "join_example" compiled as such in the database, then SQL-Injection could happen like this.rajesh@ORA11G> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
4 rows selected.
rajesh@ORA11G>
rajesh@ORA11G> create or replace function foo
2 return number
3 as
4 l_sql varchar2(1000);
5 pragma autonomous_transaction;
6 table_doesnot_exits exception ;
7 pragma exception_init(table_doesnot_exits,-00942);
8 begin
9 l_sql :=' drop table dept purge';
10 execute immediate l_sql ;
11 commit;
12 return 0;
13 exception
14 when table_doesnot_exits then
15 return 0;
16 end;
17 /
Function created.
rajesh@ORA11G> variable rc refcursor
rajesh@ORA11G> exec join_example('foo from dual --','t2','col1','x','col1','y',:rc);
t1=foo from dual --
t2=t2
c1=col1
c2=x
p_k=col1
s_k=y
saw=select foo from dual --.col1,t2.x from foo from dual -- inner join t2 on foo from dual --.col1=t2.y
PL/SQL procedure successfully completed.
rajesh@ORA11G> print rc
FOO
----------
0
1 row selected.
rajesh@ORA11G> select * from dept ;
select * from dept
*
ERROR at line 1:
ORA-00942: table or view does not exist
rajesh@ORA11G>Take care to sanitize the inputs using dbms_assert API, that could protect from SQL-Injection bugs. see the below procedure from line-no 18 to 23 rajesh@ORA11G> create or replace procedure join_example(tab1 varchar2,tab2 varchar2,col1 varchar2,
2 col2 varchar2,pk varchar2,sk varchar2, rc in out sys_refcursor)
3 AS
4 var1 varchar2(32000);
5 var2 varchar(32000);
6 v_tem VARCHAR2(32000);
7 v_tem2 VARCHAR2(32000);
8 v_tem3 VARCHAR2(32000);
9 v_tem4 VARCHAR2(32000);
10 v_tem5 VARCHAR2(32000);
11 t1 varchar2(50);
12 t2 varchar2(50);
13 c1 varchar2(50);
14 c2 varchar2(50);
15 p_k varchar2(50);
16 s_k varchar2(50);
17 begin
18 t1:=dbms_assert.SIMPLE_SQL_NAME(tab1);
19 t2:=dbms_assert.SIMPLE_SQL_NAME(tab2);
20 c1:=dbms_assert.SIMPLE_SQL_NAME(col1);
21 c2:=dbms_assert.SIMPLE_SQL_NAME(col2);
22 p_k:=dbms_assert.SIMPLE_SQL_NAME(pk);
23 s_k:=dbms_assert.SIMPLE_SQL_NAME(sk);
24
25 dbms_output.Put_line('t1='||t1);
26 dbms_output.Put_line('t2='||t2);
27 dbms_output.Put_line('c1='||c1);
28 dbms_output.Put_line('c2='||c2);
29 dbms_output.Put_line('p_k='||p_k);
30 dbms_output.Put_line('s_k='||s_k);
31
32 v_tem:='select '||t1||'.'||c1||','||t2||'.'||c2;
33 v_tem2:='from '||t1;
34 v_tem3:='inner join '||t2;
35 v_tem4:='on '||t1||'.'||pk||'='||t2||'.'||sk;
36 v_tem5:=v_tem||' '||v_tem2||' '||v_tem3||' '||v_tem4;
37
38 dbms_output.Put_line('saw='||v_tem5);
39
40 open rc for v_tem5;
41
42 end;
43 /
Procedure created.
rajesh@ORA11G> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
4 rows selected.
rajesh@ORA11G> create or replace function foo
2 return number
3 as
4 l_sql varchar2(1000);
5 pragma autonomous_transaction;
6 table_doesnot_exits exception ;
7 pragma exception_init(table_doesnot_exits,-00942);
8 begin
9 l_sql :=' drop table dept purge';
10 execute immediate l_sql ;
11 commit;
12 return 0;
13 exception
14 when table_doesnot_exits then
15 return 0;
16 end;
17 /
Function created.When the inputs are injected - we would error out, like this.rajesh@ORA11G> variable rc refcursor
rajesh@ORA11G> exec join_example('foo from dual --','t2','col1','x','col1','y',:rc);
BEGIN join_example('foo from dual --','t2','col1','x','col1','y',:rc); END;
*
ERROR at line 1:
ORA-44003: invalid SQL name
ORA-06512: at "SYS.DBMS_ASSERT", line 206
ORA-06512: at "RAJESH.JOIN_EXAMPLE", line 18
ORA-06512: at line 1
In case of no Injection, we would safely execute it like this.rajesh@ORA11G> exec join_example('t1','t2','col1','x','col1','y',:rc);
t1=t1
t2=t2
c1=col1
c2=x
p_k=col1
s_k=y
saw=select t1.col1,t2.x from t1 inner join t2 on t1.col1=t2.y
PL/SQL procedure successfully completed.
rajesh@ORA11G> print rc
no rows selected
rajesh@ORA11G>Everytime you construct the SQL either in the database or in the application, take care to sanitize the inputs using dbms_assert API to project against SQL-Injection.
March 10, 2016 - 9:49 am UTC
Good advice.
it works
A reader, March 10, 2016 - 7:13 am UTC
thanks expert i got my result in cursor ..but how could i get that data in table ...what should i do ?
March 10, 2016 - 9:52 am UTC
A reader, March 10, 2016 - 12:21 pm UTC
thx for your help :) but how could i use that in my case
March 10, 2016 - 12:59 pm UTC
Use the code from the ins_gtt procedure as an example of how to:
- Fetch the results from the refcursor
- Insert them into a table
not getting the result
A reader, March 11, 2016 - 5:05 am UTC
plz elaborate i am not getting the join result in table
thx you
tried the querry but it give nothing in gtt table
A reader, March 11, 2016 - 8:10 am UTC
create table t as
select rownum x from ORDERS;
create global temporary table gtt (
x varchar2(50),y varchar2(50)
);
create or replace procedure join_example1212(tab1 varchar2,tab2 varchar2,col1 varchar2,col2 varchar2,pk varchar2,sk varchar2,cur in out
sys_refcursor)
AS
var1 varchar2(32000);
var2 varchar(32000);
v_tem VARCHAR2(32000);
v_tem2 VARCHAR2(32000);
v_tem3 VARCHAR2(32000);
v_tem4 VARCHAR2(32000);
v_tem5 VARCHAR2(32000);
t1 varchar2(50);
t2 varchar2(50);
c1 varchar2(50);
c2 varchar2(50);
p_k varchar2(50);
s_k varchar2(50);
begin
t1:=dbms_assert.SIMPLE_SQL_NAME (tab1);
t2:=dbms_assert.SIMPLE_SQL_NAME(tab2);
c1:=dbms_assert.SIMPLE_SQL_NAME(col1);
c2:=dbms_assert.SIMPLE_SQL_NAME(col2);
p_k:=dbms_assert.SIMPLE_SQL_NAME(pk);
s_k:=dbms_assert.SIMPLE_SQL_NAME(sk);
dbms_output.Put_line('t1='||t1);
dbms_output.Put_line('t2='||t2);
dbms_output.Put_line('c1='||c1);
dbms_output.Put_line('c2='||c2);
dbms_output.Put_line('p_k='||p_k);
dbms_output.Put_line('s_k='||s_k);
v_tem:='select '||t1||'.'||c1||','||t2||'.'||c2;
v_tem2:='from '||t1;
v_tem3:='inner join '||t2;
v_tem4:='on '||t1||'.'||pk||'='||t2||'.'||sk;
v_tem5:=v_tem||' '||v_tem2||' '||v_tem3||' '||v_tem4;
dbms_output.Put_line('saw='||v_tem5);
open cur for v_tem5 ;
end;
create or replace procedure ins_gtt as
cur sys_refcursor;
type gtt_tab is table of t%rowtype index by binary_integer;
recs gtt_tab;
begin
join_example1212('ORDERS','RETURN','CUSTOMER_NAME','STATUS','ORDER_ID','ORDER_ID',cur);
fetch cur
bulk collect into recs;
forall i in 1 .. recs.count
insert into gtt (x)
values (recs(i).x);
close cur;
end;
i got this message
global temporary TABLE created.
PROCEDURE JOIN_EXAMPLE1212 compiled
PROCEDURE INS_GTT compiled
Error starting at line : 71 in command -
exec INS_GTT
Error report -
ORA-00932: inconsistent datatypes: expected - got -
ORA-06512: at "APEX_VER_1.INS_GTT", line 8
ORA-06512: at line 1
00932. 00000 - "inconsistent datatypes: expected %s got %s"
*Cause:
*Action:
t1=ORDERS
t2=RETURN
c1=CUSTOMER_NAME
c2=STATUS
p_k=ORDER_ID
s_k=ORDER_ID
saw=select ORDERS.CUSTOMER_NAME,RETURN.STATUS from ORDERS inner join RETURN on ORDERS.ORDER_ID=RETURN.ORDER_ID
what should i do and gtt table return nothing what i miss
March 12, 2016 - 1:16 am UTC
type gtt_tab is table of t%rowtype index by binary_integer;
looks wrong.
You want:
type gtt_tab is table of gtt%rowtype index by binary_integer;