简体   繁体   中英

Oracle / PLSQL - Using column results in a where clause

I've been trying to do something very simple but still can't. I am trying to interate over a table and use each row of a column in a where clause to display a query.

For example:

I want to retrieve all users from dba_users pass it to a where clause in a query to show for example account_status and profile for every user. But I want to do it in a way so I can turn the result into many html tables.

I've tried too many things really, so I will post something that doesn't work but which I think will show the problem I am having,

BEGIN
 FOR i IN (SELECT username from dba_users order by 1)
 LOOP
 EXECUTE IMMEDIATE 'select account_status from dba_users where username like ''||i.username||''';
 END LOOP;
 END;
 /

EDIT: Here's is another example of what I want to achieve:

  1. Read 2 SQL_IDs from V$SQL

    SQL> select sql_id from v$sql where rownum < 3;

    SQL_ID

    9avfy3fv2wq2x
    0ywp98ffdz77f

  2. Use those returned IDs to gather some performance info and get the results in two result sets

-- HTML Markup

set markup HTML ON HEAD " -  
" -  
BODY "" -  
TABLE "border='1' align='center' summary='Script output'" -  
SPOOL ON ENTMAP ON PREFORMAT OFF  

select sql_id, loads_total from dba_hist_sqlstat where sql_id like '9avfy3fv2wq2x';  
select sql_id, loads_total from dba_hist_sqlstat where sql_id like '0ywp98ffdz77f';  

And I get the following results

SQL_ID        LOADS_TOTAL  
------------- -----------  
9avfy3fv2wq2x          21  

SQL_ID        LOADS_TOTAL  
------------- -----------  
0ywp98ffdz77f          12  

Using the markup tag, this translates into:

Example

Thanks in advance for your time,

od

Try this using a cursor:

 DECLARE
    CURSOR USERS IS
      SELECT username FROM dba_users ;

 BEGIN

    FOR user in USER
    LOOP
       SELECT account_status FROM dba_users WHERE username = user;
    END LOOP;

 END; 

You can use some temporary table to store your data from each select and then you can process it further.

The other option is using TABLE TYPE OF xxx that you populate in your loop. You can see how to use it later by the second part that displays results.

 DECLARE
    CURSOR USERS IS
      SELECT username FROM dba_users ;

    TYPE resultType IS TABLE OF NVARCHAR2(80) ;
    result resulttype := resulttype();

    indx NUMBER(10) :=0;
 BEGIN

  -- we insert data from some selects
  FOR user in USERs
    LOOP
        result.extend();
        indx := indx + 1 ;
       SELECT account_status into result(indx) FROM dba_users WHERE username = user.username;

    END LOOP;


  -- and now we will display content 
    FOR i IN result.FIRST .. result.LAST
   LOOP
       dbms_output.put_line(result(i));
  END LOOP;

 END; 

You are not far away with your code.

declare
    v_account_status dba_users.account_status%type;
BEGIN
 FOR cur_users IN (SELECT username from dba_users order by 1)
 LOOP
   SELECT account_status INTO v_account_status -- you need to save somewhere 
                                               -- your value of account_status
          FROM dba_users 
          WHERE username LIKE cur_users.username; -- cur_users is the 
                                                  -- current row of dba_users
    -- do something with v_account_status, like
    -- htp.prn(cur_users.username || ' has account status ' || v_account_status);
 END LOOP;
END;

I believe you trying to acheive this kind of result. However this will work only when dynamic query that you are executing is fetching a single result. If your dynamic query is fetching multiple result you can use variable of collection type to store the result using a bulk collect and then loop through the list to display the output.

    DECLARE
       v_sql         VARCHAR2 (4000);
       v_user_name   VARCHAR2 (400);
    BEGIN
       FOR i IN (SELECT   username
             FROM     dba_users
             WHERE    ROWNUM < 5
             ORDER BY 1) LOOP
          v_sql :=
            'select account_status from dba_users where username= '''
         || i.username
         || '''';

          EXECUTE IMMEDIATE v_sql
          INTO              v_user_name;

          DBMS_OUTPUT.put_line ('v_Sql:' || v_sql || ' v_user: ' || v_user_name);
       END LOOP;
    END;
    /

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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