2015-03-13 92 views
1

我创建了一个功能:函数返回没有在甲骨文

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; 

为什么会这样呢?

+0

为什么你一旦你有结果递归调用相同的函数? – kevinsky 2015-03-13 16:22:47

+0

适合我。您确定dbms_output已启用? – OldProgrammer 2015-03-13 17:11:49

+1

你有'owner ='MyOwner''和'v_table_name varchar2(100):='MyTable';'。我认为这些都是你给出的例子。在你的真实情况下,他们是大写?如果不是,请尝试使它们成为大写。 – Boneist 2015-03-13 17:19:16

回答

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为您提供必要的权限,以便您能够在未见的情况下查看该视图。然后,您将不会受限于您有直接选择权限的表格。