SQLLDR 手动打命令可以,通过程序不行,救命,谢谢!

ckkwing 2009-03-17 04:49:18
大家好:
我用sqlloader导数据到Oracle,配置文件什么的都是好的,手动进入cmd,打了下面这个命令:
“sqlldr userid=aa/bb control=control.ctl”都是导入成功,可是我用c#写以下code:
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
// string strOutput = null;
try
{
p.Start();
p.StandardInput.WriteLine(@"cd\");
p.StandardInput.WriteLine(@"sqlldr userid=aa/bb control=control.ctl");
p.StandardInput.WriteLine("exit");
// strOutput = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Close();
UpdateEventArgs e = new UpdateEventArgs(true);
OnUpdateSuccess(e);
}
catch
{
p.Close();
throw;
}
程序执行没问题,不报错,可是我看strOutput时发现,sqlldr没能导入数据,“达到提交点,逻辑记录计数49”这些语句没有出现,还有补充一点,一样的程序在我本机上是好的,可是放在服务器上就不行了,本机是xp,服务器是windows2003,请大家帮我看看是什么原因,(个人认为不是程序的原因,而是权限的问题,不知道对不对)先谢谢了!
...全文
338 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
lxh023 2009-08-31
  • 打赏
  • 举报
回复
这个问我我搞定了,给一下我的处理代码:
其实是在ctl文件多指定了log文件目录-->>贴出我的代码
bool SqlLoader(string full_file, string filename, string strTableName,string path,string userid,string pwd,string db)
{
//建立CTL文件
string strCtlFile = filename + ".ctl";
string strLogFile = filename + ".log";
string strBadFile = filename + ".bad";

//string Path = Server.MapPath("UpFiles/");

if (File.Exists(path + strCtlFile))
File.Delete(path + strCtlFile);
if (File.Exists(path + strLogFile)) //创建日志文件
{
File.Delete(path + strLogFile);
File.Create(path + strLogFile);
}
if (File.Exists(path + strBadFile)) //创建异常文件
{
File.Delete(path + strBadFile);
File.Create(path + strBadFile);
}

//生成sqlldr 命令所需要的控制文件

System.IO.FileStream sf = File.Create(path + strCtlFile);
StringBuilder strCtlField = new StringBuilder();
strCtlField.Append("load data \r\n");
strCtlField.Append("infile '" + path + filename + ".txt" + "'\r\n");
strCtlField.Append("append into table " + strTableName + "\r\n");
strCtlField.Append(" fields terminated by whitespace \r\n");
strCtlField.Append("(acc_nbr char)");


byte[] bytes = Encoding.Default.GetBytes(strCtlField.ToString());

//写入数据

sf.Write(bytes, 0, bytes.Length);
sf.Close();



//运行sqlldr,导入数据
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo();
p.StartInfo.FileName = "sqlldr";
p.StartInfo.Arguments = string.Format("{0}/{1}@{2} '{3}' '{4}'",userid,pwd,db, path + strCtlFile, path + strLogFile); //*******关键在这里,多指定了log文件的路径
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.Start();

StreamReader sr = p.StandardOutput;
string info, result = "";
int info_num = 0;
while ((info = sr.ReadLine()) != null && !sr.EndOfStream) //必须有输出,防止文件过大p.WaitForExit();死掉
{
result += info;
if (info!="" )
info_num++;
}
//Response.Write("<script>alert('" + result + "');</script>");




p.WaitForExit();
if (File.Exists(path + strBadFile))
{
throw new Exception("文件:" + full_file + "数据不符合规范!");
return false;
}


//if (!p.HasExited)
//{
// Response.Write("<script>alert('由主程序强行终止程序的运行');</script>");
// p.Kill();
//}
//else
//{
// Response.Write("<script>alert('" + string.Format("由外部程序正常退出!,程序开始时间:{0},结束时间:{1},返回值:{2}", p.StartTime, p.ExitTime, p.ExitCode) + "');</script>");
//}


if (info_num > 2 && File.Exists(path+strLogFile))
return true;
else
return false;
}

--注明:我作了个web应用程序,把文件先上传到服务器,然后调用Oracle数据服务器的sqlldr进行处理
lxh023 2009-08-29
  • 打赏
  • 举报
回复
再顶一下,希望有关高手关注一下
lxh023 2009-08-29
  • 打赏
  • 举报
回复
我也遇到这个问题,是否跟操作系统是win2003有关系,有没有高手解答一下?
dave_xiang 2009-07-24
  • 打赏
  • 举报
回复
兄弟,问题解决了吗?
我也是碰到同样的问题了,在我笔记本上好使,但在台式机(XP),服务器都不好用,急死我了
ckkwing 2009-03-18
  • 打赏
  • 举报
回复
我试过了,手工打cmd进去发可以的,通过程序还是不行
vc555 2009-03-18
  • 打赏
  • 举报
回复
是不是环境变量问题。
那你调用sqlldr时用全路径试试。
d:\oracle\..\bin\sqlldr userid=aa/bb control=d:\...\control.ctl
ckkwing 2009-03-18
  • 打赏
  • 举报
回复
试过了,根本不产生日志
vc555 2009-03-18
  • 打赏
  • 举报
回复
在你的程序中调用的sqlldr后再加个log参数,看看日志的内容。
ckkwing 2009-03-18
  • 打赏
  • 举报
回复
装的,发布的机器上手工进cmd,打命令(和程序里的命令一模一样)都是可以执行的
vc555 2009-03-18
  • 打赏
  • 举报
回复
发布的机器上装的有sqlldr吗?
ckkwing 2009-03-18
  • 打赏
  • 举报
回复
为什么同样的程序在2台电脑上(一台xp,一台2003)发布,xp可以,2003不行?
ckkwing 2009-03-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 vc555 的回复:]
引用 3 楼 ckkwing 的回复:
我在本机发布程序没问题的,服务器上发布程序,访问的数据库其实也是在别的电脑上的,并不是同一台电脑,服务器只是发布网页,然后到别的服务器读数据库
那你的sqllrd命令最终是在哪台机子上执行的呢?
发布网页的服务器?数据库服务器?还是客户机?
[/Quote]

sqlldr命令最终是在发布网页的服务器执行的,通过发布网页的服务器操作数据库服务器
vc555 2009-03-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ckkwing 的回复:]
我在本机发布程序没问题的,服务器上发布程序,访问的数据库其实也是在别的电脑上的,并不是同一台电脑,服务器只是发布网页,然后到别的服务器读数据库[/Quote]
那你的sqllrd命令最终是在哪台机子上执行的呢?
发布网页的服务器?数据库服务器?还是客户机?
ckkwing 2009-03-18
  • 打赏
  • 举报
回复
有人遇到过类似的问题吗?帮下忙,谢谢
ckkwing 2009-03-18
  • 打赏
  • 举报
回复
不好意思,昨天晚上出去了,我在本机发布程序没问题的,服务器上发布程序,访问的数据库其实也是在别的电脑上的,并不是同一台电脑,服务器只是发布网页,然后到别的服务器读数据库,2台电脑(一台自己的,一台发布网页的服务器),程序都是一样的,手工在cmd里发命令都是可以执行数据导入的,可是在发布网页的服务器上调用c#程序时候查看strOutput发现cmd里命令也是发出的,可是就是没有执行导入的操作,没有返回“达到提交点,逻辑记录计数49”类似语句!
大家帮帮忙,万分感谢
ckkwing 2009-03-18
  • 打赏
  • 举报
回复
自己再顶一下,知道的人帮帮忙,谢谢
ckkwing 2009-03-18
  • 打赏
  • 举报
回复
不好意思,很急只能自己顶一下了
jdsnhan 2009-03-17
  • 打赏
  • 举报
回复
你在服务器上手工执行正确吗?

sqlldr userid=aa/bb control=control.ctl

本机和服务器上都没对应的服务名?难道两者一样
oraclelogan 2009-03-17
  • 打赏
  • 举报
回复
[Quote=引用楼主 ckkwing 的帖子:]
大家好:
我用sqlloader导数据到Oracle,配置文件什么的都是好的,手动进入cmd,打了下面这个命令:
“sqlldr userid=aa/bb control=control.ctl”都是导入成功,可是我用c#写以下code:
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.Redirect…
[/Quote]

是不是调用的时候加上用户信息啊!
在java代码中调用执行shell脚本,sqlldr导数与使用sqlplus在shell调用执行存储过程。 linux环境中有2个dba的用户:oracle、erm 还有1个web用户:erm 在linux环境中,这三个用户都可以直接在任意目录下执行该shell脚本,可是在java代码中调用shell脚本时,报了如下4个错误: 1、sqlldr: command not found 2、sqlplus: command not found 3、0750: You may need to set ORACLE_HOME to your Oracle software directory 4、Message 2100 not found; No message file for product=RDBMS, facility=ULMessage 2100 not found; No message file for product=RDBMS, facility=UL$ 检查了dba用户和web用户下关于oracle的所有环境变量发现没有问题 (/home/oracle/.profile 与 /home/erm/.profile 环境变量文件为隐藏文件需使用 ls -a 命令查看) 在网上查了一遍以后有如下几种处理办法: 1、没有oracle_home目录的执行权限,无法进入到bin目录,使用chmod 755 $oracle_home更改目录权限;使用chmod 755 $oracle_home/lib更改目录权限;对目录$oracle_home/rdbms/mesg目录赋予相应权限;当需要给非oracle用户配置使用sqlldr时,不单需要配置环境变量,还需要把相关目录的访问权限赋予该用户。【采用此法测试以后还是出现上面的错误】 2、用sh直接执行shell和在java直接执行shell是有区别的,要在shell文件内增加oracle的环境变量即. /home/oracle/.bash_profile 这句话,否则在执行sqlldr会报如下异常: Message 2100 not found; No message file for product=RDBMS...... facility=UL 【采用此法测试以后继续报错,但是这个方法有引导作用,继续往下看】 因为我在linux环境下执行shell脚本时sqlldr命令sqlplus命令是正常执行的,没有任何问题,但是在java代码中调用脚本时却报错,所有排除了其他原因,只可能是环境变量的问题, 于是我把oracle的所有环境变量直接复制到shell脚本文件中,在java中调用了一下,然后所有问题迎刃而解! 具体代码参看文件内容

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧