2017-02-01 29 views
1

我正在寫一個函數在字典視圖ALL_VIEWS中搜索文本。感興趣的列名爲TEXT,屬於LONG(!)數據類型,這會產生一個主要問題:我無法查詢視圖文本模式。如果沒有在服務器上執行的程序代碼的幫助,我將不得不提取所有視圖記錄並過濾客戶端上的感興趣的記錄。出於性能原因,這個解決方案是不行的。查詢與LONG列的表

更好的選擇是調用匿名PL/SQL塊對ALL_VIEWS執行查詢,過濾所有感興趣的視圖並將結果集返回給客戶端。有幾種可能性,如何做到這一點:

  1. 創建臨時表,並返回一個指針迭代它
  2. 創建收集的數據類型,並綁定它作爲返回值
  3. 轉儲過濾記錄到DBMS_OUTPUT,並檢查它在後續JDBC調用中

一個重要的限制是我不允許創建任何數據庫對象。同樣在第一種情況下,必須創建臨時表許可。

對於第二種情況下我嘗試以下:

String sql = "declare\n"+ 
      " l_search varchar2(1000) := 'union';\n"+ 
      " l_char varchar2(32767);\n"+ 
      " TYPE strtbl IS TABLE OF varchar2(1000) INDEX BY BINARY_INTEGER \n"+ 
      " l_st strtbl; \n"+ 
      " i integer; \n"+ 
      "begin\n"+ 
      " i := 1;"+ 
      " for rec in (select * from all_views where rownum < 10)\n"+ 
      " loop\n"+ 
      " l_char := rec.text;\n"+ 
      " if (instr(l_char, l_search) > 0) then\n"+ 
      "  l_st(i) := 'Match: ' || rec.owner || '.' || rec.view_name;\n"+ 
      "  i := i+1;\n"+ 
      " end if;\n"+ 
      " end loop;\n"+ 
      " ? := l_st;\n"+ 
      "end;"; 
    final CallableStatement cs = conn.prepareCall(sql); 
    cs.registerOutParameter(1, OracleTypes.ARRAY); 
    cs.execute(); 
    // cs.getObject(1); // cast to array, etc. 

然而,JDBC拒絕輸出參數結合的步驟;這是我卡住的地方。

最後,即使第三種解決方案是可行的,但它超出我的接受閾值是醜陋的。

+0

也許''從dual'選擇DBMS_METADATA.GET_DDL('VIEW',rec.view_name)更適合你。結果是'CLOB',比'LONG'有更好的支持 –

+0

我無法使用DBMS_METADATA在多個視圖中進行搜索。 (從技術上講,我可以,但不是性能明智的)。 –

回答

1

OracleCallableStatement上有一個API: registerIndexTableOutParameter 可用於將OUT參數定義爲PLSQL關聯數組。然後有一個getPlsqlIndexTable方法來檢索過程完成執行後的值。在你的情況下,返回的對象應該是一個String []。