【发布时间】:2018-04-28 23:44:00
【问题描述】:
在 SQL Server 2016 的一个实例中,我有一个包含几十个参数的存储过程。例如:
CREATE PROCEDURE spName (
@par1 INT = NULL,
@par2 VARCHAR(10) = NULL,
....
....
@par98 INT = NULL,
@par99 INT = NULL,
) AS
BEGIN
....
....
END
我有一个用 C# 编写的客户端,它调用存储过程,只指定带有值的参数。例如:
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "spName";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = dbConn;
cmd.Parameters.Add(new SqlParameter("par1", "val1"));
cmd.Parameters.Add(new SqlParameter("par47", "val47"));
...
cmd.ExecuteNonQuery();
完美运行!因此,该过程被执行并且只有 2 个参数(par1 和 par47)有一个值。其他参数保持默认值(NULL)。
我会从使用 Microsoft JDBC 驱动程序 6.2 的 Java 客户端执行相同的操作。
我用List<Map<String, Object>> 指定参数,所以是一对parameterName-->parameterValue 的列表。以下方法构建PreparedStatement 对象:
private CallableStatement prepareStatement(String spName, Map<String, ?> parameters) throws SQLException {
setupConnection();
CallableStatement stmt = null;
try {
stmt = conn.prepareCall(getSpCallString(spName, parameters));
if (parameters != null) {
for (String parName : parameters.keySet())
stmt.setObject(parName, parameters.get(parName));
}
} catch (SQLException e) {
ApplicationLogging.severe("Cannot prepare callable statement", e);
throw e;
}
return stmt;
}
getSpCallString() 方法生成{ call spName ?,?, ... , ? } 类型的字符串,其中? 的数量作为传递给过程的值的参数数量,因此不是所有99 个参数。如果我有 2 个参数,它会生成字符串 { call spName ?,? }。
例如,通过传递 par15=val15 和 par47=val47 会引发以下异常:
com.microsoft.sqlserver.jdbc.SQLServerException: The index 2 is out of range.
我可以在调用命令中解决这个问题! 在 C# 中,这很容易解决,因为参数只分配了它们的名称,所以参数的数量和顺序实际上可以是一个黑盒子。
我可以在 Java 中以某种方式做到这一点吗?
【问题讨论】:
-
什么是 valorized 参数?我不熟悉这个词。
-
我的意思是我给存储过程的参数(有一个值)。其他参数不传递,所以保持默认值(NULL)。
-
你不能,除非不生成一个特定于 SQL Server 的存储过程调用,它显式地为命名参数赋值。
-
我想你的意思是你想使用可选参数?您必须使用命名参数才能使其工作,并且您必须在过程定义中分配一个默认值(可以是 NULL)。但是你怎么能不知道一个存储过程中有多少个参数呢?如果您不知道参数,也许您应该考虑不调用该过程。或者至少花一点时间来看看这个过程,这样你就知道你在做什么。
-
嗨,肖恩。我有一个存储过程,可以通过许多参数提取数据过滤。然后我有各种用户界面。它们都调用相同的存储过程,但每个都有不同的参数传递给存储过程(参数的子集)。处理客户端请求时,仅将来自调用视图的参数传递给存储过程,而不是全部。
标签: sql-server stored-procedures jdbc parameters mssql-jdbc