Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在oracle中传递procedure to select语句的值?_Oracle_Plsql_Oracle11g - Fatal编程技术网

如何在oracle中传递procedure to select语句的值?

如何在oracle中传递procedure to select语句的值?,oracle,plsql,oracle11g,Oracle,Plsql,Oracle11g,我有一个过程,我使用 exec ot.selector('regions'); 但是,我在这一行遇到了错误: select * from ot."||p_table_name||"; 所以我试着做的程序是: create or replace procedure ot.selector(p_table_name varchar2) is cursor cur is select * from ot."||p_table_name||"; begin

我有一个过程,我使用

exec ot.selector('regions');
但是,我在这一行遇到了错误:

 select * from ot."||p_table_name||";
所以我试着做的程序是:

 create or replace procedure ot.selector(p_table_name varchar2)
    is
    cursor cur is
    select * from ot."||p_table_name||";
    begin
    for i in cur
    loop
    dbms_output.put_line(i.region_name);
    end loop;
    end;
我得到的错误是:

Error at line 1
ORA-06550: line 1, column 10:
PLS-00905: object OT.SELECTOR is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
我在制作过程后得到的错误是:

[Warning] ORA-24344: success with compilation error
4/19    PL/SQL: ORA-00903: invalid table name
4/1     PL/SQL: SQL Statement ignored
 (1: 0): Warning: compiled but with compilation errors
您的线路:

 select * from ot."||p_table_name||";
应该是这样的:

 select * from ot. || p_table_name;
这是一个连接符号

希望这将有助于…

您需要对游标使用动态sql

create or replace procedure ot.selector(p_table_name varchar2)
    is
    cur sys_refcursor;
    V_sql varchar2(4000);
    v_rec SOME_TABLE%ROWTYPE; -- add variable table name here
    begin
    V_sql := 'select * from ot.'|| p_table_name;
    Open cur for v_sql;
    LOOP
  FETCH CUR INTO v_rec;
   dbms_output.put_line(v_rec.region_name);
  EXIT WHEN v_rec%NOTFOUND;
END LOOP;
    Close cur;
    end;
    end selector;
    /
干杯

这里有一个可行的替代方案;看看是否有帮助

由于您没有提供测试用例,我正在Scott的部门创建REGIONS表

SQL> create table regions as
  2    select deptno, loc as region_name from dept;

Table created.
功能:

SQL> create or replace procedure selector(p_table_name in varchar2) as
  2    l_str varchar2(200);
  3    rc    sys_refcursor;
  4    l_rc  regions%rowtype;
  5  begin
  6    l_str := 'select * from ' || dbms_assert.sql_object_name(p_table_name);
  7
  8    open rc for l_str;
  9    loop
 10      fetch rc into l_rc;
 11      exit when rc%notfound;
 12      dbms_output.put_line(l_rc.region_name);
 13    end loop;
 14    close rc;
 15  end;
 16  /

Procedure created.
测试:

SQL> set serveroutput on
SQL> exec selector('regions');
NEW YORK
DALLAS
CHICAGO
BOSTON

PL/SQL procedure successfully completed.

SQL>
如果您想知道DBMS_ASSERT用于什么,这里是为了防止注释中提到的SQL注入。如果你通过了任何无效的东西,你会得到

SQL> exec selector('nonexistent_table');
BEGIN selector('nonexistent_table'); END;

*
ERROR at line 1:
ORA-44002: invalid object name
ORA-06512: at "SYS.DBMS_ASSERT", line 316
ORA-06512: at "SCOTT.SELECTOR", line 6
ORA-06512: at line 1


SQL>

请告诉我们错误。谢谢所做的更改请查看错误这是您尝试调用过程时得到的错误…好的,请刷新页面again@VBoksic只是想了解如何在select中调用过程statment@AndrewOP没有这样做。他希望向过程发送一个参数,以便该过程可以进行选择。也许我错了。在这种情况下,我将删除此内容并停止编辑:对不起,我再次尝试了v_new_table varchar2255:=“OT”。| | p|u table_name;并从v_new_表中选择*;但它仍在向我展示error@KarkiAshwin这方面有很多工作要做。甚至不确定你是否能做到。检查这里:太好了,又是一次否决票?!它说:这个答案没有用!它怎么没用?它仍然是活跃的,有了这个答案,我们已经更正了一行代码,我们正朝着正确的方向前进。。。我不明白这个。。。如果被否决,请解释原因?此实现容易受到SQL注入攻击。验证p_表名称是否为有效的数据库对象将有助于保护代码。如何执行此部分:v_rec SOME_table%ROWTYPE;-在这里添加变量表名?好的,那么OP传递的表需要是samenumber,列的类型是regions表吗?只是好奇。提前谢谢你的回答@VBokšić:在我看来,整个故事毫无用处。它仅适用于包含名为REGION\u NAME的列的表。其他一切都将失败。谁想创建这样一个函数?它的可用性非常有限。我可以理解OP是否同时传递表名和列名,但这。。。我不知道它背后有什么要求,也许是家庭作业什么的。不知道。谢谢你的回答。我也是这么想的。我已经研究过是否可以发送一个p_table_名称,然后动态生成其他所有内容,甚至是:l_rc regions%rowtype。我已经得出一个结论,这是不可能的:呵呵,至少在时间上,我必须攻击这个主题。我会让你放弃投票,因为我相信你的回答对整个问题给出了最好的看法。也谢谢你,@VBokšIć: