SQLLDR 手動打命令可以,通過程序不行,救命,謝謝!


大家好:
  我用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,請大家幫我看看是什么原因,(個人認為不是程序的原因,而是權限的問題,不知道對不對)先謝謝了!

19 个解决方案

#1


引用樓主 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…


是不是調用的時候加上用戶信息啊!

#2


你在服務器上手工執行正確嗎?

sqlldr userid=aa/bb control=control.ctl

本機和服務器上都沒對應的服務名?難道兩者一樣

#3


不好意思,昨天晚上出去了,我在本機發布程序沒問題的,服務器上發布程序,訪問的數據庫其實也是在別的電腦上的,並不是同一台電腦,服務器只是發布網頁,然后到別的服務器讀數據庫,2台電腦(一台自己的,一台發布網頁的服務器),程序都是一樣的,手工在cmd里發命令都是可以執行數據導入的,可是在發布網頁的服務器上調用c#程序時候查看strOutput發現cmd里命令也是發出的,可是就是沒有執行導入的操作,沒有返回“達到提交點,邏輯記錄計數49”類似語句!
大家幫幫忙,萬分感謝

#4


有人遇到過類似的問題嗎?幫下忙,謝謝

#5


引用 3 樓 ckkwing 的回復:
我在本機發布程序沒問題的,服務器上發布程序,訪問的數據庫其實也是在別的電腦上的,並不是同一台電腦,服務器只是發布網頁,然后到別的服務器讀數據庫

那你的sqllrd命令最終是在哪台機子上執行的呢?
發布網頁的服務器?數據庫服務器?還是客戶機?

#6


引用 5 樓 vc555 的回復:
引用 3 樓 ckkwing 的回復:
我在本機發布程序沒問題的,服務器上發布程序,訪問的數據庫其實也是在別的電腦上的,並不是同一台電腦,服務器只是發布網頁,然后到別的服務器讀數據庫
那你的sqllrd命令最終是在哪台機子上執行的呢?
發布網頁的服務器?數據庫服務器?還是客戶機?


sqlldr命令最終是在發布網頁的服務器執行的,通過發布網頁的服務器操作數據庫服務器

#7


為什么同樣的程序在2台電腦上(一台xp,一台2003)發布,xp可以,2003不行?

#8


發布的機器上裝的有sqlldr嗎?

#9


裝的,發布的機器上手工進cmd,打命令(和程序里的命令一模一樣)都是可以執行的

#10


在你的程序中調用的sqlldr后再加個log參數,看看日志的內容。

#11


試過了,根本不產生日志

#12


是不是環境變量問題。
那你調用sqlldr時用全路徑試試。
d:\oracle\..\bin\sqlldr userid=aa/bb control=d:\...\control.ctl

#13


我試過了,手工打cmd進去發可以的,通過程序還是不行

#14


不好意思,很急只能自己頂一下了

#15


自己再頂一下,知道的人幫幫忙,謝謝

#16


兄弟,問題解決了嗎?
我也是碰到同樣的問題了,在我筆記本上好使,但在台式機(XP),服務器都不好用,急死我了

#17


我也遇到這個問題,是否跟操作系統是win2003有關系,有沒有高手解答一下?

#18


再頂一下,希望有關高手關注一下

#19


這個問我我搞定了,給一下我的處理代碼:
其實是在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進行處理

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com