【问题标题】:How to build dynamic SQL with using如何使用 using 构建动态 SQL
【发布时间】:2018-03-27 03:19:34
【问题描述】:

我正在尝试使动态sql 像这样'select col1,col2 from '|| my_table ||' 它工作正常但我想这样写sql_stmt:='select col1,col2 from :myTable'; execute immediate sql_stmt using my_table; 但我有错误当我想做这样的事情时我也有同样的错误v_filter := my_proc(); sql_stmt:='select col1,col2 from my_table where :filter' execute immediate sql_stmt using v_filter;像这样用using 构建动态sql 是不可能的吗?如果不可能,还有什么方法可以避免 sql injections

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    当您想在动态 SQL 中使用表名时,是的 - 您必须将它们连接起来。为了避免 SQL 注入,请使用 DBMS_ASSERT.SQL_OBJECT_NAME。

    这是一个例子:

    SQL> create or replace procedure p_test (par_table in varchar2) is
      2    l_table varchar2(30);
      3    l_str   varchar2(200);
      4    l_cnt   number;
      5  begin
      6    l_table := dbms_assert.sql_object_name(par_table);
      7
      8    l_str := 'select count(*) from ' || par_table;
      9    execute immediate (l_str) into l_cnt;
     10    dbms_output.put_line('Table contains ' || l_cnt || ' rows');
     11  end;
     12  /
    
    Procedure created.
    
    SQL>
    SQL> exec p_test('dept');
    Table contains 4 rows
    
    PL/SQL procedure successfully completed.
    
    SQL> exec p_test('delete from emp');
    BEGIN p_test('delete from emp'); END;
    
    *
    ERROR at line 1:
    ORA-44002: invalid object name
    ORA-06512: at "SYS.DBMS_ASSERT", line 316
    ORA-06512: at "SCOTT.P_TEST", line 6
    ORA-06512: at line 1
    
    
    SQL>
    

    [编辑:WHERE 子句]

    这行得通:

    SQL> create or replace procedure p_test (par_table in varchar2,
      2                                      par_filter in varchar2) is
      3    l_table varchar2(30);
      4    l_str   varchar2(200);
      5    l_cnt   number;
      6  begin
      7    l_table := dbms_assert.sql_object_name(par_table);
      8
      9    l_str := 'select count(*) from ' || par_table ||
     10             ' where deptno = :filter';
     11    execute immediate (l_str) into l_cnt using par_filter;
     12    dbms_output.put_line('Table contains ' || l_cnt || ' rows');
     13  end;
     14  /
    
    Procedure created.
    
    SQL> exec p_test('emp', '10');
    Table contains 3 rows
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    WHERE 子句,修改后只包含 WHERE 关键字,其余用作参数:

    SQL> create or replace procedure p_test (par_table in varchar2,
      2                                      par_filter in varchar2) is
      3    l_table varchar2(30);
      4    l_str   varchar2(200);
      5    l_cnt   number;
      6  begin
      7    l_table := dbms_assert.sql_object_name(par_table);
      8
      9    l_str := 'select count(*) from ' || par_table ||
     10             ' where :filter';
     11    execute immediate (l_str) into l_cnt using par_filter;
     12    dbms_output.put_line('Table contains ' || l_cnt || ' rows');
     13  end;
     14  /
    
    Procedure created.
    
    SQL> exec p_test('emp', 'deptno = 10');
    BEGIN p_test('emp', 'deptno = 10'); END;
    
    *
    ERROR at line 1:
    ORA-00920: invalid relational operator
    ORA-06512: at "SCOTT.P_TEST", line 11
    ORA-06512: at line 1
    
    
    SQL>
    

    这行不通;你问的是这个吗?

    更多关于 Oracle 上的 dynamic SQL 以及堆栈溢出 (How can I create a dynamic WHERE clause.

    【讨论】:

    • 它适用于表名,我想将语句与过滤器连接的 where 子句怎么样?
    猜你喜欢
    • 2016-07-29
    • 1970-01-01
    • 2016-09-26
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 2017-04-11
    相关资源
    最近更新 更多