动态选择执行缺少表达式错误

时间:2017-02-23 13:03:44

标签: oracle oracle12c

我正在使用Oracle 12,我想制作一个动态过程,它从特定的表中选择行但是根据未知的条件。该条件将被指定为输入参数。

假设我有一个名为employee id的列,我想调用该过程 具有以下条件

execute s('employeeid = 2')

我的代码是

create or replace procedure s (condition varchar)
as
   TYPE EmpCurTyp IS REF CURSOR;  -- define weak REF CURSOR type
   emp_cv   EmpCurTyp;  -- declare cursor variable
   my_ename VARCHAR2(15);
   my_sal   NUMBER := 2;
   mycondition varchar2(100):=condition;
BEGIN
   OPEN emp_cv FOR  -- open cursor variable
      'SELECT employeeid, employeename FROM employees WHERE  = :s' USING mycondition;
END;

但是我收到了错误

  

缺少表达

我做错了什么,这个程序的结果是否会从employees表中选择满足应用条件的行?

2 个答案:

答案 0 :(得分:1)

create table someTable(column1 number) 旨在处理值,而不是代码片段;如果你需要根据输入参数编辑你的查询(我相信这是一种非常危险的编码方式),你应该将条件视为一个字符串以连接到查询。

例如,假设您有此表:

create or replace procedure testDyn( condition IN varchar2) is
    cur sys_refcursor;
begin
    open cur for 'select column1 from sometable where ' || condition;
    /* your code */ 
end;    

此程序与您的需求类似:

SQL> exec testDyn('column1 is null');

PL/SQL procedure successfully completed.

SQL> exec testDyn('column99 is null');
BEGIN testDyn('column99 is null'); END;

*
ERROR at line 1:
ORA-00904: "COLUMN99": invalid identifier
ORA-06512: at "ALEK.TESTDYN", line 4
ORA-06512: at line 1

热点有效:

{{1}}

答案 1 :(得分:0)

这还没有嵌入到程序中,但我测试了这个并且有效:

DECLARE
   TYPE OUT_TYPE IS TABLE OF VARCHAR2 (20)
      INDEX BY BINARY_INTEGER;

   l_cursor         INTEGER;
   l_fetched_rows   INTEGER;
   l_sql_string     VARCHAR2 (250);
   l_where_clause   VARCHAR2 (100);
   l_employeeid     VARCHAR2 (20);
   l_employeename   VARCHAR2 (20);
   l_result         INTEGER;
   o_employeeid     OUT_TYPE;
   o_employeename   OUT_TYPE;
BEGIN
   l_cursor := DBMS_SQL.OPEN_CURSOR;
   l_sql_string := 'SELECT employeeid, employeename FROM employees WHERE ';
   l_where_clause := 'employeeid = 2';
   l_sql_string := l_sql_string || l_where_clause;
   DBMS_SQL.PARSE (l_cursor, l_sql_string, DBMS_SQL.V7);
   DBMS_SQL.DEFINE_COLUMN (l_cursor,
                           1,
                           l_employeeid,
                           20);
   DBMS_SQL.DEFINE_COLUMN (l_cursor,
                           2,
                           l_employeename,
                           20);
   l_fetched_rows := 0;
   l_result := DBMS_SQL.EXECUTE_AND_FETCH (l_cursor);

   LOOP
      EXIT WHEN l_result = 0;
      DBMS_SQL.COLUMN_VALUE (l_cursor, 1, l_employeeid);
      DBMS_SQL.COLUMN_VALUE (l_cursor, 2, l_employeename);
      l_fetched_rows := l_fetched_rows + 1;
      o_employeeid (l_fetched_rows) := l_employeeid;
      o_employeename (l_fetched_rows) := l_employeename;
      l_result := DBMS_SQL.FETCH_ROWS (l_cursor);
   END LOOP;

   DBMS_SQL.CLOSE_CURSOR (l_cursor);

   DBMS_OUTPUT.PUT_LINE (o_employeeid (1));
   DBMS_OUTPUT.PUT_LINE (o_employeename (1));
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE ('GENERAL FAILURE: ' || SQLERRM);
END;