【问题标题】:Function returns nothing in oracle函数在 oracle 中不返回任何内容
【发布时间】:2015-03-14 02:22:55
【问题描述】:

我创建了一个函数:

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;

为什么会这样?

【问题讨论】:

  • 为什么在得到结果后递归调用相同的函数?
  • 对我来说很好。您确定 dbms_output 已启用?
  • 你有owner = 'MyOwner'v_table_name varchar2(100) := 'MyTable';。我认为这些是您给出的示例名称;在你的真实情况下,它们是大写的吗?如果不是,请尝试将它们设为大写。
  • @Boneist 是的,这些是示例名称,真实姓名是大写的。
  • @OldProgrammer 是的,我确信 dbms_output 已启用,因为当我使用显式 SELECT INTO 运行匿名块时,它会导致连接列名,但是当函数被分配给 dbms_output.put_line 参数变量时,它没有结果 - 输出没有任何结果。

标签: oracle plsql oracle11g


【解决方案1】:

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

这意味着您的架构对您要查找的表具有通过角色授予的选择权限。在命名的 PL/SQL 块内不尊重此类权限。如果您在运行select ... into 版本之前执行set role none,您将能够看到相同的内容;该表不会出现在您的ALL_TAB_COLUMNS 中,因为您将不再有权查询它。

你可以让函数使用invoker's rights而不是默认定义者的权限:

create or replace function get_columns
(v_table_name IN varchar2)
RETURN VARCHAR2
AUTHID CURRENT_USER
AS
...

...但是您依赖调用者有权直接或通过角色查看表。这可能不是一件坏事——如果调用者没有从表中选择的权限,也许你也不希望他们能够看到它的结构。

您也可以将表的权限直接授予函数所有者,但您必须为希望其他人能够通过函数查看的每个表执行此操作,这可能会很痛苦并且失去了角色。

改为查询DBA_TAB_COLUMNS 可能更简单,并让您的 DBA 授予您必要的权限,以便您能够查看该视图(如果您还不能查看)。然后,您将不会被限制在您拥有直接选择权限的表中。

【讨论】:

    猜你喜欢
    • 2013-09-05
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 2017-06-23
    相关资源
    最近更新 更多