[英]function returning empty string when calling from select statement
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;
/
When calling from select statement 从select语句调用时
select abc('pqr') FROM DUAL ;
abc('PQR')
1 row selected.
no output is retrieved and pqr has 40 columns in it . 没有检索到输出,pqr中有40列。
First off, exactly what are you passing to the function? 首先,你究竟传递给函数的是什么? Your
SELECT
statement shows that you are passing a lower case string 'pqr'. 您的
SELECT
语句显示您传递的是小写字符串'pqr'。 But in bold type, you are passing an upper case string 'PQR'. 但是以粗体显示,您传递的是大写字符串'PQR'。 Since table names are stored in upper case in the data dictionary in upper case (unless you happen to have used quoted identifiers and specified a lower case table name) and since you're not doing an
UPPER
in your query, that is an important difference. 由于表名以大写形式存储在大写的数据字典中(除非您碰巧使用了带引号的标识符并指定了小写表名),并且因为您没有在查询中执行
UPPER
,这是一个重要的区别。
Second, what is the purpose of your exception handler? 其次,异常处理程序的目的是什么? It makes no sense to catch an exception that you cannot handle and just call
dbms_output
which the client may or may not happen to have enabled and may or may not read from the buffer dbms_output
writes to. 这是没有意义的赶上,你不能处理并调用异常
dbms_output
,客户端可能会或可能不会发生已经启用,并可能会或可能不会从缓冲区中读取dbms_output
写入。 Remove the exception handler and see if an error is thrown. 删除异常处理程序并查看是否抛出错误。
Third, code running in a definer's rights stored procedure, which this is, does not have access to privileges granted via roles. 第三,在定义者权限存储过程中运行的代码,即无法访问通过角色授予的权限。 It only has access to privileges granted directly to the procedure owner.
它只能访问直接授予过程所有者的权限。 If the owner of the procedure has been granted access to the tables in question via a role, you could query
ALL_TAB_COLS
in a SQL*Plus session directly and see the tables but not if the query was inside a definer's rights stored procedure. 如果已通过角色授予过程的所有者对相关表的访问权限,则可以直接在SQL * Plus会话中查询
ALL_TAB_COLS
并查看表,但如果查询位于定义者的权限存储过程中,则不能查看。 In SQL*Plus, you can disable roles to simulate the privileges you would have access to in a definer's rights stored procedure 在SQL * Plus中,您可以禁用角色以模拟在定义者权限存储过程中可以访问的权限
SQL> set role none
and then retry the operation. 然后重试该操作。 If you can no longer see the data you expect in
ALL_TAB_COLS
, you'd need to grant the owner of the procedure access to the tables directly rather than via a role. 如果您无法再在
ALL_TAB_COLS
看到预期的数据,则需要授予过程所有者直接访问表的权限,而不是通过角色。 Alternately, you could grant the user access to the DBA_TAB_COLS
view via the SELECT ANY DICTIONARY
privilege and change the code to use DBA_TAB_COLS
. 或者,您可以通过
SELECT ANY DICTIONARY
权限授予用户访问DBA_TAB_COLS
视图的权限,并将代码更改为使用DBA_TAB_COLS
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.