如何用参数编写一个select语句并用PL / SQL迭代它?

时间:2017-07-10 12:28:03

标签: sql oracle loops plsql

我想在PL / SQL函数中创建一个带参数的for循环。 我希望达到这样的目的:

def form_valid(self, form):
    person = self.kwargs.get('person', None)

有没有办法做到这一点?提前谢谢。

3 个答案:

答案 0 :(得分:1)

如果你真的需要这种动态,那么使用(作为其中一个选项)弱类型的光标。这是一个示例(在此示例中使用了dual表)。

set serveroutput on;

declare
  l_c1 sys_refcursor;
  l_query varchar2(255);   
  --------------------
  l_column  varchar2(11) := 'dummy'; -- column name
  l_tabname varchar2(11) := 'dual';  -- table name
  --------------------
  l_res varchar2(1);
 begin
    l_query := 'select ' || dbms_assert.simple_sql_name(l_column) ||
               '  from ' || dbms_assert.simple_sql_name(l_tabname);
   open l_c1 for l_query;
   loop
     fetch l_c1 into l_res;
     exit when l_c1%notfound;
     dbms_output.put_line(l_res);
   end loop;

 end;

结果:

X
 PL/SQL procedure successfully completed.

注意,您需要知道变量的类型(或者如果您决定使用bulk collect into,则需要知道一个集合),事先会获取结果。其次,由于无法绑定标识符(例如列名,表名),因此必须在进行某种验证后显式连接它们以防止SQL注入。

答案 1 :(得分:0)

你应该像这样使用dynamic SQL by using EXECUTE IMMEDIATE

CREATE OR REPLACE FUNCTION f_example(p_table, p_column) return .... is
   plsql_block varchar2(4000);
begin
   plsql_block : = 'BEGIN
       FOR v_iter in (select ' || p_column || ' from ' || p_table ||' ) LOOP
       DBMS_OUTPUT.PUTLINE(v_iter.p_column);
       END LOOP;
     END;'

EXECUTE IMMEDIATE plsql_block;

END;

有关sql中动态usingin out dynamic sql参数的更多信息,请阅读以下文章

https://docs.oracle.com/cloud/latest/db112/LNPLS/dynamic.htm#LNPLS011

答案 2 :(得分:0)

希望下面的代码段有用。

CREATE OR REPLACE
  FUNCTION dummy_function_test(
      lv_col IN VARCHAR2,
      lv_tab IN VARCHAR2)
      RETURN
      DBMS_SQL.VARCHAR2_TABLE
  AS
    lv_table DBMS_SQL.VARCHAR2_TABLE;
  BEGIN
    EXECUTE IMMEDIATE 'select '||lv_col||' from '||lv_tab BULK COLLECT INTO lv_table;
    FOR I IN lv_table.FIRST..lv_table.LAST
    LOOP
      dbms_output.put_line(lv_table(i));
    END LOOP;
    RETURN lv_table;
  END;

DECLARE
  lv_1 dbms_sql.varchar2_table;
BEGIN
  lv_1:=dummy_function_test('sysdate','dual');
END;