2016-11-09 18 views
0

我有一個文件列表讓說如何從PLSQL的Oracle調用的形式存在於UNIX目錄單線條的文件名列表

File 1 : a_0001, 
File 2 : b_1001, 
File 3 : c_2001 

目前在

Directory : /home/swa/IBI directory. 

我想形成預言串如下

" [a_001] [b_1001] [c_2001] " 

並使用此〜應變g用於進一步的oracle處理。

我不能在這裏給任何代碼。至於,我不知道這樣做的任何功能。

+0

歡迎SO!請編輯您的問題並添加一些附加信息:文件名列表(數據庫表?),樣本輸入和預期輸出的來源是什麼。 –

+0

請澄清一下:你的數據庫服務器*上是否有一個目錄*,並且想要獲取它的內容列表?或者你的客戶*上有一個目錄? –

+0

你問如何在plsql中聲明變量? oracle_string:='[a_001] [b_1001] [c_2001]'?或者它是否必須動態創建?嘗試在這裏問適當的問題;) – massko

回答

0

如果我沒有記錯oracle沒有函數列出目錄中的文件。爲此,您需要使用java源代碼。列出目錄中的文件,讀取輸入並創建您的變量。下面是這將在unix環境下執行命令java源:

create or replace and compile java source named "Host" as 
import java.io.*; 
public class Host { 
    public static void executeCommand(String command) { 
    //String[] commands = command.split(" "); 
    try { 
     String[] finalCommand; 
     /*if (isWindows()) { 
     finalCommand = new String[4]; 
     // Use the appropriate path for your windows version. 
     //finalCommand[0] = "C:\\winnt\\system32\\cmd.exe"; // Windows NT/2000 
     finalCommand[0] = "C:\\windows\\system32\\cmd.exe"; // Windows XP/2003 
     //finalCommand[0] = "C:\\windows\\syswow64\\cmd.exe"; // Windows 64-bit 
     finalCommand[1] = "/y"; 
     finalCommand[2] = "/c"; 
     finalCommand[3] = command; 
     } 
     else { 
     //finalCommand = new String[commands.length + 2]; 
     finalCommand = new String[commands.length]; 
     //finalCommand[0] = "/bin/bash"; 
     //finalCommand[1] = "-c"; 
     //for (int i = 2; i < commands.length; i++){ 
     // finalCommand[i] = command[i]; 
     //} 
     for (int i = 0; i < commands.length; i++){ 
      finalCommand[i] = commands[i]; 
     } 
     }*/ 

     //final Process pr = Runtime.getRuntime().exec(finalCommand); 
     final Process pr = Runtime.getRuntime().exec(command.split(" ")); 
     pr.waitFor(); 

     new Thread(new Runnable(){ 
     public void run() { 
      BufferedReader br_in = null; 
      try { 
      br_in = new BufferedReader(new InputStreamReader(pr.getInputStream())); 
      String buff = null; 
      while ((buff = br_in.readLine()) != null) { 
       System.out.println("Process out :" + buff); 
       try {Thread.sleep(10); } catch(Exception e) {} 
      } 
      br_in.close(); 
      } 
      catch (IOException ioe) { 
      System.out.println("Exception caught printing process output."); 
      ioe.printStackTrace(); 
      } 
      finally { 
      try { 
       br_in.close(); 
      } catch (Exception ex) {} 
      } 
     } 
     }).start(); 

     new Thread(new Runnable(){ 
     public void run() { 
      BufferedReader br_err = null; 
      try { 
      br_err = new BufferedReader(new InputStreamReader(pr.getErrorStream())); 
      String buff = null; 
      while ((buff = br_err.readLine()) != null) { 
       System.out.println("Process err :" + buff); 
       try {Thread.sleep(10); } catch(Exception e) {} 
      } 
      br_err.close(); 
      } 
      catch (IOException ioe) { 
      System.out.println("Exception caught printing process error."); 
      ioe.printStackTrace(); 
      } 
      finally { 
      try { 
       br_err.close(); 
      } catch (Exception ex) {} 
      } 
     } 
     }).start(); 
    } 
    catch (Exception ex) { 
     System.out.println(ex.getLocalizedMessage()); 
    } 
    } 

    public static boolean isWindows() { 
    if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1) 
     return true; 
    else 
     return false; 
    } 

}; 

PLSQL功能:

CREATE OR REPLACE PROCEDURE host_command (p_command IN VARCHAR2) 
AS LANGUAGE JAVA 
NAME 'Host.executeCommand (java.lang.String)'; 

腳本:

DECLARE 
    l_output DBMS_OUTPUT.chararr; 
    l_lines INTEGER := 1000; 
BEGIN 
    DBMS_OUTPUT.enable(1000000); 
    DBMS_JAVA.set_output(1000000); 

    host_command('printenv'); 
    --host_command('/bin/ls /home/oracle'); 

    DBMS_OUTPUT.get_lines(l_output, l_lines); 

    FOR i IN 1 .. l_lines LOOP 
    -- Do something with the line. 
    -- Data in the collection - l_output(i) 
    /* 
     l_output(i) - unix/java output 
     Parse files list here and make your variable: 
    */ 
    DBMS_OUTPUT.put_line(l_output(i)); 
    END LOOP; 
END; 
/
0

有一個C庫/ listener.ora中/庫/外部函數的方法。這可能是對XE版有幫助那裏是不是Java

注:當有上市超過32000個字符這個解決方案會導致緩衝區溢出

1)準備好你的共享C庫目錄(list.c) - 這絕對不是C語言中最安全的使用代碼目錄列表的最佳解決方案。但是你有了基本的想法。

// 
// FILE: list.c 
// 
// gcc -Wall -fPIC -c list.c 
// gcc -shared -o list.so list.o 
// mkdir -p /u01/lib 
// cp list.so /u01/lib 
// 

#include <stdio.h> 
#include <dirent.h> 
#include <sys/types.h> 

char *list_dir(const char *path) { 

    char *filelist; 
    filelist=(char *) calloc(32000,sizeof(char)); 

    struct dirent *entry; 
    DIR *dir=opendir(path); 

    if (dir==NULL) { 
    return; 
    } 

    strcat(filelist,""); 
    while ((entry = readdir(dir)) != NULL) { 
    strcat(filelist,entry->d_name); 
    strcat(filelist,"\n"); 
    } 
    strcat(filelist,"\0"); 

    closedir(dir); 

    return (filelist); 
} 

2)編輯您的LISTENER.ORA

... 
    (SID_DESC = 
     (SID_NAME = PLSExtProc) 
     (ORACLE_HOME = <PATH TO ORACLE >) 
     (ENVS="EXTPROC_DLLS=/u01/lib/list.so") 
     ^^^^^^^^^^^^^^^^^^^^ This line enables calling of external libs 
     (PROGRAM = extproc) 
    ) 
... 

3)準備數據庫對象

create or replace library c_list is '/u01/lib/list.so'; 
/

create or replace function host_list(v_directory in varchar2) return varchar2 as external 
    name "list_dir" 
    library c_list 
    language c 
    parameters (v_directory string, return string); 
/

最後與使用它:

declare 
    v_ret varchar2(32000); 
begin 
    v_ret := host_list('/u01'); 
    dbms_output.put_line(v_ret); 
end; 
/

當然你也可以修改C和字符串post-pr適合您的需求。

致以問候

P.S.您可以按如下

create or replace package sysop as 
    type file_list_rec is record(filename varchar2(1024)); 
    type file_list is table of file_list_rec; 

    function ls(v_directory varchar2) return file_list pipelined; 
end; 
/

create or replace package body sysop as 
    function ls(v_directory varchar2) return file_list pipelined is 
    rec file_list_rec; 
    v_host_list varchar2(32000) := ''; 
    begin  
    v_host_list := host_list(v_directory); 

    for file in (
     select regexp_substr(v_host_list, '[^'||chr(10)||']+', 1, level) 
     from dual 
      connect by 
      regexp_substr(v_host_list, '[^'||chr(10)||']+', 1, level) is not null) 
     loop   
     pipe row (file); 
     end loop;   
    return; 
    end ls; 
end sysop; 
/

結果轉換成表,並把它像這樣:

select * from table(sysop.ls('/u01')) order by 1; 
相關問題