2011-12-01 86 views
0
CREATE OR REPLACE FUNCTION abc (
p_table_name  IN VARCHAR2 
) 
RETURN VARCHAR2 
IS 
v_var varchar(200); 
v_data VARCHAR2 (4000); 

CURSOR cur_column_list 
IS 
    SELECT column_name AS col_name 
    FROM all_tab_cols 
    WHERE table_name = p_table_name; 
BEGIN 
open cur_column_list; 
loop 
fetch cur_column_list into v_var; 
exit when cur_column_list%notfound; 

    v_data := v_data || ' -- ' || v_var; 

END LOOP; 

RETURN v_data; 
EXCEPTION 
WHEN OTHERS 
THEN 
dbms_output.put_line(sqlerrm); 
END; 
/

致电时从select语句功能从select语句

select abc('pqr') FROM DUAL ; 

abc('PQR')               
1 row selected. 

没有输出检索和PQR中有40列时调用返回空字符串。

+0

当你从光标自己运行select时,它是否返回行? –

+0

@Hallainzil:是的,它返回40条记录 – gaurav

+0

为什么给消极的声誉? – gaurav

回答

2

首先,你到底在传递什么函数?您的SELECT语句显示您正在传递一个小写字符串'pqr'。但用粗体字,你传递一个大写字符串'PQR'。由于表名以大写形式以大写形式存储在数据字典中(除非您碰巧使用了带引号的标识符并指定了小写表名),并且由于您在查询中没有执行UPPER,这是一个重要的区别。

其次,你的异常处理程序的目的是什么?捕获您无法处理的异常并仅调用dbms_output(客户端可能会或可能不会碰巧已启用且可能无法从缓冲区dbms_output中写入数据)读取是没有意义的。除去异常处理程序并查看是否引发错误。第三,运行在定义者权限存储过程中的代码,也就是说,它不能访问通过角色授予的权限。它只能访问直接授予程序所有者的权限。如果该过程的所有者已被授予通过角色访问相关表的权限,则可以直接在SQL * Plus会话中查询ALL_TAB_COLS,并查看表,但是如果查询位于定义者的权限存储过程中,则不能。在SQL * Plus,您可以禁用角色模拟,你将有机会获得的特权的定义者权限存储过程

SQL> set role none 

,然后重试操作。如果您在ALL_TAB_COLS中无法再看到您期望的数据,则需要直接授予该过程的所有者访问表的权限,而不是通过角色授予。或者,您可以授予用户通过SELECT ANY DICTIONARY权限访问DBA_TAB_COLS视图,并将代码更改为使用DBA_TAB_COLS

+0

+1只需添加一个' - ' PL \ SQL中的分隔列列表完全转义了我。 – Ben