【问题标题】:Adding parameters to sqlCommand query向 sqlCommand 查询添加参数
【发布时间】:2018-10-24 06:58:37
【问题描述】:

我正在做我的第一次数据库迁移,我正在尝试重新创建这个sqlCommand,以便它将正确的值添加到代表对象中。

    string sqlCommand = "UPDATE WITestData SET " +
            "Width01 = ?, Angle01 = ?, Comment01 = ?, " +
            "Width02 = ?, Angle02 = ?, Comment02 = ?, " +
            "Width03 = ?, Angle03 = ?, Comment03 = ?, " +
            "Width04 = ?, Angle04 = ?, Comment04 = ?, " +
            "Width05 = ?, Angle05 = ?, Comment05 = ?, " +
            "Width06 = ?, Angle06 = ?, Comment06 = ?, " +
            "Width07 = ?, Angle07 = ?, Comment07 = ?, " +
            "Width08 = ?, Angle08 = ?, Comment08 = ?, " +
            "Width09 = ?, Angle09 = ?, Comment09 = ?, " +
            "Width10 = ?, Angle10 = ?, Comment10 = ? " +
            "WHERE ReportNumber = @reportNumber";
        var parameters = new object[31];
        for (int i = 0; i < WITestData.WIData.Length; i++)
        {
            parameters[3 * i] = WITestData.WIData[i].Width;
            parameters[3 * i + 1] = WITestData.WIData[i].Angle;
            parameters[3 * i + 2] = WITestData.WIData[i].Comment;

        }  parameters[30] = WITestData.ReportNumber;
        if (ExecuteNonQuery(sqlCommand, parameterList))
        {
            var index = m_DataManager.Database.WITestData.FindIndex(t => t.ReportNumber == WITestData.ReportNumber);
            m_DataManager.Database.WITestData[index] = WITestData;
            return true;
        }
        return false;
    }

我在 for(...) 中添加了以下内容,以便为每个对象分配一个单独的参数,以便输出正确的值。

 for (int i = 0; i < WITestData.WIData.Length; i++)
        {
            //input Parameters into sqlCommand
            string widthParameter = $"@width{counter}";
            string angleParameter = $"@angle{counter}";
            string commentParameter = $"@comment{counter}";
            using (SqlCommand command = new SqlCommand())
            {
                parameterList.Add(new SqlParameter(widthParameter, WITestData.WIData[i].Width));
                parameterList.Add(new SqlParameter("@angle", angleParameter));
                parameterList.Add(new SqlParameter("@comment", commentParameter));

                parameterList.Add(command.Parameters.AddWithValue("@reportNumber", WITestData.ReportNumber));

                command.Parameters.Clear();
            }
            parameters[3 * i] = WITestData.WIData[i].Width;
            parameters[3 * i + 1] = WITestData.WIData[i].Angle;
            parameters[3 * i + 2] = WITestData.WIData[i].Comment;

            counter++;
        }

注意:我在方法的顶部创建了一个int counter = 1 和一个var parameterList = new List&lt;SqlParameter&gt;();

如何将宽度/角度/注释参数输入到 sqlCommand 中并确保它们的值正确分配?

【问题讨论】:

  • 你有一个 command.Paramenters.Clear 在里面使用。之后参数就消失了
  • @Steve 是的,因为否则参数将无法正确读取,出于某种原因。我在其他方法中尝试过 command.parameters.Clear 并以这种方式显示正确的信息。

标签: c# sql ms-access


【解决方案1】:

首先出错的是代码中的 command.Parameters.Clear();。这会从命令中删除所有参数,但是,在该行之后,您似乎从未将参数读取到命令对象中,而是尝试将它们添加到类型未定义的对象数组中。

尝试修复您的代码我从您的代码中存在的基本信息开始。您的查询需要 31 个参数。因此,我假设 WIData.Length 为 10,并且在循环之后添加了最终参数(ReportNumber

使用这种方法可以大大简化代码

// A command requires an sql text and an OPEN connection to execute....
OleDbCommand cmd = new OleDbCommand(sqlCommand, connection);

// Use directly the parameters collection inside the command object
var parameters = cmd.Parameters;

// Loop over the WIData array length (10 times = 30 parameters)
for (int i = 0; i < WITestData.WIData.Length; i++)
{
    // No need to give an unique name, however, if you really want a name 
    //  you can replace ? with 
    // "W"+i.ToString(), "A"+i.ToString() and "C"+i.ToString()
    parameters.Add("?", OleDbType.Decimal).Value = WITestData.WIData[i].Width;
    parameters.Add("?", OleDbType.Decimal).Value = WITestData.WIData[i].Angle;
    parameters.Add("?", OleDbType.VarWChar).Value = WITestData.WIData[i].Comment;
}  
parameters.Add("?", OleDbType.Integer).Value = WITestData.ReportNumber;

我还假设参数的数据类型是十进制、字符串和整数,如果它们不正确,您应该替换 OleDbType,但不要删除类型。它确保正确解析您的值。

这是标准方法,但如果您想保留当前代码,则可以将循环更改为

for (int i = 0; i < WITestData.WIData.Length; i++)
{
    string widthParameter = $"@width{counter}";
    string angleParameter = $"@angle{counter}";
    string commentParameter = $"@comment{counter}";
    parameterList.Add(widthParameter, OleDbType.Deciaml).Value = WITestData.WIData[i].Width;
    parameterList.Add(angleParameter, OleDbType.Decimal).Value = WITestData.WIData[i].Width;
    parameterList.Add(commentParameter, OleDbType.VarWChar).Value = WITestData.WIData[i].Comment;
    counter++;
}
parameterList.Add("@reportNumber", OleDbType.Integer).Value = WITestData.ReportNumber;

【讨论】:

  • 我仍然不确定为什么我应该使用 oleDbtype 来调整代码 sql,以便与 sql server 一起使用。所有其他方法都与 sqlCommand/ 参数一起使用,它们可以完美运行。但是我设法解决了这个问题。如果您想/有兴趣查看解决方案,我可以编辑我的问题以展示或回答我自己的问题。谢谢你的信息。我对这种编程和语言有点陌生,所以我正在努力学习。
  • 如果您连接到 MS-Access,您将取消 OleDb 客户端类。如果连接到 Sql Server,则使用 Sql Client 类。 (除非您想坚持使用 OleDb 并错过适当的 Sql Server NET 驱动程序的好处,例如命名参数)。如果您想发布自己的问题答案,您可以。 (就算接受了)
【解决方案2】:

这解决了我的问题。

   int counter = 1;
        var parameterList = new List<SqlParameter>();
        SqlCommand command = new SqlCommand();
        string sqlCommand = $"UPDATE WITestData SET " +
            "Width01 = {widthParameter}, Angle01 = {angleParameter}, Comment01 = {commentParameter}, " +
            "Width02 = {widthParameter}, Angle02 = {angleParameter}, Comment02 = {commentParameter}, " +
            "Width03 = {widthParameter}, Angle03 = {angleParameter}, Comment03 = {commentParameter}, " +
            "Width04 = {widthParameter}, Angle04 = {angleParameter}, Comment04 = {commentParameter}, " +
            "Width05 = {widthParameter}, Angle05 = {angleParameter}, Comment05 = {commentParameter}, " +
            "Width06 = {widthParameter}, Angle06 = {angleParameter}, Comment06 = {commentParameter}, " +
            "Width07 = {widthParameter}, Angle07 = {angleParameter}, Comment07 = {commentParameter}, " +
            "Width08 = {widthParameter}, Angle08 = {angleParameter}, Comment08 = {commentParameter}, " +
            "Width09 = {widthParameter}, Angle09 = {angleParameter}, Comment09 = {commentParameter}, " +
            "Width10 = {widthParameter}, Angle10 = {angleParameter}, Comment10 = {commentParameter} " +
            "WHERE ReportNumber = @reportNumber";
        var parameters = new object[31];
        for (int i = 0; i < WITestData.WIData.Length; i++)
        {
            //input Parameters into sqlCommand
            string widthParameter = $"@width{(counter < 10 ? counter.ToString("D2") : counter.ToString() )}";
            string angleParameter = $"@angle{(counter < 10 ? counter.ToString("D2") : counter.ToString())}";
            string commentParameter = $"@comment{(counter < 10 ? counter.ToString("D2") : counter.ToString())}";
            using (command)
            {
                parameterList.Add(new SqlParameter(widthParameter, WITestData.WIData[i].Width));
                parameterList.Add(new SqlParameter(angleParameter, WITestData.WIData[i].Angle));
                parameterList.Add(new SqlParameter(commentParameter, WITestData.WIData[i].Comment));

                command.Parameters.Clear();
            }
            parameters[3 * i] = WITestData.WIData[i].Width;
            parameters[3 * i + 1] = WITestData.WIData[i].Angle;
            parameters[3 * i + 2] = WITestData.WIData[i].Comment;

            counter++;
        }

代码可能看起来更好,但在这种情况下,我会在稍后的清理阶段进行处理。

【讨论】:

    猜你喜欢
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多