You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Microsoft SQL Server 2019 (RTM-CU25) (KB5033688) - 15.0.4355.3 (X64)
Jan 30 2024 17:02:22
Copyright (C) 2019 Microsoft Corporation
Developer Edition (64-bit) on Windows Server 2019 Standard 10.0 <X64> (Build 17763: )
Client Operating System
Linux
JAVA/JVM version
Java 21.0.1
Table schema
N/A
Problem description
Since 12.6.0, stored procedure calls using the four-part syntax (i.e. including a linked server name) are broken, at least when using output parameters and being executed using the CALL JDBC escape syntax. I have not tested other permutations, such as the EXEC syntax and no return parameters.
Here is a short script to reproduce the issue:
packagemssql.repro;
importcom.microsoft.sqlserver.jdbc.SQLServerDataSource;
importjava.sql.JDBCType;
importjava.sql.SQLException;
publicclassMsSqlRepro {
privatestaticfinalStringserver = ""; // the server to connect toprivatestaticfinalStringlinkedServer = "LOCAL_L"; // the linked server pointing back to the same serverprivatestaticfinalStringprocDefinition = """ create or alter procedure dbo.TestAdd(@Num1 int, @Num2 int, @Result int output) as begin set @Result = @Num1 + @Num2; end; """;
publicstaticvoidmain(String[] args) throwsSQLException {
System.setProperty("sun.security.jgss.native", "true");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
vards = newSQLServerDataSource();
ds.setServerName(server);
ds.setDatabaseName("tempdb");
ds.setTrustServerCertificate(true);
ds.setIntegratedSecurity(true);
ds.setAuthenticationScheme("JavaKerberos");
ds.setUseDefaultGSSCredential(true);
try (varconn = ds.getConnection()) {
try (varstmt = conn.createStatement()) {
stmt.execute(procDefinition);
}
try (varstmt = conn.prepareCall("{call %s.tempdb.dbo.TestAdd(?, ?, ?)}".formatted(linkedServer))) {
stmt.setInt(1, 1);
stmt.setInt(2, 2);
stmt.registerOutParameter(3, JDBCType.INTEGER);
stmt.execute();
System.out.println(stmt.getInt(3));
}
}
}
}
Expected behavior
The above code snippet prints "3", as it does if used with driver version 12.4.x and earlier, or when used without the linked-server call syntax.
Actual behavior
An exception is thrown within the driver when stmt.getInt(3) is called.
Error message/stack trace
Mar 07, 2024 4:50:15 PM com.microsoft.sqlserver.jdbc.SQLServerCallableStatement skipOutParameters
INFO: sp_executesql SQL: EXEC LOCAL_L.tempdb.dbo.TestAdd @P0 , @P1 , @P2 OUT Unexpected outParamIndex: 0; adjustment: 0
Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: The TDS protocol stream is not valid.
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:4266)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:4255)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.throwInvalidTDS(SQLServerConnection.java:4238)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.skipOutParameters(SQLServerCallableStatement.java:431)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getOutParameter(SQLServerCallableStatement.java:226)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getterGetParam(SQLServerCallableStatement.java:517)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getValue(SQLServerCallableStatement.java:522)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getInt(SQLServerCallableStatement.java:563)
at mssql.repro.MsSqlRepro.main(MsSqlRepro.java:37)
Any other details that can be helpful
From what I know of the changes in the 12.6.x series, I believe the issue here may be that the code which tries to detect whether a statement is using exec or call syntax already (and therefore for which the additional sp_executesql wrapping layer can be skipped) does not correctly recognise the four-part syntax being used here.
Driver version
12.6.1 (issue introduced in 12.6.0)
SQL Server version
Client Operating System
Linux
JAVA/JVM version
Java 21.0.1
Table schema
N/A
Problem description
Since 12.6.0, stored procedure calls using the four-part syntax (i.e. including a linked server name) are broken, at least when using output parameters and being executed using the CALL JDBC escape syntax. I have not tested other permutations, such as the EXEC syntax and no return parameters.
Here is a short script to reproduce the issue:
Expected behavior
The above code snippet prints "3", as it does if used with driver version 12.4.x and earlier, or when used without the linked-server call syntax.
Actual behavior
An exception is thrown within the driver when
stmt.getInt(3)
is called.Error message/stack trace
Any other details that can be helpful
From what I know of the changes in the 12.6.x series, I believe the issue here may be that the code which tries to detect whether a statement is using exec or call syntax already (and therefore for which the additional sp_executesql wrapping layer can be skipped) does not correctly recognise the four-part syntax being used here.
JDBC trace logs
The text was updated successfully, but these errors were encountered: