【问题标题】:How to execute results of dbms_output.put_line如何执行 dbms_output.put_line 的结果
【发布时间】:2017-08-01 11:51:33
【问题描述】:

有一个表包含这种数据:select to_char(sysdate,'day') from dual 在一个列中。我想获得该表保留的每个查询的结果。

我的结果集应该是select to_char(sysdate,'day') from dual 查询的结果。所以在本例中是星期二

SO_SQL_BODY 是 Varchar2。

我编写了这段代码,但它只返回表格数据。

CREATE  or replace PROCEDURE a_proc
AS

 CURSOR var_cur IS

select  SO_SQL_BODY FROM SO_SUB_VARS group by SO_SQL_BODY;

var_t  var_cur%ROWTYPE;

   TYPE var_ntt IS TABLE OF var_t%TYPE;

var_names  var_ntt;
BEGIN
OPEN  var_cur;
FETCH var_cur BULK COLLECT INTO var_names;
CLOSE var_cur;

FOR indx IN 1..var_names.COUNT LOOP

   DBMS_OUTPUT.PUT_LINE(var_names(indx).SO_SQL_BODY);

END LOOP;
END a_proc;

【问题讨论】:

  • 可以分享一下表格数据吗?

标签: sql oracle stored-procedures plsql execute-immediate


【解决方案1】:
DECLARE
   res varchar2(4000);
   sql_str varchar2(1000);
BEGIN
  FOR r IN
    (select  SO_SQL_BODY FROM SO_SUB_VARS  WHERE SO_SQL_BODY IS NOT NULL
  )
  LOOP
     sql_str := r.SO_SQL_BODY;
     EXECUTE immediate sql_str INTO res;
     dbms_output.put_line(sql_str);
     dbms_output.put_line('***********************');
     dbms_output.put_line(res);
     dbms_output.put_line('***********************');
  END LOOP;
END;
/

试试这个 - 迭代到不为空的记录 - 执行它们并打印结果。假设 SO_SQL_BODY 包含一个仅投影一列的查询,则此脚本有效。此外,如果投影包含两列以上,则尝试使用一个 refcursor 和 dbms_sql 包

【讨论】:

    【解决方案2】:

    İf var_names(indx).SO_SQL_BODY 输出是可运行的 sql 文本;

    CREATE  or replace PROCEDURE a_proc
    AS
    
     CURSOR var_cur IS
    
    select  SO_SQL_BODY FROM SO_SUB_VARS group by SO_SQL_BODY;
    
    var_t  var_cur%ROWTYPE;
    
       TYPE var_ntt IS TABLE OF var_t%TYPE;
    
    var_names  var_ntt;
    BEGIN
    OPEN  var_cur;
    FETCH var_cur BULK COLLECT INTO var_names;
    CLOSE var_cur;
    
    FOR indx IN 1..var_names.COUNT LOOP
    
       DBMS_OUTPUT.PUT_LINE(var_names(indx).SO_SQL_BODY);
       EXECUTE IMMEDIATE var_names(indx).SO_SQL_BODY;
    END LOOP;
    END a_proc;
    

    【讨论】:

    • 它给出了一个错误。 ORA-06535: EXECUTE IMMEDIATE 中的语句字符串为 NULL 或 0 长度
    • 'var_names(indx).SO_SQL_BODY'这个语句是否返回一个可执行的sql文本?
    • 我不这么认为。它是一个有两列的表,列保留'select to_char(sysdate,'day') from dual'类型的数据,类型是varchar2。
    【解决方案3】:

    对于本示例,您不需要完整的光标。一个隐含的会使其更短。

    create or replace procedure a_proc is
            lReturnValue varchar2(250);
        begin
            for q in (select so_sql_body from so_sub_vars group by so_sql_body)
            loop
    
                execute immediate q.so_sql_body into lReturnValue;
                dbms_output.put_line(lReturnValue);
    
            end loop;
        end a_proc;
    

    您应该添加一个异常处理程序来处理表中存在错误 SQL 查询的情况。另请注意,执行保存在数据库表中的查询是 SQL 注入的入口点。

    【讨论】:

      猜你喜欢
      • 2012-12-05
      • 2020-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      • 2020-12-09
      • 1970-01-01
      相关资源
      最近更新 更多