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

发布于 2024-12-19 02:55:07 字数 714 浏览 0 评论 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 abc('pqr') FROM DUAL ;

abc('PQR')                                                         
1 row selected.

不会检索任何输出,并且 pqr 中有 40 列。

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 abc('pqr') FROM DUAL ;

abc('PQR')                                                         
1 row selected.

no output is retrieved and pqr has 40 columns in it .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

戴着白色围巾的女孩 2024-12-26 02:55:07

首先,您究竟要传递给该函数什么?您的 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

First off, exactly what are you passing to the function? Your SELECT statement shows that you are passing a lower case string 'pqr'. But in bold type, you are passing an upper case string '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.

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. 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. In SQL*Plus, you can disable roles to simulate the privileges you would have access to in a definer's rights stored procedure

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. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文