如何在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ć: