函数在oracle中不返回任何内容

函数在oracle中不返回任何内容,oracle,plsql,oracle11g,Oracle,Plsql,Oracle11g,我创建了一个函数: create or replace function get_columns (v_table_name IN varchar2) RETURN VARCHAR2 AS v_columns_list VARCHAR2(2048); BEGIN SELECT listagg(column_name,',') WITHIN GROUP (ORDER BY column_name) AS t_list into v_columns_list FROM ALL_T

我创建了一个函数:

create or replace function get_columns
(v_table_name IN varchar2)
RETURN VARCHAR2
AS
  v_columns_list VARCHAR2(2048);
BEGIN
  SELECT listagg(column_name,',') WITHIN GROUP (ORDER BY column_name) AS t_list into v_columns_list
      FROM ALL_TAB_COLUMNS WHERE owner='MyOwner' AND table_name=v_table_name;
      RETURN v_columns_list;
END;
当我测试此函数时,它不会向输出返回任何内容:

declare
v_columns_list varchar2(2048);
v_table_name varchar2(100) := 'MyTable';
begin
--  SELECT listagg(column_name,',') WITHIN GROUP (ORDER BY column_name) AS t_list INTO v_columns_list
--      FROM ALL_TAB_COLUMNS WHERE owner='MyOwner' AND table_name=v_table_name;
  v_columns_list := get_columns(v_table_name);
  dbms_output.put_line(v_columns_list);
end;
结果:

anonymous block completed
但是,当我测试相同的“SELECT INTO”语句时,它工作正常并返回连接的字符串:

declare
v_columns_list varchar2(2048);
v_table_name varchar2(100) := 'MyTable';
begin
  SELECT listagg(column_name,',') WITHIN GROUP (ORDER BY column_name) AS t_list INTO v_columns_list
      FROM ALL_TAB_COLUMNS WHERE owner='MyOwner' AND table_name=v_table_name;
--  v_columns_list := get_columns(v_table_name);
  dbms_output.put_line(v_columns_list);
end;

为什么会这样?

您的函数正在查询特定用户拥有的表的
所有选项卡列
视图,该视图可能与函数本身所在的架构不同,并且您无法在该函数中看到表列。但是,当您直接或在匿名块中查询
所有选项卡列时,您可以看到表列

这意味着您的架构通过角色对您要查找的表具有select权限。在命名的PL/SQL块中,不会授予此类权限。如果在运行
选择之前执行了
设置角色无
,则可以看到相同的情况。。。进入
版本;该表将不会出现在您的
所有选项卡列中,因为您将不再具有查询该表的权限

您可以使用函数而不是默认定义者的权限:

create or replace function get_columns
(v_table_name IN varchar2)
RETURN VARCHAR2
AUTHID CURRENT_USER
AS
...
。。。但是,您需要依赖于调用方有权直接或通过角色查看表。这可能不是一件坏事——如果调用者没有从表中选择的权限,那么您可能也不希望他们能够看到它的结构

您还可以直接将表的权限授予函数所有者,但对于希望其他人能够通过函数查看的每个表,您都必须这样做,这可能会很痛苦,并失去角色的优势


查询
DBA\u TAB\u列
可能更简单,如果您还不能查看该视图,则让您的DBA授予您必要的权限。这样,您就不会被限制在具有直接选择权限的表中。

一旦得到结果,为什么要递归调用同一个函数?对我来说很好。您确定dbms_输出已启用?您有
owner='MyOwner'
v_table_name varchar2(100):='MyTable'。我想这些都是你举的例子;在你的真实案例中,它们是大写的吗?如果没有,请尝试将其大写。@Boneist是,这些是示例名称,实名是大写。@OldProgrammer是,我确信dbms_输出已启用,因为当我运行带有显式SELECT的匿名块时,结果是作为串联列名,但当函数分配给dbms_output.put_行参数变量时,结果不是这样的——输出没有任何结果。