[C#] SqlParameter에 null 할당

다음 코드는 “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충족시키는 유형으로 캐스팅 할 수 있습니다 ?:.

??다음과 같이 null 병합 연산자를 사용할 수 있습니다

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 유형에는이 캐스트를 피하는 데 사용할 수있는 특수 Null 필드가 있습니다.

예를 들어 SqlInt32.Null“SqlInt32 클래스의이 인스턴스에 할당 할 수있는 DBNull을 나타냅니다.”

int? example = null;
object exampleCast = (object) example ?? DBNull.Value;
object exampleNoCast = example ?? SqlInt32.Null;


답변

DBNull.Value저장 프로 시저 내에 기본값이 지정되지 않은 경우 (저장 프로 시저를 사용하는 경우) SQLCommand 내에서 널 매개 변수로 전달해야 합니다. 가장 좋은 방법은 DBNull.Value쿼리 실행 전에 누락 된 매개 변수 를 할당 하는 것이며 foreach를 수행하면 작업이 수행됩니다.

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가 서로 다르므로 조건문에 다른 유형의 값을 사용할 수 없기 때문입니다. 이것이 도움이되기를 바랍니다.


답변

한 줄의 코드로 다음을 시도하십시오.

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;


답변

조건부 (삼항) 연산자를 사용하는 경우 컴파일러는 두 유형 사이에 암시 적 변환이 필요합니다. 그렇지 않으면 예외가 발생합니다.

따라서 다음 중 하나를 캐스팅하여 문제를 해결할 수 있습니다 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 클래스 의 Parameters 속성을 사용하여이를 수행하는 것이 더 좋습니다 .

public static void AddCommandParameter(SqlCommand myCommand)
{
    myCommand.Parameters.AddWithValue(
        "@AgeIndex",
        (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex);
}