1

以下のコードでは、単純なパラメーター化されたクエリを使用しています。
多くのパラメーターがあり、一部は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();

                }
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

これにより、パラメーターの数が 2 倍になります。オプションのパラメーターごとに、 が使用されている場合は に、が使用されていない場合はに設定するパラメーター@XYZを追加する必要があります。@XYZ_set1@XYZ0@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 に答える