我有一个将对象添加到数据库并返回生成的 ID 号的存储过程。
作为引用,它的基本结构是这样的:
ALTER PROCEDURE [dbo].[myProc]
@Name nvarchar(50),
@Creator nvarchar(50),
@Text nvarchar(200),
@Lat float,
@Lon float,
@myID int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO myTable --# blah blah blah
SELECT @myID = scope_identity(); --# grab the auto-inc key from myTable
INSERT INTO anotherTable --# blah blah blah
END
我在 SQL Server Management Studio 中运行它并验证它是否正常工作。
现在我想从 Java 调用该存储过程。我写了这段代码来做到这一点:
CallableStatement cs = con.prepareCall("EXEC myProc "
+ "@Name = ?, @Creator = ?, @Text = ?, @Lat = ?, @Lon = ?, @myID = ? OUTPUT");
cs.setString(1, aString);
cs.setString(2, anotherString);
cs.setString(3, yetAnotherString);
cs.setFloat(4, aFloat);
cs.setFloat(5, anotherFloat);
cs.registerOutParameter(6, java.sql.Types.INTEGER);
cs.execute();
但是 execute()
调用抛出异常:
java.sql.SQLException: [Microsoft][ODBC SQL Server Driver][SQL Server]Error converting data type nvarchar to int.
这里出了什么问题?为什么它甚至试图将 nvarchar 转换为 int?我什至还没有尝试通过 getInt()
获取返回值(在下一行)。
我尝试过的:
- 通过字符串操作构建查询以检查问题是否可能出在输入参数中。同样的异常(exception)。至少这缩小了问题的范围。
- 将输出参数的类型更改为
Types.NVARCHAR
,以防万一。但我正在使用的 JdbcOdbcDriver 甚至不支持它。 - 弄乱调用语法(我以前没有使用过带有 Java 的 SQL Server)。总是以语法错误结束。这包括尝试使 myID 成为返回值而不是输出参数。
- 搜索谷歌。很多。以一堆无用的论坛主题和 EE“答案”告终。
现在我被难住了。真的有这么难还是我只是错过了显而易见的东西?
最佳答案
您的代码看起来没问题。唯一错误的是 SQL Server 中的“float”映射为 Java 中的 double。 MS SQL 中的“real”映射为 Java 中的 float。但这不会产生问题。
问题是有问题的 ODBC 桥。您应该为 MS SQL 使用 4 类 JDBC 驱动程序。如果您想使用 ODBC Bridge,那么您可以测试为第 6 个参数设置一个值:
cs.setInt(6, 0);
但我不知道这是否有效。该消息表示驱动程序正在为最后一个参数使用数据类型 NVARCHAR。看起来 ODBC Bridge 没有转发带有 registerOutParameter 的类型。
关于java - 如何从 Java 中的 T-SQL 存储过程获取返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4081910/