这是一个非常奇怪的情况,但我不能指出我做错了什么。
我正在执行一大堆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
。路径中的空间是否重要?我总是双引他们!
答案 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()并将内容打印到文件或控制台。