【问题标题】:Adding textbox values to an SQL database in c#在 C# 中将文本框值添加到 SQL 数据库
【发布时间】:2018-10-02 07:32:11
【问题描述】:

我正在尝试将文本框中的值添加到 datagridview 中,我之前曾问过这个问题,但我现在遇到了一个不同的错误说

INSERT 语句中的列多于 VALUES 子句中指定的值。 VALUES 子句中的值数必须与 INSERT 语句中指定的列数匹配。

这是导致错误的代码

private void SaveBtn_Click(object sender, EventArgs e)
{
    SqlConnection sc = new SqlConnection();
    SqlCommand com = new SqlCommand();
    sc.ConnectionString = ("Data Source=localhost;Initial Catalog=LoginScreen;Integrated Security=True");
    sc.Open();
    com.Connection = sc; 
    com.CommandText = ("INSERT INTO Stock (Prod_ID, Prod_Name, Prod_Cat, Supplier, Cost, Price_1, Price_2, Price_3) VALUES ('"+ProdID.Text+"''"+ProdName.Text+"'+'"+ProdCat.Text+"'+'"+ProdSup.Text+"'+'"+ProdCost.Text+"'+'"+ProdPrice1.Text+"'+'"+ProdPrice2.Text+"'+'"+ProdPrice3.Text+"');");
    com.ExecuteNonQuery();
    sc.Close();
}

my database

【问题讨论】:

标签: c# sql sql-server winforms


【解决方案1】:

错误的直接原因是查询的“值”部分中省略了逗号(“,”)。 你应该这样说的

VALUES ('"+ProdID.Text+"', '"+ProdName.Text+", '+'"+ProdCat.Text+", '+'"+ProdSup.Text+...

而不是

VALUES ('"+ProdID.Text+"''"+ProdName.Text+"'+'"+ProdCat.Text+"'+'"+ProdSup.Text+...

您的代码也容易受到所谓的 SQL 注入攻击(想象一下有人将 '" 从 Stock 中删除 --' 到 ProdID.Text:执行将导致 Stock 表 清关)

推荐的方式如下所示:

using(SqlConnection sc = new SqlConnection()) {
  sc.ConnectionString = "Data Source=localhost;Initial Catalog=LoginScreen;Integrated Security=True";
  sc.Open();

  using (SqlCommand com = sc.CreateCommand()) {
    com.CommandText =
      "insert into Stock(\n" + 
      "  Prod_Id,\n" + 
      "  Prod_Name,\n" +
      "  Prod_Cat,\n" +
      "  Supplier,\n" +
      "  Cost,\n" +
      "  Price_1,\n" +
      "  Price_2,\n" +
      "  Price_3)\n" +
      "values(\n" +
      "  @prm_Prod_Id,\n" +
      "  @prm_Prod_Name,\n" +
      "  @prm_Prod_Cat,\n" +
      "  @prm_Supplier,\n" +
      "  @prm_Cost,\n" +
      "  @prm_Price_1,\n" +
      "  @prm_Price_2,\n" +
      "  @prm_Price_3)";

    //TODO: Change my arbitrary "80" to actual Stock fields' sizes! 
    com.Parameters.Add("@prm_Prod_Id", SqlDbType.VarChar, 80).Value = ProdID.Text;
    com.Parameters.Add("@prm_Prod_Name", SqlDbType.VarChar, 80).Value = ProdName.Text;
    com.Parameters.Add("@prm_Prod_Cat", SqlDbType.VarChar, 80).Value = ProdCat.Text;
    com.Parameters.Add("@prm_Supplier", SqlDbType.VarChar, 80).Value = ProdSub.Text;
    com.Parameters.Add("@prm_Cost", SqlDbType.VarChar, 80).Value = ProdCost.Text;
    com.Parameters.Add("@prm_Price_1", SqlDbType.VarChar, 80).Value = ProdPrice1.Text;
    com.Parameters.Add("@prm_Price_2", SqlDbType.VarChar, 80).Value = ProdPrice2.Text;
    com.Parameters.Add("@prm_Price_3", SqlDbType.VarChar, 80).Value = ProdPrice3.Text;

    com.ExecuteNonQuery();
  }
}

【讨论】:

    【解决方案2】:

    您在 sql 的值部分中缺少逗号。当你在做这样的事情(一个字符串的大连接)时,你应该知道两件事。首先,测试的一个好方法是写出到控制台、消息框、分机。您通常会立即看到错误。接下来要知道的是,如果您要插入数据库,请不要这样做。使用参数化查询。 -> How do parameterized queries help against SQL injection?

    com.CommandText = ("INSERT INTO Stock (Prod_ID, Prod_Name, Prod_Cat, Supplier, Cost, Price_1, Price_2, Price_3) VALUES ('"+ProdID.Text+"''"+ProdName.Text+"'+'"+ProdCat.Text+"'+'"+ProdSup.Text+"'+'"+ProdCost.Text+"'+'"+ProdPrice1.Text+"'+'"+ProdPrice2.Text+"'+'"+ProdPrice3.Text+"');");
    

    应该是这样的

       com.CommandText = (@"INSERT INTO Stock (Prod_ID, Prod_Name, Prod_Cat, Supplier, Cost, Price_1, Price_2, Price_3) VALUES ('"+ProdID.Text+"','"+ProdName.Text+"','"+ProdCat.Text+"','"+ProdSup.Text+"','"+ProdCost.Text+"','"+ProdPrice1.Text+"','"+ProdPrice2.Text+"','"+ProdPrice3.Text+"');"));
    

    【讨论】:

    • @ReeceCottam 请确保您阅读了我上次关于 SQL 注入的编辑。从用户那里获取输入并使用连接构建查询是非常糟糕的。非常非常糟糕。我的意思是你能做的最糟糕的事情。
    【解决方案3】:

    如果没有选中任何框,则表单中的复选框值或以逗号分隔的值列表不会产生任何结果。您可能做的最糟糕的事情是将此列表存储在单个记录中。这将导致无法使用的数据。

    相反,您不仅希望更改您的代码,还希望更改您的数据库设计,以便您对每个选中的框都有一条记录。请记住考虑没有选中框的情况。

    【讨论】:

    • +1,这里有很多问题。 SQL 注入问题,从 ui 访问数据库,没有 using 语句。希望这只是一个测试/学习应用程序。
    【解决方案4】:

    试试:

    com.CommandText = ("INSERT INTO Stock (Prod_ID, Prod_Name, Prod_Cat, Supplier, Cost, Price_1, Price_2, Price_3) VALUES ('"+ProdID.Text+"','"+ProdName.Text+"','"+ProdCat.Text+"','"+ProdSup.Text+"','"+ProdCost.Text+"','"+ProdPrice1.Text+"','"+ProdPrice2.Text+"','"+ProdPrice3.Text+"');");
    

    【讨论】:

    • 这是一个选项,但它容易受到 SQL 注入的攻击。最好使用准备好的语句。
    • @StefanM 但这就是他想要的!
    【解决方案5】:

    你应该替换

     ('"+ProdID.Text+"''"+ProdName.Text+"'+'"+ProdCat.Text+"'+'"+ProdSup.Text+"'+'"+ProdCost.Text+"'+'"+ProdPrice1.Text+"'+'"+ProdPrice2.Text+"'+'"+ProdPrice3.Text+"');");`
    

    ('"+ProdID.Text+"','"+ProdName.Text+"','"+ProdCat.Text+"','"+ProdSup.Text+"','"+ProdCost.Text+"','"+ProdPrice1.Text+"','"+ProdPrice2.Text+"','"+ProdPrice3.Text+"');");`
    

    VALUES 部分每列需要逗号)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多