2012-09-04 46 views
1

我需要創建一個動態的交叉表查詢,其中列不會總是固定在數字中,所以無法使用大小寫硬編碼。我已經搜索了一下,它確實發現了一個關於在SQL Server中做同樣的事情的博客,但我想知道是否有任何這樣的文章博客在Oracle中做同樣的事情。沒有在SQL Server中工作。 Fol是關於我的問題的信息。在Oracle中的動態交叉表查詢

硬編碼的橫標籤查詢我寫

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可以由用戶被添加爲每他們的需要。查詢應該是這樣的,它應該動態地生成所有這些類別。

任何有關這方面的指導將不勝感激。

由於提前

+2

鏈接到博客也會啓發我們;-) – Vikdor

+0

我編輯了問題更詳細的問題陳述圖片 – learner

+0

@LandonAshes這些結果將如何使用?如果你只是需要這些信息進行其他處理,那麼像常規動態SQL(如kothvandir的解決方案)應該可以工作。但是,如果您在adhoc SQL語句中確實需要可變數量的列,則需要使用「方法4動態SQL」。在這個網站的數據盒式磁帶解決方案可能會有幫助:http://www.oracle-developer.net/display.php?id=422 –

回答

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 immediate,更容易實現,如果你只需要檢查的值或執行和插入/更新/刪除查詢

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