1

次のpl/sqlブロックを持つストアドプロシージャがあります。このブロックはforステートメントでselectqueryを使用していましたが、その静的変数を動的クエリに変更する必要があります。私が変更したので、エラーがあります。暗黙カーソルでFORLOOPで変数を使用する方法はありますか?

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

2 に答える 2

1

残念ながら、ドキュメントには次のように記載されています。

動的SQLステートメントが複数の行を返すSELECTステートメントである場合、ネイティブ動的SQLは次の選択肢を提供します。

  • BULKCOLLECTINTO句を指定してEXECUTEIMMEDIATEステートメントを使用します。
  • 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には不明なため、ブール値以外のタイプを使用する必要があります。

于 2012-11-16T10:08:34.327 に答える
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; 
于 2012-11-16T10:10:01.713 に答える