在我的代码中,我使用简单的参数化查询
它有很多参数,有些可以是 NULL ,有些是null 抱怨FK 。
如何解决此问题以获得可选参数,但不使用存储过程
要清楚,我想在参数为null时避免尝试更新该字段。
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();
}
答案 0 :(得分: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");
与实际参数相同 - 请勿添加您不想添加的内容。
答案 1 :(得分: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
,或者<{1}}时未使用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
,因为参数本身的值中不再包含有关是否设置相应参数的信息。
请注意,无论设置了多少字段,查询都将保持静态,因此每次设置不同的参数组时,RDBMS都可能避免构建新的查询计划。