Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Tiku.

Asked: July 27, 2005 - 4:43 pm UTC

Last updated: July 28, 2005 - 9:06 am UTC

Version: 9.2.0

Viewed 1000+ times

You Asked

I have a select statement as follows.

select GRANTEE,table_name,PRIVILEGE
from user_tab_privs
where table_name='TEMP'
and grantee='DEVUSR'
group by GRANTEE,TABLE_NAME,PRIVILEGE;

It returns me data in following format
GRANTEE TABLE_NAME PRIVILEGE
---------------------------- ------------------------------ ---------
DEVUSR TEMP DELETE
DEVUSR TEMP INSERT
DEVUSR TEMP UPDATE
DEVUSR TEMP SELECT
TMPUSR TEMP SELECT

How can I get the output in following format? I'm trying with different approches, inline view, analytic sql but no success so far.

GRANTEE TABLE_NAME DEL_PRIV INS_PRIV SEL_PRIV UPD_PRIV
DEVUSR TEMP Y Y Y Y
TMPUSR TEMP N


Thanks


and Tom said...

call your query "q"


select grantee, table_name,
max(decode(privilege,'DELETE','Y')) del,
......
max(decode(privilege,'UPDATE','Y')) upd
from (Q)
group by grantee, table_name;


very standard "pivot" query.

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

An alternate way - when number of different privs could be anything

Pawan Negi, July 28, 2005 - 5:50 am UTC

Hi Tom,

  Just thought about it. Your solution works perfectly when we know in advance there are going to be only 4 different privileges - insert, select, update, delete. Here is an alternate solution which would work for any number of privileges that might change dynamically. This solution is in fact inspired by one of yours.

package tmp as
type rc is ref cursor;
procedure p (p_curs in out rc);
end tmp;
/

PACKAGE BODY TMP as
procedure p(p_curs in out rc)
IS
CURSOR curs IS SELECT DISTINCT privilege FROM user_tab_privs WHERE table_name = 'TEMP';
varcur curs%ROWTYPE;
l_stmt VARCHAR2(1000) := 'select grantee, table_name ';
BEGIN
OPEN curs;
LOOP
    FETCH curs INTO varcur;
    EXIT WHEN curs%NOTFOUND;
        l_stmt:=l_stmt||',max(decode(privilege,'''||varcur.privilege||''',''Y'',''N'')) "'||varcur.privilege||'_PRIV"';
END LOOP;
CLOSE curs;
l_stmt:=l_stmt||' from user_tab_privs where table_name = ''TEMP'' group by grantee, table_name';
OPEN p_curs FOR l_stmt;
END;
end tmp;
/

SQL> variable x refcursor;
SQL> exec tmp.p(:x);

PL/SQL procedure successfully completed.

SQL> print :x

and this gives the desired output. 

Tom Kyte
July 28, 2005 - 9:06 am UTC

If you have "Expert One on One Oracle", I have a stored procedure in there that does this "generically", you tell it the query, and the column to pivot on - and it writes the query based on the data and returns the ref cursor - yes.