简体   繁体   English

函数从select语句调用时返回空字符串

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM