1

在下面的代码中,我使用简单的参数化查询。
它有很多参数,有些可以为NULL,有些为 null 时抱怨 FK
如何解决此问题以使其具有可选参数但不使用存储过程
需要明确的是,我想在参数为空时避免尝试更新该字段。

conn.Open();

                string sql = @"UPDATE UserProfile
                               SET FirstName = @p_FirstName
                                  ,LastName = @p_LastName
                                  ,Gender = @p_Gender
                                  ,DateOfBirth = @p_DateOfBirth
                                  ,CityId = @p_CityId
                                  ,MartialStatusId = @p_MartialStatusId
                                  ,ProfileImageId = @p_ProfileImageId
                             WHERE UserId = @p_UserId";

                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {                    
                    cmd.Parameters.AddWithValue("@p_FirstName", userProfile.FirstName);
                    cmd.Parameters.AddWithValue("@p_LastName", userProfile.LastName);
                    cmd.Parameters.AddWithValue("@p_Gender", userProfile.Gender);
                    cmd.Parameters.AddWithValue("@p_DateOfBirth", userProfile.DateOfBirth);
                    cmd.Parameters.AddWithValue("@p_CityId", userProfile.CityId);
                    cmd.Parameters.AddWithValue("@p_MartialStatusId", userProfile.MartialStatusId);
                    cmd.Parameters.AddWithValue("@p_ProfileImageId", userProfile.ProfileImageId);
                    cmd.Parameters.AddWithValue("@p_UserId", userProfile.UserId);

                    cmd.ExecuteNonQuery();

                }
4

2 回答 2

2

您可以构造您的 SQL,以便那些不需要的可选参数永远不会出现在其中:

var sql = new StringBuilder();
sql.Append(@"UPDATE UserProfile
               SET "); 

if(addFirstName) // <-- some boolean condition here
  sql.Append("FirstName = @p_FirstName, ");

// ... etc...

sql.Append(" WHERE UserId = @p_UserId");

与实际参数相同 - 不要添加您不想添加的内容。

于 2013-11-03T13:42:53.300 回答
1

UPDATE您可以按如下方式更改语句,以避免NULL将参数设置为的字段排除在外NULL

UPDATE UserProfile
SET
    FirstName = CASE WHEN @p_FirstName_set THEN @p_FirstName ELSE FirstName END
,   LastName  = CASE WHEN @p_LastName_set  THEN @p_LastName  ELSE LastName END
--  ...and so on
WHERE UserId = @p_UserId

这使参数的数量增加了一倍 - 对于每个可选参数@XYZ,您需要添加一个@XYZ_set参数,1如果@XYZ使用 ,则设置为,或者不使用0时设置为。@XYZ

if (changeFirstName) {
    cmd.Parameters.AddWithValue("@p_FirstName", userProfile.FirstName);
    cmd.Parameters.AddWithValue("@p_FirstName_set", 1);
} else {
    cmd.Parameters.AddWithValue("@p_FirstName", "");
    cmd.Parameters.AddWithValue("@p_FirstName_set", 0);
}
// ... and so on

您可以添加一个函数来封装此if语句。

这种方法允许您NULL在需要时设置值,因为有关是否设置相应参数的信息不再包含在参数本身的值中。

请注意,无论设置了多少字段,查询都保持静态,因此您的 RDBMS 可以避免在每次设置不同的参数组时构建新的查询计划。

于 2013-11-03T13:39:46.480 回答