【问题标题】:Oracle / PLSQL - Using column results in a where clauseOracle / PLSQL - 使用列导致 where 子句
【发布时间】:2016-01-07 16:05:43
【问题描述】:

我一直在尝试做一些非常简单的事情,但仍然做不到。 我正在尝试对表进行交互并使用 where 子句中列的每一行来显示查询。

例如:

我想从 dba_users 中检索所有用户,将其传递给查询中的 where 子句,以显示每个用户的 account_status 和 profile。但我想以某种方式将结果转换为许多 html 表格。

我真的尝试了太多东西,所以我会发布一些不起作用但我认为会显示我遇到的问题的东西,

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

编辑:这是我想要实现的另一个示例:

  1. 从 V$SQL 中读取 2 个 SQL_ID

    SQL> select sql_id from v$sql where rownum

    SQL_ID

    9avfy3fv2wq2x
    0ywp98ffdz77f

  2. 使用这些返回的 ID 收集一些性能信息并在两个结果集中获取结果

-- HTML 标记

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

我得到以下结果

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

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

使用标记标签,这会转化为:

Example

提前感谢您的宝贵时间,

【问题讨论】:

  • 你必须选择一些东西 - 使用光标。
  • 运行一个简单的查询来获取必要的数据。使用应用程序代码显示它。
  • 我不能,因为我想要的是单独的结果,如果我选择进入,它会告诉我 ORA-01422: exact fetch 返回的行数超过了请求的行数。

标签: sql oracle plsql


【解决方案1】:

用光标试试这个:

 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; 

【讨论】:

  • 它给了我一个错误:PLS-00382:表达式类型错误 ORA-06550:第 9 行,第 8 列:PLS-00428:此 SELECT 语句中应有一个 INTO 子句
【解决方案2】:

您可以使用一些临时表来存储来自每个选择的数据,然后您可以进一步处理它。

另一个选项是使用您在循环中填充的TABLE TYPE OF xxx。 稍后您可以通过显示结果的第二部分了解如何使用它。

 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; 

【讨论】:

  • 非常感谢您的努力。我编辑了我的原始帖子以澄清最终结果应该是什么样子。希望对你有帮助
【解决方案3】:

你的代码离你不远了。

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;

【讨论】:

    【解决方案4】:

    我相信您正在努力实现这种结果。但是,这仅在您正在执行的动态查询获取单个结果时才有效。如果您的动态查询正在获取多个结果,您可以使用集合类型的变量来使用批量收集来存储结果,然后循环遍历列表以显示输出。

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

    【讨论】:

    • 遗憾的是,在某些情况下它确实返回不止一行,无论如何谢谢!
    猜你喜欢
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 2013-03-09
    相关资源
    最近更新 更多