将null参数发送到存储过程

时间:2014-07-11 12:46:06

标签: c# asp.net sql stored-procedures

我有Subject课程。它的成员是id_subjectint)和subjectNamestring

我创建一个列表

List<Subject> listSubject = new List<Subject>();

并将其发送到此存储过程:

 public bool AddNewNews(News news, List<Subject> subject)
 {
        SqlParameter[] parameters = new SqlParameter[]
        {
           new SqlParameter ("@title",news.Title),
           new SqlParameter ("@text",news.Text),
           new SqlParameter ("@year",news.Year),    
           new SqlParameter ("@month",news.Month) ,    
           new SqlParameter ("@day",news.Day) ,   
           new SqlParameter ("@id_writer",news.Id_writer)  ,
           new SqlParameter ("@id_subject1",subject[0]!=null? subject[0].Id_subject:null),
           new SqlParameter ("@id_subject2",subject[1]!=null? subject[1].Id_subject:null) ,
           new SqlParameter ("@id_subject3",subject[2]!=null? subject[2].Id_subject:null), 
           new SqlParameter ("@id_subject4",subject[3]!=null? subject[3].Id_subject:null),
           new SqlParameter ("@id_subject5",subject[4]!=null? subject[4].Id_subject:null)
    };

    return SqlDBHelper.ExecuteNonQuery("AddNewNews", CommandType.StoredProcedure, parameters);
}

第一:如果不是真的短暂

我将它们转换为对象并发送到存储过程

BEGIN TRANSACTION;

   DECLARE @last_id_news int

   BEGIN TRY
      insert into news (title, text, year, month, day, id_writer)
      values(@title, @text, @year, @month, @day, @id_writer)

      set @last_id_news = SCOPE_IDENTITY()

      if(@id_subject1 <> null)
      begin
           insert into news_subject (id_news, id_subject) 
           values (@last_id_news, @id_subject1)
      end

      if(@id_subject2 <> null)
      begin
         insert into news_subject (id_news, id_subject) 
         values (@last_id_news, @id_subject2)
      end

      if(@id_subject3 <> null)
      begin
         insert into news_subject (id_news, id_subject) 
         values (@last_id_news, @id_subject3)
      end

if(@id_subject4<>null)
begin
    insert into news_subject (id_news,id_subject) values (@last_id_news,@id_subject4)
end
if(@id_subject5<>null)
begin
    insert into news_subject (id_news,id_subject) values (@last_id_news,@id_subject5)
end

    COMMIT TRANSACTION;
END TRY
BEGIN CATCH

ROLLBACK TRANSACTION;
END CATCH;

RETURN

为什么不起作用?

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

正如评论和答案中所述,DBNull是令人讨厌的要求;您可以使用 null-coalescing 运算符使其具有相当的可读性,但是:

   new SqlParameter ("@id_subject1",((object)subject[0]) ?? DBNull.Value),
   new SqlParameter ("@id_subject2",((object)subject[1]) ?? DBNull.Value),
   new SqlParameter ("@id_subject3",((object)subject[2]) ?? DBNull.Value),
   new SqlParameter ("@id_subject4",((object)subject[3]) ?? DBNull.Value),
   new SqlParameter ("@id_subject5",((object)subject[4]) ?? DBNull.Value),

或者更好:也许您的ExecuteNonQuery方法可以循环参数并检查是否.Value == null,如果是DBNull.Value则替换它。

另外,或者考虑像“小巧玲珑”这样的工具,它可以方便地为您完成所有工作:

connection.Execute("AddNewNews", new {
    title = news.Title,
    //...
    id_writer = news.Id_writer,
    id_subject1 = subject[0],
    //...
    id_subject5 = subject[4],
}, commandType: CommandType.StoredProcedure);

然后完全参数化,并适当处理空值。