如何使用使用构建动态SQL

时间:2018-03-26 18:07:45

标签: oracle plsql

我正在尝试动态function collectPuppies (dogs) { let solution=[]; for(let i=0; i<dogs.length; i++){ solution.push(dogs[i].puppies); } return solution; } 这样[[ ]]它工作正常但我想写这样Expected [ [ 'Spot', 'Spotless' ] ] to deeply equal [ 'Spot', 'Spotless' ] 但我有错误我有同样的错误当我想做某事像这样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;的方法是什么?

1 个答案:

答案 0 :(得分:3)

如果要在动态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