我有一个文件列表比如
File 1 : a_0001,
File 2 : b_1001,
File 3 : c_2001
存在于
Directory : /home/swa/IBI directory.
我想形成一个oracle字符串如下
" [a_001] [b_1001] [c_2001] "
,并使用该字符串进行进一步的oracle处理。
我不能在这里给出任何代码。因为,我不知道有什么函数能做到这一点
从Oracle 11开始,您可以使用外部表预处理列出目录中的文件,然后遍历从外部表读取的文件。
像这样:http://www.oracle-developer.net/display.php?id=513
如果我没记错的话,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;
/
有一个C库/侦听器。ora/库/外部函数方法。在没有java
的XE版本中可能会很有帮助。注意:当目录列表超过32000个字符时,此解决方案会导致缓冲区溢出
1)准备你的共享C库(in 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," ");
closedir(dir);
return (filelist);
}
2)编辑你的听众。奥拉
...
(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和字符串的后处理来满足你的需要。
问好注:您可以将结果转换为表,如下所示
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;