Oracle execute immediate 拼接条件 参数化

来源:互联网 发布:练听力软件 编辑:程序博客网 时间:2024/06/06 17:25

最近在将项目的数据库改成Oracle,本人对Oracle也是一无所知,边做边摸索。

在使用 execute immediate 动态执行SQL分页,发现网上很多例子都是通过参数值直接拼接成SQL来执行。

对于Oracle新手来说,好像Oracle没有类似 SQLServer exec sp_executesql 参数化查询这样的功能。

例如:

declare  p_accountnum  varchar2(100);  p_groupid     integer;  p_recordcount integer;  p_select      varchar2(500);begin  p_accountnum := 'gh_xxxxxxxxx';  p_groupid    := 109;  p_select     := 'select count(*) from wxuser where 1=1 and accountnum =''' ||  p_accountnum || ''' and groupid =' || p_groupid;  execute immediate p_select into p_recordcount;  dbms_output.put_line(p_recordcount);end;

这样很明显的一样问题,如果参数p_accountnum存在SQL特殊字符,就会出现SQL注入了。当然你也可以在项目程序中对SQL特殊字符进行过滤。

但有时候在写程序中,可能因各种不小心会忘记对SQL特殊字符过滤,所以最可靠的办法就是直接将值参数化,不通过参数值直接拼接成SQL来执行。

这是我写的一个存储过程,希望可以帮到一些Oracle新手。

procedure SelectByWhere(p_accountnum  in varchar2,                          p_groupid     in integer,                          p_pageindex   in integer,                          p_pagesize    in integer,                          p_recordcount out integer,                          v_result      out pack_wxuser.cur_type) is    v_select varchar2(500);    v_where  varchar2(500);  begin    v_where := ' where 1=1';    if p_accountnum is not null and length(p_accountnum) > 0 then      begin        v_where := v_where || ' and accountnum = :a';      end;    else      begin        v_where := v_where || ' and ((1=1) or :a is null)';      end;    end if;    if p_groupid is not null and p_groupid > 0 then      begin        v_where := v_where || ' and groupid = :b ';      end;    else      begin        v_where := v_where || ' and ((1=1) or :b is null)';      end;    end if;    v_select := 'select count(*) from wxuser' || v_where;    dbms_output.put_line(v_select);    execute immediate v_select      into p_recordcount      using p_accountnum, p_groupid;    v_where := v_where || ' order by subscribe_time desc';    if p_pageindex is not null and p_pageindex > 0 and       p_pagesize is not null and p_pagesize > 0 then      begin        v_select := 'select t.* ,g.groupname groupname from (select w.*, rownum as rowno from (select * from wxuser' ||                    v_where || ') w where rownum <=' ||                    (p_pageindex * p_pagesize) ||                    ') t left join wxgroup g on t.groupid=g.groupid where t.rowno >=' ||                    ((p_pageindex - 1) * p_pagesize);      end;    else      begin        v_select := 'select t.*,g.groupname groupname from ( select * from wxuser' ||                    v_where ||                    ' ) t left join wxgroup g on t.groupid=g.groupid';      end;    end if;    dbms_output.put_line(v_select);    open v_result for v_select      using p_accountnum, p_groupid;  end;





0 0
原创粉丝点击