C#TSQL存储过程不传递参数?

时间:2015-12-30 11:20:47

标签: c# sql-server tsql stored-procedures parameters

我不知道这个查询是否值得询问,但是了解哪些有效和无效以及为什么这样做会很好。

我有一个名为tbl_Person_Details的表:

ID | Name | Likes
-----------------
0  | Jon  | Fish
1  | Doey | Coding

这样的代码背后(示例显示了两个函数,但可能有更多):

public void updatePerson()
{
    string sID = GridView1.SelectedDataKey[0].ToString();

    SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
    con.Open();

    SqlCommand comm = new SqlCommand("spUpdatePersonBasics", con);
    comm.CommandType = CommandType.StoredProcedure;

    comm.Parameters.Add(new SqlParameter("@Name", tbName.Text.ToString()));
    comm.Parameters.Add(new SqlParameter("@ID", sID));

    object tmp = comm.ExecuteScalar();
    con.Close();

    lblStatus.Text = "<img src=\"img/icons/green-tick.gif\" /> <strong>>Person Details have been updated!</strong>";
}

public void updatePersonLikes()
{
    string sID = GridView1.SelectedDataKey[0].ToString();

    SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
    con.Open();

    SqlCommand comm = new SqlCommand("spUpdatePersonBasics", con);
    comm.CommandType = CommandType.StoredProcedure;

    comm.Parameters.Add(new SqlParameter("@Likes", tbName.Text.ToString()));
    comm.Parameters.Add(new SqlParameter("@ID", sID));

    object tmp = comm.ExecuteScalar();
    con.Close();

    lblStatus.Text = "<img src=\"img/icons/green-tick.gif\" /> <strong>>Person likes have been updated!</strong>";
}

存储过程:

ALTER PROCEDURE [dbo].[spUpdatePersonBasics]
    @ID int, 
    @Name varchar(50),
    @Likes varchar(50)
AS
    UPDATE tbl_Person_Details
    SET Name = @Name,
        Likes = @Likes
    WHERE ID = @ID

    SELECT CAST(scope_identity() AS int)

问题:

到目前为止,我们可以看到所有精美和花花公子。但是,在调试时,我们可能会有多个导致问题的场景。这些如下:

  1. 在我的代码隐藏函数之后,我必须声明所有参数,即使有时我只想更新一个参数。
  2. 如果我们添加一个名为“Title”的新列,并且前端HTML有一个下拉列表。我们可以通过向存储过程添加一行以及向任何函数添加一行参数来更新我们的代码。但是因为现在存储过程将有一个新参数,然后在函数中我们没有更新'Title',我们将得到一个SQL异常错误,因为我们不通过这个给定的函数将数据提供回存储过程。
  3. 我认为这里的设计很糟糕,但我认为唯一可行的解​​决方案是拥有多个存储过程,即每个函数一个。任何想法,如果这是最好的方式,它是否健壮?

    我真正需要的是不更新某些列(如果它们已存在)。例如,当我更新Likes时,我不想更新行的名称。

1 个答案:

答案 0 :(得分:2)

如果您不想更新它, 可以只传递NULL中的任何一个值,然后根据此修改存储过程:< / p>

ALTER PROCEDURE [dbo].[spUpdatePersonBasics]
    @ID int, 
    @Name varchar(50),
    @Likes varchar(50)
AS
    UPDATE tbl_Person_Details
    SET Name = ISNULL(@Name, Name)
        Likes = ISNULL(@Likes, Likes)
    WHERE ID = @ID

因此,如果您传入@Name = NULL,则UPDATE基本上会将Name更新为Name - a&#34;非更新&#34; ,真的。

要从C#传入NULL,请使用DBNull.Value

comm.Parameters.Add("@Name", SqlDbType.VarChar, 50).Value = DBNull.Value;

我选择使用.Add()方法,并选择为参数显式指定SqlDbType(包括基于字符串的参数的长度)。

如果你想传递参数 - 只需使用:

comm.Parameters.Add("@Name", SqlDbType.VarChar, 50).Value = tbName.Text;

由于.Text属性已经string,因此在其上调用.ToString()真的没有意义....