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

本文关键字:参数 TSQL 存储过程 | 更新日期: 2023-09-27 18:28:37

我不知道这个查询是否值得问,但最好了解什么有效,什么无效以及为什么。

我有一张这样的表,叫做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. 如果我们添加一个名为"标题"的新列,并且前端 HTML 有一个下拉列表。我们可以通过在存储过程中再添加一行,向任何函数添加一个行参数来更新我们的代码隐藏。但是因为现在存储过程将有一个新参数,那么在我们没有更新"标题"的函数后面的代码中,我们将收到 SQL 异常错误,因为我们没有通过这个给定函数将数据提供回存储过程。
我认为

这里的设计很糟糕,但我认为对我来说唯一可能的解决方案是有多个存储过程,即每个函数一个。任何想法,如果这是最好的方法,它是否强大?

我实际需要的是不要更新某些列(如果它们已经存在(。例如,我不想在更新"喜欢"时更新行的名称。

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

如果您

不想更新它,则可以只为两个值中的任何一个传入NULL,然后将存储过程调整为:

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的值 - 实际上是"非更新"。

若要从 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()真的没有意义....