不能调用在SQL Server
问题描述:
我使用的是官方的SQL Server JDBC驱动程序通过JDBC CREATE SCHEMA不能调用在SQL Server
try (Connection c = new com.microsoft.sqlserver.jdbc.SQLServerDriver().connect(u, p)) {
try (PreparedStatement s1 = c.prepareStatement("create schema x");
PreparedStatement s2 = c.prepareStatement("drop schema x")) {
System.out.println(s1.execute());
System.out.println(s2.execute());
}
}
但我发现了这个错误:
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near the keyword 'schema'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:258)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1547)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:528)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:461)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7151)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2689)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:224)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:204)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:445)
Obviuosly,该声明是正确的,他们的工作与静态语句:
try (Statement s1 = c.createStatement();
Statement s2 = c.createStatement()) {
System.out.println(s1.execute("create schema x"));
System.out.println(s2.execute("drop schema x"));
}
这是故意的还是JDBC驱动程序中的错误?
答
这似乎是版本6.2.0中的一种回归。它曾经在版本6.1.0中工作。我报道这个问题微软:https://github.com/Microsoft/mssql-jdbc/issues/370
的CREATE VIEW
声明也受到了影响:
// Works on both versions 6.2.0 and 6.1.0
try (Statement s1 = c.createStatement();
Statement s2 = c.createStatement()) {
System.out.println(s1.execute("create view x as select 1 a"));
System.out.println(s2.execute("drop view x"));
}
// Works only on version 6.1.0
try (PreparedStatement s1 = c.prepareStatement("create view x as select 1 a");
PreparedStatement s2 = c.prepareStatement("drop view x")) {
System.out.println(s1.execute());
System.out.println(s2.execute());
}
(我对堆栈溢出这里记录这一点,因为几个工具运行DDL,包括jOOQ,休眠, MyBatis,Flyway等可能会受到影响)
不是我的DV,好像是一个合理的QA。我很好奇为什么它失败了,你能分析SQL并准确地查看发送到SQL Server的内容吗? – DavidG
@DavidG:不太熟悉SQL Server工具。我在日志目录的跟踪文件中没有看到任何消息。通过JDBC驱动程序进行调试并不会在语句字符串本身显示任何异常。当然,我不太了解发送到服务器的协议字节...... –
在SQL Server Management Studio的“工具”菜单中,SQL Server Profiler。它让你看到哪些SQL命令正在发送。在这种情况下,如果驱动程序阻碍,可能不会显示任何内容,但异常消息似乎表明它来自SQL引擎。当然,我认为没有太多的好处,以创建模式和意见准备声明:) – DavidG