PL/SQL - 作为表名的函数参数 - 这怎么可能?

Posted

技术标签:

【中文标题】PL/SQL - 作为表名的函数参数 - 这怎么可能?【英文标题】:PL/SQL - function parameter as table name - how is this possible? 【发布时间】:2019-05-04 09:44:26 【问题描述】:

使用 Oracle 时(使用 12c 企业版 12.1.0.2.0 版),我们可以编写类似 ...

SQL> select * from dual ;
DUMMY  
X  

但是,不能在 FROM 子句中使用“a”作为表,因为它是 - 例如

SQL> select * from 'a' ;

Error starting at line : 1 in command -
select * from 'a'
Error at Command Line : 1 Column : 15
Error report -
SQL Error: ORA-00903: invalid table name
00903. 00000 -  "invalid table name"
*Cause:    
*Action:

在编写 CURSOR FOR LOOP (PL/SQL) 时,我发现编译了以下函数代码:

create or replace function f (
  a varchar2
) return varchar2
is
begin
  for r in ( select * from a )  -- parameter (type varchar2) as table name!
  loop
    dbms_output.put_line( ' a -> ' || a  ) ;
  end loop;
  return a ;
end f ;
/

Function F compiled

测试

set serveroutput on

SQL> select f( 'z' ) from dual ;
F('Z')  
z       


a -> z
 a -> z

问题

1我们如何在 PL/SQL 游标 for 循环中的 SELECT 语句的 FROM 子句中使用参数名称(表示单个 varchar2)?

2(在示例中)为什么 DBMS_OUTPUT.PUT_LINE() 显然执行了两次?

【问题讨论】:

我假设你有一个名为a 的表,试试select * from a,那么你应该会看到它。 @WernfriedDomscheit 不,没有名为 a 的表。 a 是单个 varchar2 值。 我怀疑,试试aa,然后你应该得到错误。 @WernfriedDomscheit - 你对的!我不应该把测试表留在这个架构中。 这是一个有价值的教导。下次当你发现 Oracle 做了一些奇怪的事情时,记得问问自己,“我忽略了什么明显的事情?” 【参考方案1】:

如果你走这条线

for r in ( select * from a ) -- parameter (type varchar2) as table name!

然后 Oracle 不会从 varchar2 变量 a 中选择 - 它从表 a 中选择,巧合的是,该表与您的变量具有相同的名称。

【讨论】:

以上是关于PL/SQL - 作为表名的函数参数 - 这怎么可能?的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 游标使用参数作为列名

可选参数作为游标中的条件 (PL/SQL)

如何确定通用 PL/SQL 过程的参数(执行 group by 子句)?

pl/sql:在oracle中选择作为函数的参数/参数

pl/sql 过程不允许将表名/视图名作为参数传递

Oracle PL/SQL 传递行类型作为构造函数参数