【问题标题】:Must declare a scalar variable (C# and OleDb)必须声明一个标量变量(C# 和 OleDb)
【发布时间】:2018-03-05 11:13:29
【问题描述】:

我知道这个问题已经被问过好几次了,但没有一个答案能帮助我解决这个问题。

所以,我正在编写数据传输实用程序,将数据从 OleDb 数据库的一个表复制到另一个 OleDb 数据库的表。

我已从源数据库中读取了所有数据,我正在尝试写入,但总是出现此错误

必须声明标量变量“@CategoryID”

这是代码

 // generating the insert string below
 string insert = "INSERT INTO Categories VALUES (";
 for(int i = 0; i < cols.Length; i++)
 {
     string coma = ", ";
     if (i == cols.Length - 1)
     coma = " )";

     insert += "@" + cols[i] + coma;
 }

try
{ 
    while (src_reader.Read())         // reading from source database
    {
        dstcmd.CommandText = insert;   

        for (int i = 0; i < cols.Length; i++)
        {
            string temp = "@" + cols[i];     // cols is array of column names
            dstcmd.Parameters.AddWithValue(temp, src_reader[cols[i]]);

            // for debug purposes... below is screenshot of error
            Console.Write(temp + "  " + src_reader[cols[i]] + "\n");
        }

        Console.WriteLine("");

        // point of error
        dstcmd.ExecuteNonQuery();
    }
}
catch(Exception ex)
{
    Console.WriteLine(ex);
}

这是错误截图。

CategoryID 是表的第一列,因此是插入的第一个值。

任何帮助将不胜感激。如果我遗漏了任何信息或有什么不合理的地方,请告诉我。

【问题讨论】:

    标签: c# sql sql-server ado.net oledb


    【解决方案1】:

    尝试更改此部分:

    // generating the insert string below
     string insert = "INSERT INTO Categories VALUES (";
     for(int i = 0; i < cols.Length; i++)
     {
         string coma = ", ";
         if (i == cols.Length - 1)
         coma = " )";
    
         insert += "@" + cols[i] + coma;
     }
    

    // generating the insert string below
     string insert = "INSERT INTO Categories VALUES (";
     for(int i = 0; i < cols.Length; i++)
     {
         string coma = ", ";
         if (i == cols.Length - 1)
         coma = " )";
    
         insert += "?" + coma;
     }
    

    您不需要在VALUES 中使用参数名称,只需使用? 占位符即可。但是,请确保添加参数时的顺序与表中列的顺序相匹配。

    另外,最好在 INSERT 子句中明确指定列列表,例如:

    string insert = "INSERT INTO Categories (Col1, Col2, Col3, etc.)  VALUES (";
    

    看看你是否想让列名列表也动态生成。但我建议先让它适用于静态列列表,然后将其转换为动态版本。

    此外,如果您没有为 INSERT 指定列名列表,您将需要为所有列指定值。

    【讨论】:

    • 此外,SqlClient 是 .NET 应用程序在 ADO.NET 中访问 SQL Server 的首选 API。它将比 ODBC 或 OLE DB 执行得更好。
    • @andrews 非常感谢您的回答。这行得通。我挣扎了好几个小时。 :)
    • @Shrey 不客气!很高兴它起作用了。如果您接受答案,将不胜感激:)。
    • @DanGuzman 是的,但是我正在编写的应用程序,它需要处理所有类型的 OleDb 数据库,所以它可以是 SqlServer 或 MySql 或 Access 数据库。这就是我使用 OleDb 连接的原因。 :)
    • @Shrey,考虑使用DbProviderFactory 或类似的工厂模式,并使用ADO.NET IDb* 接口进行数据访问。这将允许您为底层 DBMS 使用最佳提供程序/驱动程序,它可以是除 SQL Server 或其他仅具有 OLE DB 或 ODBC 的 DBMS 产品的 .NET 提供程序。
    猜你喜欢
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    相关资源
    最近更新 更多