【问题标题】:plsql block to get the dynamic sql query resultplsql块获取动态sql查询结果
【发布时间】:2010-11-24 06:33:05
【问题描述】:

我们创建了以下匿名块............

DECLARE
   sql_str long(32000);
   where_str long(32000);
   counter NUMBER(3):=0;
   BEGIN
   sql_str:='SELECT '||' A.bio_id ,';
   where_str:=' where '||'A.bio_id=B.bio_id AND'||' A.bio_id<>0 and rownum<25 AND (' ;
   LOOP
   counter:=counter+1;
  sql_str:=sql_str||'decode(A.wk_units'||(counter+1)||' - B.wk_units'|| (counter)||',0,NULL,A.wk_units'||(counter+1)||')';
 sql_str:=sql_str||', decode(A.wk_units'||(counter+1)||' - B.wk_units'|| (counter)||',0,NULL,B.wk_units'||(counter)||')' ;
  where_str:=where_str||' A.wk_units'||(counter+1)||'<> B.wk_units'||(counter) ;
  EXIT WHEN counter=5;
  sql_str:=sql_str||', ';
  where_str:=where_str||' or ';
  END LOOP;
  sql_str:=sql_str||' from cnt_sls_dm.fct_sales_summary A, cnt_sls_dm.fct_sales_summary B';
  sql_str:=sql_str||where_str||')';
  dbms_output.put_line(sql_str);
  EXECUTE IMMEDIATE(sql_str);
  END;

需要的结果: 我们编写了一个动态 sql 查询。 它应该得到选择查询的结果集。 但是我们在运行这个块时得到了查询本身。 而不是得到这个查询的任何结果。

让我们知道我们是否在仪式轨道上。 或者我们需要做些别的事情来得到结果。

结果是

SQL> /
SELECT  A.bio_id ,decode(A.wk_units2 - B.wk_units1,0,NULL,A.wk_units2),
decode(A.wk_units2 - B.wk_units1,0,NULL,B.wk_units1), decode(A.wk_units3 -
B.wk_units2,0,NULL,A.wk_units3), decode(A.wk_units3 -
B.wk_units2,0,NULL,B.wk_units2), decode(A.wk_units4 -
B.wk_units3,0,NULL,A.wk_units4), decode(A.wk_units4 -
B.wk_units3,0,NULL,B.wk_units3), decode(A.wk_units5 -
B.wk_units4,0,NULL,A.wk_units5), decode(A.wk_units5 -
B.wk_units4,0,NULL,B.wk_units4), decode(A.wk_units6 -
B.wk_units5,0,NULL,A.wk_units6), decode(A.wk_units6 -
B.wk_units5,0,NULL,B.wk_units5) from cnt_sls_dm.fct_sales_summary A,
cnt_sls_dm.fct_sales_summary B where A.bio_id=B.bio_id AND A.bio_id<>0 and
rownum<25 AND ( A.wk_units2<> B.wk_units1 or  A.wk_units3<> B.wk_units2 or
A.wk_units4<> B.wk_units3 or  A.wk_units5<> B.wk_units4 or  A.wk_units6<>
B.wk_units5)

PL/SQL procedure successfully completed.

【问题讨论】:

    标签: sql oracle plsql oracle10g


    【解决方案1】:

    这个:

    dbms_output.put_line(sql_str);
    

    ...是打印输出的内容,这是正确的行为。 DECLARE 部分给我的印象是您正在尝试运行匿名函数,对吗?

    我从未使用过 EXECUTE IMMEDIATELY - 只有以下:

    FUNCTION MY_FUNCTION()
    RETURN SYS_REFCURSOR
    
    L_CURSOR SYS_REFCURSOR;
    L_QUERY  VARCHAR2(5000) DEFAULT 'SELECT ...';
    
    BEGIN
    
      OPEN L_CURSOR FOR L_QUERY;
      RETURN L_CURSOR;
    
    END;
    

    如果要在动态 SQL 中包含绑定变量:

    FUNCTION MY_FUNCTION()
    RETURN SYS_REFCURSOR
    
    L_CURSOR SYS_REFCURSOR;
    L_QUERY  VARCHAR2(5000) DEFAULT 'SELECT ...';
    
    BEGIN
    
      OPEN L_CURSOR FOR L_QUERY
       USING bind_var1;
      RETURN L_CURSOR;
    
    END;
    

    【讨论】:

    • EXECUTE IMMEDIATE 用于运行动态 DML 语句。您的答案对于获取动态查询的结果集是正确的。
    • 我们有一个 FCT_SALES_SUMMARY 表,其中包含 105 个列,其中包含第 1 周(wk_units1)到第 105 周(wk_units105)的数据。并且每周我们添加一个新的列,其中包含与当前周相关的数据删除最旧的周列(本周 wk104 将是 wk 105)以保持列数为 105 所以我们需要进行一个查询,它可以选择此表中的数据如下所示 select a.bio_id,a.wk_unit1...a.wk_unit105, a.wk_unit1-b.wk_unit2, from fct_sales_summary a,fct_sales_summary_new b 如果存在差异,则应显示 d 值,否则显示 null 所以我们发现2 自动化
    【解决方案2】:

    如果您在块中将其作为硬编码语句运行,它将因PLS-00428 而失败,因为您没有选择变量。

    EXECUTE IMMEDIATE 不会失败,因为它在 SQL 空间中运行。但是如果你想得到结果集,你仍然需要将它传递给一个局部变量。

    SQL> declare
      2      n number;
      3  begin
      4      execute immediate 'select sum(sal) from emp';
      5      dbms_output.put_line('sum of salaries = '||n);
      6  end;
      7  /
    sum of salaries =
    
    PL/SQL procedure successfully completed.
    
    SQL> declare
      2      n number;
      3  begin
      4      execute immediate 'select sum(sal) from emp' into n;
      5      dbms_output.put_line('sum of salaries = '||n);
      6  end;
      7  /
    sum of salaries = 48525
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    您选择哪种类型的变量取决于您要如何处理检索到的数据,以及结果集是单行还是多行。

    顺便说一句,您为此查询使用动态 SQL 有什么特殊原因吗?

    【讨论】:

      【解决方案3】:

      对我来说,欧文想要达到什么目标尚不清楚:

      @Irveen,为什么不是一个有 105 条记录的表?每周您都会删除一条记录并添加另一条记录。您将永远不会更改您的查询。

      另一种解决方案是移动数据,因此您将第 2 列的数据放入 1、3 放入 2、4 放入 3、...、103 放入 102。您永远不必添加列和删除列.

      【讨论】:

        猜你喜欢
        • 2015-06-23
        • 1970-01-01
        • 2012-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-26
        • 2021-08-22
        • 1970-01-01
        相关资源
        最近更新 更多