我正在尝试使用几个必需参数和几个可选参数调用存储过程。在我出现之前,程序的开头是这样编写的:
USE [MYDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_GetStudents]
(
@SortOrder varchar(50),
@SortColumn varchar(150),
@SortLetter varchar(10),
@Status varchar(250),
@PageIndex int,
@PageSize int,
@User_ID int,
@Reference_No varchar(50) = NULL,
@First_Name varchar(50) = NULL,
@Middle_Name varchar(50) = NULL,
@Last_Name varchar(50) = NULL
)
As
BEGIN
-- other stuff here
一切似乎都很好。然后我在最后添加了另一个参数:
USE [MYDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_GetStudents]
(
@SortOrder varchar(50),
@SortColumn varchar(150),
@SortLetter varchar(10),
@Status varchar(250),
@PageIndex int,
@PageSize int,
@User_ID int,
@Reference_No varchar(50) = NULL,
@First_Name varchar(50) = NULL,
@Middle_Name varchar(50) = NULL,
@Last_Name varchar(50) = NULL,
@ContextID int = NULL
)
As
BEGIN
-- other stuff here
现在它已经坏了。当我使用ADO.NET通过设置带参数的命令对象来调用存储过程时,它会抛出异常,因为我没有设置@ContextID
参数。
知道为什么吗?我想如果我将它设置为默认值NULL
,那么它实际上是完全可选的。
更新:这里是SqlCommand的设置方式,我最好能代表它:
SqlCommand cmd = new SqlCommand("SP_GetStudents");
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter();
param.ParameterName = "@SortOrder";
param.Value = sortOrder;
param.Direction = ParameterDirection.Input;
SqlParameter param2 = new SqlParameter();
param2.ParameterName = "@SortColumn";
param2.Value = sortColumn;
param2.Direction = ParameterDirection.Input;
cmd.Parameters.Add(param);
cmd.Parameters.Add(param2);
cmd.Parameters.Add(new SqlParameter("@SortLetter", sortLetter));
cmd.Parameters.Add(new SqlParameter("@Status", status));
cmd.Parameters.Add(new SqlParameter("@PageIndex", pageIndex));
cmd.Parameters.Add(new SqlParameter("@PageSize", pageSize));
// here, the code splits a search expression into multiple parameters, looping over a switch statement like this:
foreach (string token in tokens)
{
switch(token)
{
case "Reference_No":
cmd.Parameters.Add(new SqlParameter("@Reference_No", (object)value ?? DBNull.Value));
break;
case "First_Name":
cmd.Parameters.Add(new SqlParameter("@First_Name", (object)value ?? DBNull.Value));
break;
case "Last_Name":
cmd.Parameters.Add(new SqlParameter("@Last_Name", (object)value ?? DBNull.Value));
break;
case "Middle_Name":
cmd.Parameters.Add(new SqlParameter("@Middle_Name", (object)value ?? DBNull.Value));
break;
case "Generation":
cmd.Parameters.Add(new SqlParameter("@Generation", (object)value ?? DBNull.Value));
break;
case "ContextID":
cmd.Parameters.Add(new SqlParameter("@ContextID", (object)value ?? DBNull.Value));
break;
}
}
cmd.Parameters.AddWithValue("@User_ID", userID);
// fires off cmd through a DAL
这是例外(类型System.Data.SqlClient.SqlException
):
参数化查询'(@ Reference_No varchar(50), @First_Name varchar(5'需要参数'@ContextID',这是未提供的。
我发现此消息有点奇怪,因为格式化似乎已经失效。无论如何,在引擎盖下,命令通过SqlDataAdapter
执行,该DataSet
用于填充Fill
。在{{1}}方法执行期间抛出异常。
答案 0 :(得分:0)
在这个http://msdn.microsoft.com/en-us/library/ms187926.aspx链接上提到以下行..
除非定义参数的默认值或将值设置为等于另一个参数,否则在调用过程时,必须由用户提供每个声明的参数的值。如果过程包含表值参数,并且调用中缺少参数,则传入一个空表。
所以基于此我可以说,如果你把“默认”键工作,你的问题就会得到解决。
同样在同一页面上提到有关默认的信息,详情如下。
默认 参数的默认值。如果为参数定义了默认值,则可以在不指定该参数的值的情况下执行该过程。默认值必须是常量,或者可以为NULL。常量值可以采用通配符的形式,从而可以在将参数传递给过程时使用LIKE关键字。见下面的例C.
默认值仅记录在sys.parameters.default列中 用于CLR程序。对于Transact-SQL,该列将为NULL 程序参数。
谢谢, Jigar