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;
/

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 .

6
  • When you run the select from the cursor on its own, does it return rows? Commented Dec 1, 2011 at 8:08
  • @Hallainzil: yes it returns 40 records Commented Dec 1, 2011 at 8:11
  • why given negative reputation? Commented Dec 1, 2011 at 8:14
  • There's nothing wrong with your code that I can see, and it works on my instance. It's not something silly like case-sensitivity or something, is it? Commented Dec 1, 2011 at 8:14
  • Wait... is abc('PQR') what is actually returned from the statement? Commented Dec 1, 2011 at 8:17

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

+1 Would just add that the reason for a ` -- ` separated column list in PL\SQL completely escapes me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.