Java 使用命名的JDBC参数调用存储过程会引发异常
因此,当我试图运行我的线束,连接。但是,当程序试图调用我的存储过程“iCurrentLocations01”时。它在我的日志中返回错误消息 “2016-01-27 13:11:17错误SQLConnection:97-参数运行日期为 未为存储过程iCurrentLocations01定义。“ 有人能解释一下我做错了什么吗?程序btw从LDAP目录获取信息并将其插入本地数据库 编辑-这是我的存储过程:Java 使用命名的JDBC参数调用存储过程会引发异常,java,sql-server,jdbc,Java,Sql Server,Jdbc,因此,当我试图运行我的线束,连接。但是,当程序试图调用我的存储过程“iCurrentLocations01”时。它在我的日志中返回错误消息 “2016-01-27 13:11:17错误SQLConnection:97-参数运行日期为 未为存储过程iCurrentLocations01定义。“ 有人能解释一下我做错了什么吗?程序btw从LDAP目录获取信息并将其插入本地数据库 编辑-这是我的存储过程: package com.brookfieldres.operations; import ja
package com.brookfieldres.operations;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Properties;
import java.util.ResourceBundle;
import org.apache.log4j.Logger;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
public class SQLConnection {
private static Connection acon = null;
private static CallableStatement _cs = null;
private static String _dbServer = null;
private static String _dbUsername = null;
private static String _dbPassword = null;
private static String _dbName = null;
private static String _dbInstance = null;
private static String _dbWindowsAuthentication = null;
private static final Logger aLogger = Logger.getLogger(SQLConnection.class.getName());
// static ResourceBundle resource = ResourceBundle.getBundle("Resource");
public SQLConnection() {
_dbServer = "localhost";
_dbUsername = "NewLocationTestUser";
_dbPassword = "TestPass123";
_dbName = "NewLocationDB";
_dbInstance = "APPSQL";
_dbWindowsAuthentication = "FALSE";
}
public Connection getConnection() {
SQLServerDataSource ds = new SQLServerDataSource();
Properties properties = new Properties();
try {
String dbURL = "jdbc:sqlserver://" + _dbServer;
if(!_dbInstance.equalsIgnoreCase(""))
{
dbURL += "\\" + _dbInstance;
}
if(_dbWindowsAuthentication.equalsIgnoreCase("TRUE"))
{
dbURL += ";integratedSecurity=true";
}
else
{
properties.put("user", _dbUsername);
properties.put("password", _dbPassword);
}
dbURL += ";";
properties.put("database", _dbName);
acon = DriverManager.getConnection(dbURL, properties);
System.out.println("1");
} catch (Exception e) {
aLogger.error(e.getMessage());
}
finally {
ds = null;
}
aLogger.info("The sql connection has been established.");
return acon;
}
public int insertLocations(Timestamp RunDate, String rlpCompanyid, String rlpLocationid, String rlpOpenDate){
int returnVal = 0;
try{
_cs = getConnection().prepareCall("{call iCurrentLocations01(?, ?, ?, ?)}");
_cs.setTimestamp("RunDate", RunDate);
_cs.setString("CompanyId", rlpCompanyid);
_cs.setString("LocationId", rlpLocationid);
_cs.setString("rlpOpenDate", rlpOpenDate );
returnVal = _cs.executeUpdate();
System.out.println("2");
}catch (SQLException e){
aLogger.error(e.getMessage());
}finally {
if (_cs != null){
try{
_cs.close();
}catch(SQLException e) {
aLogger.error(e.getMessage());
}
}
}
return returnVal;
}
使用基于索引的集合方法
USE [NewLocationDB]
GO
/****** Object: StoredProcedure [dbo].[iCurrentLocations01] Script Date: 01/27/2016 1:27:10 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[iCurrentLocations01]
@RunDate datetime,
@CompanyId varchar,
@LocationId varchar,
@rlpOpenDate varchar
AS
DECLARE @RetVal int
SET @RetVal = 0
INSERT CurrentLocations (RunDate, CompanyId, LocationId, rlpOpenDate )
VALUES (@RunDate, @CompanyId, @LocationId, @rlpOpenDate)
SET @RetVal = @@ERROR
Return @RetVal
GO
这可能不是您所希望的,但它确实可以按名称将参数传递给存储过程,从而允许我们
- 在命令文本中按任意顺序指定参数,然后
- 忽略具有默认值的参数
创建过程[dbo]。[my_sp]
@p1 nvarchar(10)=你好,
@p2 nvarchar(10)=N'world'
作为
开始
不计数;
选择@p1+N'、“+@p2+N”!”作为回应;
结束
JDBC调用
try(CallableStatement s=conn.prepareCall(“{CALL my_sp(@p2=?)}”)){
s、 设置管柱(1,“Gord”);
try(ResultSet rs=s.executeQuery()){
rs.next();
System.out.println(rs.getString(“response”);
}
}
返回
你好,戈德!
(使用Microsoft JDBC Driver 4.1 for SQL Server进行了测试。)认为消息是明确的好答案在评论中!但是,我不想使用它,因为将来如果我更改列的顺序。如果您想使用命名参数,则不应使用
?
,?
是位置参数,只能通过索引进行设置。您可能需要检查驱动程序是否支持命名参数;在这种情况下,您可能需要使用SQL Server特定的语法,而不是调用
转义(但我不确定)。
_cs = getConnection().prepareCall("{call iCurrentLocations01(?, ?, ?, ?)}");
_cs.setTimestamp(1, RunDate);
_cs.setString(2, rlpCompanyid);
_cs.setString(3, rlpLocationid);
_cs.setString(4, rlpOpenDate );
returnVal = _cs.executeUpdate();
System.out.println("2");