Ton*_*son 101 .net sql-server stored-procedures
我在访问SQL Server中的存储过程时遇到错误
Server Error in '/' Application.
Procedure or function 'ColumnSeek' expects parameter '@template', which was not supplied.
Run Code Online (Sandbox Code Playgroud)
当我通过.net的数据连接调用带有参数的存储过程时(System.data.SqlClient)
,即使我提供了参数,也会发生这种情况.这是我的代码.
SqlConnection sqlConn = new SqlConnection(connPath);
sqlConn.Open();
//METADATA RETRIEVAL
string sqlCommString = "QCApp.dbo.ColumnSeek";
SqlCommand metaDataComm = new SqlCommand(sqlCommString, sqlConn);
metaDataComm.CommandType = CommandType.StoredProcedure;
SqlParameter sp = metaDataComm.Parameters.Add("@template",SqlDbType.VarChar,50);
sp.Value = Template;
SqlDataReader metadr = metaDataComm.ExecuteReader();
Run Code Online (Sandbox Code Playgroud)
我的存储过程是:
USE [QCApp]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ColumnSeek]
@template varchar(50)
AS
EXEC('SELECT Column_Name, Data_Type
FROM [QCApp].[INFORMATION_SCHEMA].[COLUMNS]
WHERE TABLE_NAME = ' + @template);
Run Code Online (Sandbox Code Playgroud)
我想知道我在这里做错了什么.
编辑:事实证明,模板是null因为我从通过URL传递的参数获取其值,我搞砸了url param传递(我正在使用@
for而不是&
)
Bri*_*ian 284
除了这里的其他答案,如果你忘了放:
cmd.CommandType = CommandType.StoredProcedure;
Run Code Online (Sandbox Code Playgroud)
然后你也会得到这个错误.
Xca*_*bur 27
这个问题确实通常是由于将参数值设置为null而引起的,如上所述的HLGEM.我想我会详细说明这个问题的一些解决方案,我发现这对这个问题的新用户有益.
我更喜欢的解决方案是将存储过程参数默认为NULL(或任何你想要的值),这是上面的sangram提到的,但可能会错过,因为答案非常详细.有点像:
CREATE PROCEDURE GetEmployeeDetails
@DateOfBirth DATETIME = NULL,
@Surname VARCHAR(20),
@GenderCode INT = NULL,
AS
Run Code Online (Sandbox Code Playgroud)
这意味着如果参数最终在某些条件下在代码中设置为null,则.NET将不会设置参数,然后存储过程将使用它已定义的默认值.另一个解决方案,如果你真的想在代码中解决问题,那就是使用一个为你解决问题的扩展方法,例如:
public static SqlParameter AddParameter<T>(this SqlParameterCollection parameters, string parameterName, T value) where T : class
{
return value == null ? parameters.AddWithValue(parameterName, DBNull.Value) : parameters.AddWithValue(parameterName, value);
}
Run Code Online (Sandbox Code Playgroud)
Matt Hamilton 在这里有一篇很好的文章,列出了处理这个领域时更好的扩展方法.
And*_*sen 10
我有一个问题,当我向整数参数提供0时,我会得到错误.并发现:
cmd.Parameters.AddWithValue("@Status", 0);
Run Code Online (Sandbox Code Playgroud)
有效,但这不是:
cmd.Parameters.Add(new SqlParameter("@Status", 0));
Run Code Online (Sandbox Code Playgroud)
小智 5
我在调用存储过程时遇到了类似的问题
CREATE PROCEDURE UserPreference_Search
@UserPreferencesId int,
@SpecialOfferMails char(1),
@NewsLetters char(1),
@UserLoginId int,
@Currency varchar(50)
AS
DECLARE @QueryString nvarchar(4000)
SET @QueryString = 'SELECT UserPreferencesId,SpecialOfferMails,NewsLetters,UserLoginId,Currency FROM UserPreference'
IF(@UserPreferencesId IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE UserPreferencesId = @DummyUserPreferencesId';
END
IF(@SpecialOfferMails IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE SpecialOfferMails = @DummySpecialOfferMails';
END
IF(@NewsLetters IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE NewsLetters = @DummyNewsLetters';
END
IF(@UserLoginId IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE UserLoginId = @DummyUserLoginId';
END
IF(@Currency IS NOT NULL)
BEGIN
SET @QueryString = @QueryString + ' WHERE Currency = @DummyCurrency';
END
EXECUTE SP_EXECUTESQL @QueryString
,N'@DummyUserPreferencesId int, @DummySpecialOfferMails char(1), @DummyNewsLetters char(1), @DummyUserLoginId int, @DummyCurrency varchar(50)'
,@DummyUserPreferencesId=@UserPreferencesId
,@DummySpecialOfferMails=@SpecialOfferMails
,@DummyNewsLetters=@NewsLetters
,@DummyUserLoginId=@UserLoginId
,@DummyCurrency=@Currency;
Run Code Online (Sandbox Code Playgroud)
哪个动态构建我在上面调用的搜索查询:
public DataSet Search(int? AccessRightId, int? RoleId, int? ModuleId, char? CanAdd, char? CanEdit, char? CanDelete, DateTime? CreatedDatetime, DateTime? LastAccessDatetime, char? Deleted)
{
dbManager.ConnectionString = ConfigurationManager.ConnectionStrings["MSSQL"].ToString();
DataSet ds = new DataSet();
try
{
dbManager.Open();
dbManager.CreateParameters(9);
dbManager.AddParameters(0, "@AccessRightId", AccessRightId, ParameterDirection.Input);
dbManager.AddParameters(1, "@RoleId", RoleId, ParameterDirection.Input);
dbManager.AddParameters(2, "@ModuleId", ModuleId, ParameterDirection.Input);
dbManager.AddParameters(3, "@CanAdd", CanAdd, ParameterDirection.Input);
dbManager.AddParameters(4, "@CanEdit", CanEdit, ParameterDirection.Input);
dbManager.AddParameters(5, "@CanDelete", CanDelete, ParameterDirection.Input);
dbManager.AddParameters(6, "@CreatedDatetime", CreatedDatetime, ParameterDirection.Input);
dbManager.AddParameters(7, "@LastAccessDatetime", LastAccessDatetime, ParameterDirection.Input);
dbManager.AddParameters(8, "@Deleted", Deleted, ParameterDirection.Input);
ds = dbManager.ExecuteDataSet(CommandType.StoredProcedure, "AccessRight_Search");
return ds;
}
catch (Exception ex)
{
}
finally
{
dbManager.Dispose();
}
return ds;
}
Run Code Online (Sandbox Code Playgroud)
然后经过大量的挠头,我将存储过程修改为:
ALTER PROCEDURE [dbo].[AccessRight_Search]
@AccessRightId int=null,
@RoleId int=null,
@ModuleId int=null,
@CanAdd char(1)=null,
@CanEdit char(1)=null,
@CanDelete char(1)=null,
@CreatedDatetime datetime=null,
@LastAccessDatetime datetime=null,
@Deleted char(1)=null
AS
DECLARE @QueryString nvarchar(4000)
DECLARE @HasWhere bit
SET @HasWhere=0
SET @QueryString = 'SELECT a.AccessRightId, a.RoleId,a.ModuleId, a.CanAdd, a.CanEdit, a.CanDelete, a.CreatedDatetime, a.LastAccessDatetime, a.Deleted, b.RoleName, c.ModuleName FROM AccessRight a, Role b, Module c WHERE a.RoleId = b.RoleId AND a.ModuleId = c.ModuleId'
SET @HasWhere=1;
IF(@AccessRightId IS NOT NULL)
BEGIN
IF(@HasWhere=0)
BEGIN
SET @QueryString = @QueryString + ' WHERE a.AccessRightId = @DummyAccessRightId';
SET @HasWhere=1;
END
ELSE SET @QueryString = @QueryString + ' AND a.AccessRightId = @DummyAccessRightId';
END
IF(@RoleId IS NOT NULL)
BEGIN
IF(@HasWhere=0)
BEGIN
SET @QueryString = @QueryString + ' WHERE a.RoleId = @DummyRoleId';
SET @HasWhere=1;
END
ELSE SET @QueryString = @QueryString + ' AND a.RoleId = @DummyRoleId';
END
IF(@ModuleId IS NOT NULL)
BEGIN
IF(@HasWhere=0)
BEGIN
SET @QueryString = @QueryString + ' WHERE a.ModuleId = @DummyModuleId';
SET @HasWhere=1;
END
ELSE SET @QueryString = @QueryString + ' AND a.ModuleId = @DummyModuleId';
END
IF(@CanAdd IS NOT NULL)
BEGIN
IF(@HasWhere=0)
BEGIN
SET @QueryString = @QueryString + ' WHERE a.CanAdd = @DummyCanAdd';
SET @HasWhere=1;
END
ELSE SET @QueryString = @QueryString + ' AND a.CanAdd = @DummyCanAdd';
END
IF(@CanEdit IS NOT NULL)
BEGIN
IF(@HasWhere=0)
BEGIN
SET @QueryString = @QueryString + ' WHERE a.CanEdit = @DummyCanEdit';
SET @HasWhere=1;
END
ELSE SET @QueryString = @QueryString + ' AND a.CanEdit = @DummyCanEdit';
END
IF(@CanDelete IS NOT NULL)
BEGIN
IF(@HasWhere=0)
BEGIN
SET @QueryString = @QueryString + ' WHERE a.CanDelete = @DummyCanDelete';
SET @HasWhere=1;
END
ELSE SET @QueryString = @QueryString + ' AND a.CanDelete = @DummyCanDelete';
END
IF(@CreatedDatetime IS NOT NULL)
BEGIN
IF(@HasWhere=0)
BEGIN
SET @QueryString = @QueryString + ' WHERE a.CreatedDatetime = @DummyCreatedDatetime';
SET @HasWhere=1;
END
ELSE SET @QueryString = @QueryString + ' AND a.CreatedDatetime = @DummyCreatedDatetime';
END
IF(@LastAccessDatetime IS NOT NULL)
BEGIN
IF(@HasWhere=0)
BEGIN
SET @QueryString = @QueryString + ' WHERE a.LastAccessDatetime = @DummyLastAccessDatetime';
SET @HasWhere=1;
END
ELSE SET @QueryString = @QueryString + ' AND a.LastAccessDatetime = @DummyLastAccessDatetime';
END
IF(@Deleted IS NOT NULL)
BEGIN
IF(@HasWhere=0)
BEGIN
SET @QueryString = @QueryString + ' WHERE a.Deleted = @DummyDeleted';
SET @HasWhere=1;
END
ELSE SET @QueryString = @QueryString + ' AND a.Deleted = @DummyDeleted';
END
PRINT @QueryString
EXECUTE SP_EXECUTESQL @QueryString
,N'@DummyAccessRightId int, @DummyRoleId int, @DummyModuleId int, @DummyCanAdd char(1), @DummyCanEdit char(1), @DummyCanDelete char(1), @DummyCreatedDatetime datetime, @DummyLastAccessDatetime datetime, @DummyDeleted char(1)'
,@DummyAccessRightId=@AccessRightId
,@DummyRoleId=@RoleId
,@DummyModuleId=@ModuleId
,@DummyCanAdd=@CanAdd
,@DummyCanEdit=@CanEdit
,@DummyCanDelete=@CanDelete
,@DummyCreatedDatetime=@CreatedDatetime
,@DummyLastAccessDatetime=@LastAccessDatetime
,@DummyDeleted=@Deleted;
Run Code Online (Sandbox Code Playgroud)
这里我将存储过程的输入参数初始化为 null 如下
@AccessRightId int=null,
@RoleId int=null,
@ModuleId int=null,
@CanAdd char(1)=null,
@CanEdit char(1)=null,
@CanDelete char(1)=null,
@CreatedDatetime datetime=null,
@LastAccessDatetime datetime=null,
@Deleted char(1)=null
Run Code Online (Sandbox Code Playgroud)
这对我有用。
我希望这对陷入类似陷阱的人有所帮助。
归档时间: |
|
查看次数: |
150061 次 |
最近记录: |