oracle spool 脚本在 cmd.exe 中工作,但在从代码调用时挂起
Posted
技术标签:
【中文标题】oracle spool 脚本在 cmd.exe 中工作,但在从代码调用时挂起【英文标题】:oracle spool script works in cmd.exe, but hangs when called from code 【发布时间】: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 快捷方式并选择以管理员身份运行。
【参考方案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;
【讨论】:
以上是关于oracle spool 脚本在 cmd.exe 中工作,但在从代码调用时挂起的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Oracle APEX 中设置 SPOOL 脚本以将视图数据导出为 CSV?
Linux sh脚本用spool导出oracle数据库指定表表数据