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;
}
所以当我尝试运行我的安全带时,连接就建立了。但是,当程序尝试调用我的存储过程“iCurrentLocations01”时。它在我的日志中返回错误消息
" 2016-01-27 13:11:17 ERROR SQLConnection:97 - Parameter RunDate was not defined for stored procedure iCurrentLocations01."
有人可以解释一下我在这里做错了什么吗?顺便说一句,该程序正在从 LDAP 目录获取信息并将其插入本地数据库。
编辑 - 这是我的存储过程:
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
最佳答案
这可能并不完全是您所希望的,但它确实可以按名称将参数传递给存储过程,从而使我们能够
- 在命令文本中以任意顺序指定参数,并且
- 省略具有默认值的参数。
对于存储过程
CREATE PROCEDURE [dbo].[my_sp]
@p1 nvarchar(10) = N'Hello',
@p2 nvarchar(10) = N'world'
AS
BEGIN
SET NOCOUNT ON;
SELECT @p1 + N', ' + @p2 + N'!' AS response;
END
JDBC 调用
try (CallableStatement s = conn.prepareCall("{CALL my_sp (@p2=?)}")) {
s.setString(1, "Gord");
try (ResultSet rs = s.executeQuery()) {
rs.next();
System.out.println(rs.getString("response"));
}
}
返回
Hello, Gord!
(使用 Microsoft JDBC Driver 4.1 for SQL Server 进行测试。)
关于java - 使用命名 JDBC 参数调用存储过程会引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61264151/