sqlparameterにnullを割り当てます
-
14-10-2019 - |
質問
次のコードには、「dbnullからintへの暗黙的な変換はありません」というエラーが発生します。
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
parameters[0] = planIndexParameter;
解決
問題は、 ?:
オペレーターは返品タイプを決定できません。 int
互換性がない値またはdbnullタイプの値。
もちろん、ageindexのインスタンスを型にすることができます object
それは満足します ?:
要件。
使用できます ??
次のように、ヌルコーールスする演算子
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (object)AgeItem.AgeIndex ?? DBNull.Value;
parameters[0] = planIndexParameter;
これがからの引用です MSDNドキュメント のために ?:
問題を説明するオペレーター
first_expressionとsecond_expressionのタイプは同じでなければならないか、暗黙の変換があるタイプから他のタイプに存在する必要があります。
他のヒント
受け入れられた答え キャストを使用することを提案します。ただし、ほとんどのSQLタイプには、このキャストを回避するために使用できる特別なヌルフィールドがあります。
例えば、 SqlInt32.Null
「SQLINT32クラスのこのインスタンスに割り当てることができるDBNULLを表します。」
int? example = null;
object exampleCast = (object) example ?? DBNull.Value;
object exampleNoCast = example ?? SqlInt32.Null;
パスが必要です DBNull.Value
SQLCommand内のNULLパラメーターとして、デフォルト値がストアドプロシージャ内で指定されていない限り(ストアドプロシージャを使用している場合)。最良のアプローチは割り当てることです DBNull.Value
クエリの実行前に欠落しているパラメーターの場合、およびフォローフォーチーがジョブを行います。
foreach (SqlParameter parameter in sqlCmd.Parameters)
{
if (parameter.Value == null)
{
parameter.Value = DBNull.Value;
}
}
それ以外の場合は、この行を変更します。
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
次のように:
if (AgeItem.AgeIndex== null)
planIndexParameter.Value = DBNull.Value;
else
planIndexParameter.Value = AgeItem.AgeIndex;
条件付きステートメントで異なるタイプの値を使用できないため、dbnullとintは互いに異なるためです。これが役立つことを願っています。
コードの1行で、これを試してください:
var piParameter = new SqlParameter("@AgeIndex", AgeItem.AgeIndex ?? (object)DBNull.Value);
これを試して:
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.IsNullable = true; // Add this line
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex== ;
parameters[0] = planIndexParameter;
条件付き(三元)演算子を使用する場合、コンパイラは両方のタイプ間で暗黙的な変換を必要とします。そうしないと、例外が得られます。
そのため、両方の1つをにキャストすることで修正できます System.Object
:
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : (object) AgeItem.AgeIndex;
しかし、結果は本当にきれいではなく、このキャストを常に覚えておく必要があるため、代わりにそのような拡張法を使用できます。
public static object GetDBNullOrValue<T>(this T val)
{
bool isDbNull = true;
Type t = typeof(T);
if (Nullable.GetUnderlyingType(t) != null)
isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
else if (t.IsValueType)
isDbNull = false;
else
isDbNull = val == null;
return isDbNull ? DBNull.Value : (object) val;
}
次に、この簡潔なコードを使用できます。
planIndexParameter.Value = AgeItem.AgeIndex.GetDBNullOrValue();
私の意見では、より良い方法はこれを行うことです パラメーター のプロパティ sqlcommand クラス:
public static void AddCommandParameter(SqlCommand myCommand)
{
myCommand.Parameters.AddWithValue(
"@AgeIndex",
(AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex);
}
利用可能なNullable(T)構造の使用を検討してください。それらを持っている場合のみを設定することができます、そしてあなたのSQLコマンドオブジェクトは、あなたの最後に手間がかからずにそれに応じてヌル可能な値を認識し、それに応じて処理します。
これを試して:
if (AgeItem.AgeIndex != null)
{
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = AgeItem.AgeIndex;
parameters[0] = planIndexParameter;
}
言い換えれば、パラメーターがnullの場合は、保存されたProcに送信しないでください(もちろん、保存されたProcが質問に暗黙のヌルパラメーターを受け入れると仮定します)。
このようなことを試してみてください:
if (_id_categoria_padre > 0)
{
objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}
int? nullableValue = null;
object nullableValueDB
{
get{
if(nullableValue==null)
return DBNull.Value;
else
return (int)nullableValue;
}
}
私はそのように解決しています。
if (_id_categoria_padre > 0)
{
objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}
if (AgeItem.AgeIndex== null)
cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = DBNull);
else
cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = AgeItem.AgeIndex);
これは私が単にすることです...
var PhoneParam = new SqlParameter("@Phone", DBNull.Value);
if (user.User_Info_Phone != null)
{
PhoneParam.SqlValue = user.User_Info_Phone;
}
return this.Database.SqlQuery<CustLogonDM>("UpdateUserInfo @UserName, @NameLast, @NameMiddle, @NameFirst, @Address, @City, @State, @PostalCode, @Phone",
UserNameParam, NameLastParam, NameMiddleParam, NameFirstParam, AddressParam, CityParam, StateParam, PostalParam, PhoneParam).Single();
dynamic psd = DBNull.Value;
if (schedule.pushScheduleDate > DateTime.MinValue)
{
psd = schedule.pushScheduleDate;
}
sql.DBController.RunGeneralStoredProcedureNonQuery("SchedulePush",
new string[] { "@PushScheduleDate"},
new object[] { psd }, 10, "PushCenter");
これの単純な拡張方法は、次のとおりです。
public static void AddParameter(this SqlCommand sqlCommand, string parameterName,
SqlDbType sqlDbType, object item)
{
sqlCommand.Parameters.Add(parameterName, sqlDbType).Value = item ?? DBNull.Value;
}
ヌルチェックを使用して簡単な方法を使用します。
public SqlParameter GetNullableParameter(string parameterName, object value)
{
if (value != null)
{
return new SqlParameter(parameterName, value);
}
else
{
return new SqlParameter(parameterName, DBNull.Value);
}
}
私のコードは、実際のプロジェクトで働いています。
public bool Key_AddExisting
(
string clave
, int? idHito_FileServer
, int? idTipoDocumental_Almacen
, string tipoExp_CHJ
, int idTipoExp_Verti2
, int idMov_Verti2
)
{
List<SqlParameter> pars = new List<SqlParameter>()
{
new SqlParameter { ParameterName = "@Clave", Value = clave }
LOOK -> , idHito_FileServer == null ? new SqlParameter { ParameterName = "@IdHito_FileServer", Value = DBNull.Value } : new SqlParameter { ParameterName = "@IdHito_FileServer", Value = idHito_FileServer }
LOOK -> , idTipoDocumental_Almacen == null ? new SqlParameter { ParameterName = "@IdTipoDocumental_Almacen", Value = DBNull.Value } : new SqlParameter { ParameterName = "@IdTipoDocumental_Almacen", Value = idTipoDocumental_Almacen }
, new SqlParameter { ParameterName = "@TipoExp_CHJ", Value = tipoExp_CHJ }
, new SqlParameter { ParameterName = "@IdTipoExp_Verti2", Value = idTipoExp_Verti2 }
, new SqlParameter { ParameterName = "@IdMov_Verti2", Value = idMov_Verti2 }
};
string sql = "INSERT INTO [dbo].[Enlaces_ClavesCHJ_MovimientosVerti2] " +
"( " +
" [Clave] " +
", [IdHito_FileServer] " +
", [IdTipoDocumental_Almacen] " +
", [TipoExp_CHJ] " +
", [IdTipoExp_Verti2] " +
", [IdMov_Verti2] " +
") " +
"VALUES" +
"( " +
" @Clave" +
", @IdHito_FileServer" +
", @IdTipoDocumental_Almacen" +
", @TipoExp_CHJ" +
", @IdTipoExp_Verti2" +
", @IdMov_Verti2" +
")";
return DbBasic.ExecNonQuery(ref this.conn, sql, pars);
}