【问题标题】:opening implicit cursor with for loop用 for 循环打开隐式游标
【发布时间】:2012-11-05 00:06:12
【问题描述】:

我有一个具有以下 pl/sql 块的存储过程。此块在 for 语句中使用 select 查询,但我需要将该静态变量更改为动态查询。当我改变它有错误时。有什么方法可以在隐式游标中使用带有 FOR LOOP 的变量。

  declare
      sql_query varchar2(32767) := 'select ctlchar ';
      kpiNameQuery varchar2(600);
      isWg boolean := true;
    begin
          IF isWG then
             kpiNameQuery := 'select distinct KPI_NAME from weeklykpi where kpi_name in (select kpi_wg from auxillary.kpi_types) order by 1';

      Else
        kpiNameQuery := 'select distinct KPI_NAME from weeklykpi where kpi_name in (select kpi_wg1 from auxillary.kpi_types) order by 1';
      End IF;         

     for KPI_NAME in kpiNameQuery
      loop
          sql_query := sql_query || ' , min(case when KPI_NAME = '''||x.KPI_NAME||''' then KPI_VALUE end) as '||x.KPI_NAME;
          dbms_output.put_line(sql_query);
      end loop;
end;

【问题讨论】:

    标签: plsql oracle11g


    【解决方案1】:

    您可以使用以下光标实现类似的功能

    declare
          type t_cursor is ref cursor;
          c_cursor t_cursor;
          l_sql varchar2(512);
          l_var number;
       begin
         l_sql := 'select count(*) from emp';  -- do dynamic check before here for    
       -- correct sql
         open c_cursor for l_sql;
         loop
           fetch c_cursor 
            into l_var;           
           exit When c_cursor%notfound;
           DBMS_OUTPUT.put_line ('val '||l_var);           
         end loop;  
         close c_cursor;
      end; 
    

    【讨论】:

      【解决方案2】:

      很遗憾,没有,the doc states:

      如果动态 SQL 语句是返回多行的 SELECT 语句,则本机动态 SQL 为您提供以下选择:

      • 使用带有 BULK COLLECT INTO 子句的 EXECUTE IMMEDIATE 语句。
      • 使用 OPEN FOR、FETCH 和 CLOSE 语句。

      因此您将不得不使用 REF 游标(或 EXECUTE IMMEDIATE 并循环遍历结果)。

      顺便说一句,在您的情况下,您可以选择静态 SQL 并具有相当的性能:

      BEGIN
         FOR cc IN (SELECT DISTINCT KPI_NAME
                      FROM weeklykpi
                     WHERE kpi_name IN (SELECT CASE WHEN l_variable = 1
                                                        THEN kpi_wg
                                                    ELSE kpi_wg1
                                               END
                                          FROM auxillary.kpi_types) LOOP
                     ORDER BY 1
            -- do something
         END LOOP;
      END;
      

      您必须使用布尔型以外的其他类型,因为 SQL 不知道它。

      【讨论】:

      • 非常感谢!好吧,我最终使用了显式光标,但你告诉的技术很好。感谢您提供更多信息!
      猜你喜欢
      • 1970-01-01
      • 2013-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-03
      • 2016-02-12
      • 2022-06-27
      相关资源
      最近更新 更多