2

我目前在 Visual Studio 中使用 C# 并且正在使用访问数据库。当从列表框中选择客户时,我试图从数据库中取回数据。当 sql 被硬编码时,这非常有效,例如

command.CommandText = "SELECT * FROM Customers WHERE CustomerID = 2 ";

但是,当我尝试使用字符串变量来存储选定的用户 ID 时,我在

"OleDbDataReader reader = command.ExecuteReader();".

我使用消息框来确认 s2 变量在选择时包含正确的 ID,因此我不确定问题所在。

有谁知道这个问题的解决方案?

    private void lst_disp_SelectedIndexChanged(object sender, EventArgs e)
    {
        String s = (String)lst_disp.SelectedItem; // the s string contains the selected customers ID + name,
        string s2 = s.Split(' ').FirstOrDefault(); // by spliting we can gain only the ID and store in s2
        MessageBox.Show("Selected " + s2);
        showCust(s2);
    }

    private void showCust(string s2)
    {
        dataGridView1.AllowUserToAddRows = false;

        dataGridView1.Columns.Add("CustomerID", "Customer ID");
        dataGridView1.Columns.Add("CustomerName", "Customer Name");
        dataGridView1.Columns.Add("Description", "Description");
        dataGridView1.Columns.Add("Email", "Email");
        dataGridView1.Columns.Add("Telephone", "Telephone");
        dataGridView1.Columns.Add("DeliveryAddress", "Delivery Address");
        dataGridView1.Columns.Add("Notes", "Notes");

        OleDbConnection connect = new OleDbConnection();
        connect.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:\Uni\Year 3\Final Year Project\independent foods\coding\showCustomers\Database1.accdb;Persist Security Info=False";
        connect.Open();
        MessageBox.Show("Connection open");

        OleDbCommand command = new OleDbCommand();
        command.Connection = connect;

        MessageBox.Show("SELECT * FROM Customers WHERE CustomerID = '" + s2 + "' ");
        command.CommandText = "SELECT * FROM Customers WHERE CustomerID = '" + s2 + "' ";


        try
        {
            OleDbDataReader reader = command.ExecuteReader();

            while (reader.Read())
            {

                dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells["CustomerID"].Value = reader[0].ToString();
                dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells["CustomerName"].Value = reader[1].ToString();
                dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells["Description"].Value = reader[2].ToString();
                dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells["Email"].Value = reader[3].ToString();
                dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells["Telephone"].Value = reader[4].ToString();
                dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells["DeliveryAddress"].Value = reader[5].ToString();
                dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells["Notes"].Value = reader[6].ToString();
            }
        }
        catch(Exception e)
        {
    MessageBox.Show("The File  cann't be read. Error: " + e.Message);
        }
    }
4

3 回答 3

3

删除单引号,看起来该列是一个 int。

command.CommandText = "SELECT * FROM Customers WHERE CustomerID = " + s2;

此外,您应该参数化它以更好地防止 sql 注入(类似这样):

SqlParameter custID = new SqlParameter("custID",s2);
command.Parameters.Add(custID);
command.CommandText = "SELECT * FROM Customers WHERE CustomerID = @custID";

看看这篇文章,或者做一个简单的搜索参数化你的查询。

于 2013-03-05T17:11:00.353 回答
-1

一个简单的谷歌展示如何使用参数MSDN

于 2013-03-05T17:08:57.310 回答
-1

这是因为当你这样参数化它时,结果查询是不一样的。

在您的原始硬编码声明中,您有

SELECT * FROM Customers WHERE CustomerID = 2

在你的新声明中,你最终得到

SELECT * FROM Customers WHERE CustomerID = '2'

CustomerID是一个 int,但您试图将它与第二个示例中的字符串进行比较。

试试这行代码:

        command.CommandText = "SELECT * FROM Customers WHERE CustomerID = " + s2;

我删除了单引号。

编辑 Mike C 提出了一个非常好的观点。您应该对其进行参数化,以获得更高的可靠性。

于 2013-03-05T17:11:44.910 回答