본문 바로가기
MES 문의 : 010-8015-0400
IT개발/개발 일반

c#, "SqlParameter이(가) 이미 다른 SqlParameterCollection에 들어 있습니다." 에러 처리

by all it 2024. 11. 11.
반응형

현재 사용 중인 코드에서 "SqlParameter이(가) 이미 다른 SqlParameterCollection에 들어 있습니다." 오류가 발생하는 경우, 주로 동일한 SqlParameter 인스턴스를 여러 번 사용하려는 경우가 문제일 수 있다. 이 오류를 방지하려면, parameters 리스트에 포함된 각 파라미터가 다른 SqlCommand에 재사용되지 않도록 해야 한다.

문제 코드

using (var command = new SqlCommand(query, GetConnection()))
{
    if (parameters != null)
    {
        command.Parameters.AddRange(parameters);
    }

    command.CommandType = commandType;
    command.CommandTimeout = TimeOut;

    using (var adapter = new SqlDataAdapter(command))
    {
        adapter.Fill(resultTable);
    }
}

아래와 같이 코드를 수정하여 AddRange 호출 전에 각 파라미터를 복제하거나, 매번 새 인스턴스를 추가하도록 변경할 수 있다. 이를 통해 동일한 파라미터 객체가 여러 곳에서 사용되는 문제를 해결할 수 있다.

1. 파라미터 복제 후 사용

AddRange를 사용하기 전에 각 파라미터를 새로운 인스턴스로 복제한다.

수정된 코드

using (var command = new SqlCommand(query, GetConnection()))
{
    if (parameters != null)
    {
        foreach (SqlParameter parameter in parameters)
        {
            // 파라미터를 복제하여 새로운 SqlParameter 인스턴스로 추가
            var clonedParameter = new SqlParameter(parameter.ParameterName, parameter.SqlDbType)
            {
                Value = parameter.Value,
                Direction = parameter.Direction,
                Size = parameter.Size,
                Precision = parameter.Precision,
                Scale = parameter.Scale
            };
            command.Parameters.Add(clonedParameter);
        }
    }

    command.CommandType = commandType;
    command.CommandTimeout = TimeOut;

    using (var adapter = new SqlDataAdapter(command))
    {
        adapter.Fill(resultTable);
    }
}
  • 파라미터 복제: 파라미터 객체를 복제하여 각 SqlCommand에 다른 인스턴스를 추가한다. 이렇게 하면 원래의 파라미터 객체는 다른 곳에서 사용할 수 있다.

2. 파라미터 리스트를 새로 생성해서 사용

매번 새 파라미터 리스트를 생성하고, 기존의 parameters를 기준으로 새로운 SqlParameter 객체를 생성하여 사용한다.

수정된 코드

using (var command = new SqlCommand(query, GetConnection()))
{
    if (parameters != null)
    {
        // 새 파라미터 리스트를 생성하여 기존 파라미터 복사
        foreach (SqlParameter parameter in parameters)
        {
            command.Parameters.Add(new SqlParameter(parameter.ParameterName, parameter.Value)
            {
                SqlDbType = parameter.SqlDbType,
                Direction = parameter.Direction,
                Size = parameter.Size,
                Precision = parameter.Precision,
                Scale = parameter.Scale
            });
        }
    }

    command.CommandType = commandType;
    command.CommandTimeout = TimeOut;

    using (var adapter = new SqlDataAdapter(command))
    {
        adapter.Fill(resultTable);
    }
}
  • 새로운 파라미터 리스트 생성: 기존의 파라미터들을 기준으로 새로운 파라미터 인스턴스를 생성하여 추가한다. 이렇게 하면 각 파라미터 객체가 다른 SqlCommand에서 사용될 때 발생하는 문제를 방지할 수 있다.

요약

  • 원인: 동일한 SqlParameter 객체가 여러 SqlCommand에서 사용되어 "SqlParameter이(가) 이미 다른 SqlParameterCollection에 들어 있습니다." 오류가 발생하는 경우가 많다.
  • 해결책:
    1. 파라미터 복제: AddRange를 호출하기 전에 각 SqlParameter 객체를 복제한 후 사용한다.
    2. 새 파라미터 생성: 기존 파라미터를 기준으로 새로운 SqlParameter 인스턴스를 생성하여 사용한다.

이렇게 수정하면 동일한 파라미터 객체가 여러 번 사용되는 문제를 피할 수 있으며, 순환 참조 오류도 방지할 수 있다.

반응형

댓글