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 abc('pqr') FROM DUAL ;
abc('PQR')
1 row selected.
没有检索到输出,pqr中有40列。
答案 0 :(得分:2)
首先,你准确传递给函数的是什么?您的SELECT
语句显示您传递的是小写字符串'pqr'。但是以粗体显示,您传递的是大写字符串'PQR'。由于表名以大写形式以大写形式存储在数据字典中(除非您碰巧使用了带引号的标识符并指定了小写表名),并且由于您未在查询中执行UPPER
,因此是一个重要的区别。
其次,异常处理程序的目的是什么?捕获一个你无法处理的异常并且只调用客户端可能启用或未启用的dbms_output
并且可能从缓冲区dbms_output
读取也可能不读取它是没有意义的。删除异常处理程序并查看是否抛出错误。
第三,在定义者权限存储过程中运行的代码,即无法访问通过角色授予的权限。它只能访问直接授予过程所有者的权限。如果已通过角色授予过程的所有者对相关表的访问权限,则可以直接在SQL * Plus会话中查询ALL_TAB_COLS
并查看表,但如果查询位于定义者的权限存储过程中,则不能查看。在SQL * Plus中,您可以禁用角色来模拟您在定义者权限存储过程中可以访问的权限
SQL> set role none
然后重试该操作。如果您无法再在ALL_TAB_COLS
中看到预期的数据,则需要授予过程所有者直接访问表的权限,而不是通过角色。或者,您可以通过DBA_TAB_COLS
权限授予用户访问SELECT ANY DICTIONARY
视图的权限,并将代码更改为使用DBA_TAB_COLS
。