1

列の数が常に固定されるとは限らない動的なクロス集計クエリを作成する必要があるため、大文字と小文字を区別してハードコードすることはできません。私はグーグルで検索しましたが、SQL Serverで同じことをすることについてのブログを見つけましたが、Oracleで同じことをすることについてのそのような記事のブログがあるかどうか疑問に思っていました. SQL Server で作業していません。Fol は私の問題に関する情報です。

私が書いたハードコードされたクロス集計クエリ

SELECT

LU_CITY.CITY_NAME as "City",
count(CASE WHEN emp.emp_category='Admin'  THEN emp.emp_id END) As "Admins",
count(CASE WHEN emp.emp_category='Executive'  THEN emp.emp_id END) As "Executive",
count(CASE WHEN emp.emp_category='Staff'  THEN emp.emp_id END) As "Staff",
count(emp.emp_id) As "Total"

FROM emp, LU_CITY

where

   LU_CITY.CITY_ID = EMP.CITY_ID(+)
group by
LU_CITY.CITY_NAME, LU_CITY.CITY_ID
order by
LU_CITY.CITY_ID

テーブル

        emp (emp_id, emp_name, city_id, emp_category)
        lu_city(city_id,city_name)

クエリ結果

          ------------------------------------------
          City | Admins | Executive | Staff . . . .
          ------------------------------------------ 
          A    |    1   |   2       | 3
          B    |    0   |   0       | 4
          .    |    .   |   .       | . 
          .
          .

emp_category は、ユーザーが必要に応じて追加できます。クエリは、そのようなカテゴリをすべて動的に生成する必要があります。

この点に関するガイダンスをいただければ幸いです。

前もって感謝します

4

1 に答える 1

2

動的カーソルを使用して、VARCHAR2 変数からコンパイルされた動的 SQL を実行できます。

DECLARE 
       w_sql             VARCHAR2 (4000);
       cursor_           INTEGER;
       v_f1    NUMBER (6);
       v_f2    NUMBER (2);
       v_some_value_2_filter_4    NUMBER (2);
       rc      INTEGER         DEFAULT 0;
BEGIN
        -- join as many tables as you need and construct your where clause
        w_sql :='SELECT f1, f2 from TABLE1 t1, TABLE2 t2, ... WHERE t1.f1 =' || v_some_value_2_filter_4 ; 

       -- Open your cursor
       cursor_ := DBMS_SQL.open_cursor;
       DBMS_SQL.parse (cursor_, w_sql, 1);
       DBMS_SQL.define_column (cursor_, 1, v_f1);
       DBMS_SQL.define_column (cursor_, 2, v_f2);
      -- execute your SQL
       rc := DBMS_SQL.EXECUTE (cursor_);

       WHILE DBMS_SQL.fetch_rows (cursor_) > 0
       LOOP
          -- get values from record columns
          DBMS_SQL.COLUMN_VALUE (cursor_, 1, v_f1);
          DBMS_SQL.COLUMN_VALUE (cursor_, 2, v_f2);

          -- do what you need with v_f1 and v_f2 variables

       END LOOP;

END;

または、値を確認するか、クエリを実行して挿入/更新/削除するだけでよい場合は、 execute immediatelyを使用すると実装が簡単になります。

    w_sql :='select f1 from table where f1 = :variable';
    execute immediate w_sql into v_f1 using 'valor1'

動的カーソルの詳細: http://docs.oracle.com/cd/B10500_01/appdev.920/a96590/adg09dyn.htm

于 2012-09-04T07:37:42.640 に答える