【问题标题】:oracle spool script works in cmd.exe, but hangs when called from codeoracle spool 脚本在 cmd.exe 中工作,但在从代码调用时挂起
【发布时间】:2021-04-13 08:09:12
【问题描述】:

我正在尝试使用 Oracle 的SQLcl 以编程方式创建 Oracle 数据转储文件。脚本如下:

SET SQLFORMAT XML

SPOOL 'ABC.XML'
SELECT * FROM ABC;
SPOOL OFF

SPOOL 'XYZ.XML'
SELECT * FROM XYZ;
SPOOL OFF

//MORE TABLES BELOW

命令如下:

exit | "path\to\sqlcl\folder\bin\sql.exe" username/password@connection_string @"path\to\data\dump\script\datadumpscript.sql"

通过在CMD(windows 10)中执行命令,它工作得很好。

代码执行逻辑来自this thread,转换为vb.net:

Private Shared Sub ExecuteCommand(ByVal command As String)
    Dim exitCode As Integer
    Dim processInfo As ProcessStartInfo
    Dim process As Process
    processInfo = New ProcessStartInfo("cmd.exe", "/c """ & command & """")
    processInfo.CreateNoWindow = True
    processInfo.UseShellExecute = False
    processInfo.RedirectStandardError = True
    processInfo.RedirectStandardOutput = True
    process = Process.Start(processInfo)
    process.WaitForExit()
    Dim output As String = process.StandardOutput.ReadToEnd()
    Dim [error] As String = process.StandardError.ReadToEnd()
    exitCode = process.ExitCode
    System.Diagnostics.Debug.WriteLine("output>>" & (If(String.IsNullOrEmpty(output), "(none)", output)))
    System.Diagnostics.Debug.WriteLine("error>>" & (If(String.IsNullOrEmpty([error]), "(none)", [error])))
    System.Diagnostics.Debug.WriteLine("ExitCode: " & exitCode.ToString(), "ExecuteCommand")
    process.Close()
End Sub

当从代码调用时,通过传入上面的命令,程序确实会转到“process.WaitForExit()”并阻塞,但只有 spool 脚本中的第一个文件被创建,大小为 0,文件被锁定通过 JAVA 二进制文件,之后没有任何反应。导出过程似乎没有运行。

感谢任何建议。谢谢。

【问题讨论】:

  • 您可以尝试您链接的线程中提到的异步日志记录选项吗?或尝试WriteLine(processInfo.Arguments) 以确保引用正常...
  • 您是管理员吗? VS 不会默认为管理员权限。如果您在 VS 中运行,则必须右键单击 VS 快捷方式并选择以管理员身份运行。

标签: java c# sql oracle plsql


【解决方案1】:

调整参数后,我发现当设置processInfo.UseShellExecute = True 修复了无法运行的问题。但是,即使使用processInfo.CreateNoWindow = True,也会显示控制台窗口。

我正在寻找一种方法来隐藏控制台窗口,但如果我不能,它仍然可以接受。

【讨论】:

    【解决方案2】:

    创建一个使用 UTL_FILE 实用程序将数据从表转储到文件的存储过程/匿名 PL/SQL 块将是另一种选择。下面的脚本是从表的一列中提取数据的基本脚本,但是可以扩展到多于一列或所有列。

    DECLARE
      fhandle  utl_file.file_type;
    
    BEGIN 
    
    // File1
     BEGIN
      fhandle := utl_file.fopen(
                    '/user/home'     -- Folder location or an Oracle directory
                   , 'filename1.XML' -- File name
                   , 'w' -- writemode Mode 
                      );
     
       FOR V1 IN (Select colA from TableA)
       LOOP 
        utl_file.put_line(fhandle, v1.COLA);
       END LOOP;
       utl_file.fclose(fhandle);
     exception
      when others then
        dbms_output.put_line('ERROR: ' || SQLCODE 
                          || ' - ' || SQLERRM);
        raise;
     end;
    
    // File 2
    BEGIN
    
      fhandle := utl_file.fopen(
                    '/user/home'     -- Folder location or an Oracle directory
                   , 'filename2.XML' -- File name
                   , 'w' -- Write Mode 
                      );
     
       FOR V1 IN (Select colA from TableA)
       LOOP 
        utl_file.put_line(fhandle,v1.COLA);
       END LOOP;
       utl_file.fclose(fhandle);
     exception
      when others then
        dbms_output.put_line('ERROR: ' || SQLCODE 
                          || ' - ' || SQLERRM);
        raise;
     end;
    
    END;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-23
      • 2011-11-18
      • 1970-01-01
      • 1970-01-01
      • 2013-10-29
      • 1970-01-01
      相关资源
      最近更新 更多