使用Java运行时SQLCMD无法正常工作

时间:2011-12-07 10:25:49

标签: java sql sql-server-2008 sqlcmd

这是一个非常奇怪的情况,但我不能指出我做错了什么。

我正在执行一大堆SQL脚本(主要是表创建脚本)。它们使用sqlcmd通过Java执行。这是我使用的sqlcmd命令。

sqlcmd -m 11 -S SERVER -d DB -U USER -P PASS -r0 -i "SCRIPT.sql" 2> "ERRORS.log" 1> NULL

注意:我使用-r0并重定向以确保只有错误进入日志文件。我扔掉了所有的STDOUT。

现在我使用getRuntime.exec()在Java中执行此命令,就像这样。

Runtime.getRuntime().gc();
strCmd = "cmd /c sqlcmd -m 11 -S SERVER -d DB -U USER -P PASS -r0 -i \"SCRIPT.sql\" 2> \"ERRORS.log\" 1> NULL"
Process proc = Runtime.getRuntime().exec(strCmd);
proc.waitFor();

注意:我使用cmd /c,因此命令在自己的shell中运行并正常退出。此外,这有助于立即读取错误日志以查找错误。

问题!

在命令提示符下手动运行时,此命令可以正常工作(即表格按预期创建)。但是,如图所示通过Java执行时,脚本会运行,并且日志中没有错误,没有异常,也没有任何异常。 但是 ,在签入SSMS时,表格不存在!

我甚至在哪里开始调试此问题?

更新:我是个好人

getRuntime().exec方法的返回值为1.它应为0,表示正常执行。

有关如何解决此问题的任何指示?

更新2

我查看过程'ErrorStream,这就是它的内容。

  

Sqlcmd:错误:打开或操作文件2时发生错误>   (原因:文件名,目录名或卷标语法是   不正确的)。

看起来我传递的路径是错误的。错误日志会进入我的个人资料目录,即C:\Documents and Settings\my_username。路径中的空间是否重要?我总是双引他们!

3 个答案:

答案 0 :(得分:3)

使用字符串数组作为参数查看exec方法:

 java.lang.Runtime.exec(String[] cmdArray)

此方法的JavaDoc说:

  

在单独的进程中执行指定的命令和参数。

因此,数组中的第一项是命令,所有参数都附加到数组中,例如:克,

Runtime.getRuntime().exec(new String[] {"cmd", "/c", "sqlcmd ... "});

在查看您的评论和exec(String)的实现之后,似乎是exec方法将管道运算符>识别为cmd的参数,因为{{1}使用空格作为分隔符将命令字符串拆分为数组。

答案 1 :(得分:1)

我没有发表评论的权限 - 这就是这个 - 但是如果你尝试为数据库设置一个虚假的用户ID呢?这会导致不同的执行路径吗?这会给你一个Java错误吗?或者数据库中有Auth错误?此外,def调整用户,而不是密码,并从我的经验中了解到,如果你调整密码,这是一个锁定帐户的好方法!

另一件事 - 这可能是在黑暗中拍摄的 - 但你使用的JRE和驱动程序是什么?我相信JRE 1.6.0.29和sqljdbc4 JAR存在已知问题。我有更多关于此的详细信息,但是一旦我开始工作,我将不得不发布链接。

编辑:

我知道已经确定JRE / sqljdbc组合不是你的问题,但是如果大家搜索并找到它,这里是我上面提到的链接:

Driver.getConnection hangs using SQLServer driver and Java 1.6.0_29

答案 2 :(得分:0)

首先启用log / view命令输出(因为exec()返回1),这将指出问题的可能原因。 使用proc.getInputStream()并将内容打印到文件或控制台。