2015-03-13 79 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爲您提供必要的權限,以便您能夠在未見的情況下查看該視圖。然後,您將不會受限於您有直接選擇權限的表格。