使用Java运行时SQLCMD不工作

使用Java运行时SQLCMD不工作,java,sql,sql-server-2008,sqlcmd,Java,Sql,Sql Server 2008,Sqlcmd,这是一个非常奇怪的情况,但我无法指出我做错了什么 我正在执行大量SQL脚本(主要是表创建脚本)。它们通过Java执行,使用sqlcmd。下面是我使用的sqlcmd命令 sqlcmd -m 11 -S SERVER -d DB -U USER -P PASS -r0 -i "SCRIPT.sql" 2> "ERRORS.log" 1> NULL 注意:我使用-r0和重定向来确保只有错误进入日志文件。我把所有的糖果都扔掉了 现在我用Java执行这个命令,使用getRuntime.exe

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

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

sqlcmd -m 11 -S SERVER -d DB -U USER -P PASS -r0 -i "SCRIPT.sql" 2> "ERRORS.log" 1> NULL
注意:我使用
-r0
和重定向来确保只有错误进入日志文件。我把所有的糖果都扔掉了

现在我用Java执行这个命令,使用
getRuntime.exec()
,如下所示

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执行时,脚本将运行,并且日志中没有错误、异常和任何内容但是,当签入SSM时,表不在那里

我从哪里开始调试这个问题

更新:我是个白痴

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

有关于如何解决这个问题的建议吗

更新2

我已经查看了流程的ErrorStream,它就是这样

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


看来我走过的路错了。错误日志进入我的配置文件目录,即
C:\Documents and Settings\my_username
。路径中的空间重要吗?无论如何,我都在重复引用它们

我没有发布评论的权限-这就是问题所在-但是如果你试图为数据库输入一个伪造的用户id怎么办?这是否会导致不同的执行路径?这会给你一个Java错误吗?或者数据库中存在身份验证错误?此外,def调整用户,而不是密码,并从我的经验中了解到,如果你调整密码,这是一个伟大的方式来锁定帐户

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

编辑:

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


请查看以字符串数组作为参数的exec方法:

 java.lang.Runtime.exec(String[] cmdArray)
此方法的JavaDoc说明:

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

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

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

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

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

是否尝试从进程读取输出流?@RogerLindsjö好的,因此我尝试获取错误流,结果显示错误“Sqlcmd:error:打开或操作文件2时出错>(原因:文件名、目录名或卷标语法不正确”你必须重定向流吗?处理这些流的解析应该是cmd的工作。但是,如果你完全跳过重定向并处理Java格式的流,你能让它工作吗?我不想用Java处理流。所以我决定让SQLCMD处理它。现在出现了这个问题,我点击了ErrorStream来看看它。另外,看看我的第二次更新。Matt,我正在使用JRE 1.6.0.03和sqljdbc4 JAR。还要检查我的第二次更新!哇,学习了这么多关于运行时的知识真是令人兴奋!所以我尝试将整个命令作为单个元素数组传递,比如
Runtime.getRuntime().exec(新字符串[]{strCmd});
。现在ErrorStream是空的,但是仍然没有创建表!您是否尝试传递一个包含三个元素的数组?0.命令
cmd
1.命令
cmd
的第一个参数:
/c
2.命令
cmd
的第二个参数:“sqlcmd-m…”好的,所以我尝试了。我得到了错误“访问被拒绝”在ErrorStream中。是否可以抛出此错误?嗯,请仅尝试sqlcmd部分,暂时忽略日志文件。sqlcmd似乎返回前缀为“sqlcmd:”.这很有效!我传递了
sqlcmd-m 11-S SERVER-d DB-U USER-P PASS-I“SCRIPT.sql”
而且它是有效的!但是日志记录基本上是为了我的目的=[