codememo

"SqlParameterCollection은 Null이 아닌 SqlParameter 유형 개체만 허용하고 String 개체는 허용하지 않습니다."

tipmemo 2023. 8. 16. 22:24
반응형

"SqlParameterCollection은 Null이 아닌 SqlParameter 유형 개체만 허용하고 String 개체는 허용하지 않습니다."

계속 예외가 발생합니다.

The SqlParameterCollection only accepts non-null SqlParameter type objects, not String objects

다음 코드를 실행하는 동안:

string StrQuery;
using (SqlConnection conn = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=SanFransiscoData;Integrated Security=True;Pooling=False"))
{
    using (SqlCommand comm = new SqlCommand())
    {
        comm.Connection = conn;
        conn.Open();
       // SqlParameter author = new SqlParameter("@author", dataGridView1.Rows[0].Cells[0].Value.ToString());
        comm.Parameters.Add("@author", SqlDbType.VarChar);
        comm.Parameters.Add("@title", SqlDbType.NVarChar);
        comm.Parameters.Add("@genre", SqlDbType.VarChar);
        comm.Parameters.Add("@price", SqlDbType.Float);
        comm.Parameters.Add("@publish_date", SqlDbType.Date);
        comm.Parameters.Add("@description", SqlDbType.NVarChar);
        comm.Parameters.Add("@bookid", SqlDbType.VarChar);
        for (int i = 0; i < dataGridView1.Rows.Count; i++)
        {
            StrQuery = "INSERT INTO BooksData VALUES(@author,@title,@genre,@price,@publish_date,@description,@bookid)";
            comm.Parameters.Add(dataGridView1.Rows[i].Cells[0].Value.ToString());
            comm.Parameters.Add(dataGridView1.Rows[i].Cells[1].Value.ToString());
            comm.Parameters.Add(dataGridView1.Rows[i].Cells[2].Value.ToString());
            comm.Parameters.Add(Convert.ToDecimal(dataGridView1.Rows[i].Cells[3].Value));
            comm.Parameters.Add(Convert.ToDateTime(dataGridView1.Rows[i].Cells[4].Value));
            comm.Parameters.Add(dataGridView1.Rows[i].Cells[5].Value.ToString());
            comm.Parameters.Add(dataGridView1.Rows[i].Cells[6].Value.ToString());
            comm.CommandText = StrQuery;
            comm.ExecuteNonQuery();
        }
    }
}

제가 어디서 잘못되고 있는지 말씀해 주세요.

위에 언급된 모든 단계를 시도했지만 도움이 되지 않습니다.

네임스페이스를 변경하여 최종적으로 찾아서 수정했습니다.

시스템을 사용합니다.Microsoft 사용하기 위한 Data.SqlClient.Data.SqlClient

참조: https://learn.microsoft.com/en-us/sql/connect/ado-net/introduction-microsoft-data-sqlclient-namespace?view=sql-server-ver16

System에 대한 참조를 교체했습니다.Microsoft가 설치된 Data.SqlClient.Data.SqlClient가 사용 설명서를 수정하여 문제가 해결되었습니다.

.csproj에서 나는 지금

  <ItemGroup>
    <PackageReference Include="Microsoft.Data.SqlClient" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
  </ItemGroup>

하지만 다음 시나리오를 사용하여 시스템을 생성했습니다.Data.SqlClient.Sql 매개 변수

    public static List<T> RunQuery<T>(ApiDbContext context, string query, Func<DbDataReader, T> map, params SqlParameter[] parameters)
    {
        var cn = context.Database.GetDbConnection();
        var oldState = cn.State;
        if (cn.State.Equals(ConnectionState.Closed)) { cn.Open(); }

        using (var command = cn.CreateCommand())
        {
            command.CommandText = query;
            command.CommandType = CommandType.Text;
            foreach (var param in parameters)
            {
                var p = new System.Data.SqlClient.SqlParameter
                {
                    ParameterName = param.ParameterName, Value = param.Value, SqlDbType = param.SqlDbType
                };
                command.Parameters.Add(p);
            }
            if (cn.State.Equals(ConnectionState.Closed)) { cn.Open(); }
            var entities = new List<T>();
            using (var result = command.ExecuteReader())
            {
                while (result.Read())
                {
                    entities.Add(map(result));
                }
            }

            if (oldState.Equals(ConnectionState.Closed) && cn.State == ConnectionState.Open) { cn.Close(); }
            return entities;
        }
    }

동일한 오류가 발생하여 사용해야 했습니다.AddWithValue이렇게...

cmd.Parameters.AddWithValue(@columnToUpdate, newValue);
cmd.Parameters.AddWithValue(@conditionalColumn, conditionalValue);

사용할 때Add메서드, 새 매개 변수를 추가하려고 합니다.당신이 원하는 것은 가치를 할당하는 것입니다.변경 내용:

comm.Parameters.Add(dataGridView1.Rows[i].Cells[0].Value.ToString());

대상:

comm.Parameters["@author"].Value = dataGridView1.Rows[i].Cells[0].Value.ToString();

다른 파라미터도 마찬가지입니다.

아래로 시도해 보십시오.

comm.Parameters.Add("@author", SqlDbType.VarChar);
comm.Parameters["@author"].Value = dataGridView1.Rows[i].Cells[0].Value.ToString();

동일한 문제가 발생했지만, 제 문제는 시도 중인 것과 유사한 object[2] = object[1]를 SqlParameters로 실행하고 있었습니다.

스레드에 추가하기 위해 이와 같은 방법으로 SqlParameters의 간단한 객체 배열을 추가했습니다.

    private SqlParameter GetGenericParamsObject(string name, object data)
    {
        return new SqlParameter(name, SetSqlDataType(data.GetType().ToString())) { Direction = Input, Value = data };
    }

SetSqlDataType()에 대한 단순 스위치, 즉 SqlDbType이 있는 경우.Int는 설정할 반환 유형 중 하나입니다.

그럼 나는 뛰어요

    private static void ExecuteSqlCommand(DbContext dbContext, string sql, params object[] sqlParameters)
    {
        try
        {
            if (dbContext.Database.Connection.State == ConnectionState.Closed)
                dbContext.Database.Connection.Open();
            var cmd = dbContext.Database.Connection.CreateCommand();
            cmd.CommandText = sql;
            foreach (var param in sqlParameters)
                cmd.Parameters.Add(param);
            cmd.ExecuteNonQuery();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }

이렇게 하면 적절한 데이터 유형으로 캐스트하는 데 도움이 되며 명령 메서드에서 매개 변수 이름, 데이터 유형 및 개체를 이동하여 디버깅을 쉽게 한 다음 전체 SqlParameter를 cmd에 추가할 수 있습니다.매개 변수.

이 질문의 미래 독자를 위해 - 예제는 다음을 다룹니다..Add(),그렇지만.Remove()올바르게 사용하지 않을 경우에도 이 오류가 발생합니다.올바른 사용 방법.Add()다른 사람들에 의해 문서화된 바와 같이:

cmd.Parameters.AddWithValue("Key", "Value");

올바른 사용 방법.Remove()다음과 같습니다.

cmd.Parameters.Remove(command.Parameters["Key"]); 

사용할 때 동일한 오류가 발생했습니다.

cmd.Parameters.Add(pars)

어디에pars의 배열이었습니다.SqlParameter문제는 제가 사용하고 있다는 것이었습니다.Add()기능을 사용했어야 했습니다.AddRange()대신.

cmd.Parameters.AddRange(pars)

다음과 같은 간단한 솔루션이 적합합니다.

SqlCommand command = ...
command.Parameters.Add(parameterPlaceholder, SqlDbType.Char);
command.Parameters[parameterPlaceholder].Value = (object)parameterValue ?? DBNull.Value;

null 값을 "DBNull"로 바꿉니다."값"이 핵심입니다.위의 예와 같이 SqlDbType을 필요에 맞게 조정하는 것을 잊지 마십시오.

저도 System을 사용하여 이 오류를 얻었습니다.데이터. 엔티티.데이터베이스

sqlquery

EF 6.4의 경우, 저는 다음과 같은 것을 사용해야 했습니다.

  var parameters = new List<SqlParameter> parameters  // using System.Data.SqlClient
  sql = $"{sql} and ( headkey like @headkey)";
  parameters.Add(new SqlParameter("@headkey", $"%{headKey}%") { DbType = DbType.String });

이것을 먹어보세요!!도움이 될 것입니다.

저는 제 프로젝트에서 이런 방법을 시도해 왔습니다. 그것은 제 문제를 해결해줍니다.

cmd.Parameters.Add(new SqlParameter("@author", SqlDbType.VarChar));

StrQuery = "INSERT INTO BooksData 
VALUES(@author,@title,@genre,@price,@publish_date,@description,@bookid)";

cmd.Parameters.AddWithValue("@author", dataGridView1.Rows[i].Cells[0].Value.ToString());

cmd.ExecuteNonQuery();

언급URL : https://stackoverflow.com/questions/22705767/sqlparametercollection-only-accepts-non-null-sqlparameter-type-objects-not-str

반응형