You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用三表连接SELECT查询加载数据至DataGridView与TextBox并解决歧义列错误

解决"ambiguous column name PO_No"错误并正确加载多表数据到DataGridView和TextBox

错误原因分析

你遇到的ambiguous column name PO_No错误,核心问题出在SQL查询的WHERE子句里:PO_No这个字段同时存在于TBL_PO和TBL_PO_Cart两个表中,数据库无法判断你要过滤的是哪个表的PO编号,因此抛出了字段歧义的错误。

分步解决方案

1. 修复SQL语句的字段歧义

给WHERE子句里的PO_No加上表别名,明确指定是主采购单表TBL_PO(别名p)的字段:

SELECT p.PO_No,p.Supplier_ID,p.Date,p.RequiredDate,p.GrandTotal,b.BookName,c.ISBN_No,c.OrderQuantity,c.UnitPrice,c.Total 
FROM TBL_PO_Cart AS c 
INNER JOIN TBL_Book AS b ON c.ISBN_No = b.ISBN_No 
INNER JOIN TBL_PO AS p ON c.PO_No=p.PO_No 
WHERE p.PO_No=@PO_No -- 改用参数化查询,避免SQL注入

2. 替换字符串拼接为参数化查询(关键优化!)

你当前直接把cmbPO.Text拼进SQL的写法存在严重的SQL注入风险,必须改成参数化查询,确保代码安全。

3. 简化数据加载逻辑(移除冗余操作)

你同时用DataReader和DataAdapter重复读取数据,完全没必要。可以只通过DataSet完成所有数据的加载和赋值,逻辑更简洁。

修改后的完整代码

public void loadPOCarttable() 
{
    DynamicConnection con = new DynamicConnection();
    try 
    {
        // 修复SQL歧义+参数化查询
        con.sqlquery(@"SELECT p.PO_No,p.Supplier_ID,p.Date,p.RequiredDate,p.GrandTotal,b.BookName,c.ISBN_No,c.OrderQuantity,c.UnitPrice,c.Total 
                       FROM TBL_PO_Cart AS c 
                       INNER JOIN TBL_Book AS b ON c.ISBN_No = b.ISBN_No 
                       INNER JOIN TBL_PO AS p ON c.PO_No=p.PO_No 
                       WHERE p.PO_No=@PO_No");
        // 添加参数,避免SQL注入
        con.cmd.Parameters.AddWithValue("@PO_No", cmbPO.Text);
        
        con.mysqlconnection();
        DataSet ds = new DataSet();
        SqlDataAdapter da = new SqlDataAdapter(con.cmd);
        da.Fill(ds);
        
        // 清空并填充DataGridView
        this.dataGridView1.Rows.Clear();
        foreach (DataRow dr in ds.Tables[0].Rows)
        {
            DataGridViewRow row = (DataGridViewRow)dataGridView1.Rows[0].Clone();
            row.Cells[0].Value = dr["BookName"].ToString();
            row.Cells[1].Value = dr["ISBN_No"].ToString();
            row.Cells[2].Value = dr["OrderQuantity"].ToString();
            row.Cells[3].Value = dr["UnitPrice"].ToString();
            row.Cells[4].Value = dr["Total"].ToString();
            dataGridView1.Rows.Add(row);
        }
        
        // 填充TextBox(按PO_No查询的头信息唯一,取第一行即可)
        if (ds.Tables[0].Rows.Count > 0)
        {
            DataRow headerRow = ds.Tables[0].Rows[0];
            txtPONo.Text = headerRow["PO_No"].ToString();
            cmbsupID.Text = headerRow["Supplier_ID"].ToString();
            date1.Text = headerRow["Date"].ToString();
            requireddate.Text = headerRow["RequiredDate"].ToString();
            txtgrandTotal.Text = headerRow["GrandTotal"].ToString();
        }
    } 
    catch (Exception ex) 
    {
        MessageBox.Show("Error Occured: " + ex.Message);
    }
    finally
    {
        // 确保关闭数据库连接,避免资源泄漏
        if(con.conn != null && con.conn.State == ConnectionState.Open)
        {
            con.conn.Close();
        }
    }
}

额外注意事项

  • 确认你的DynamicConnection类中cmd属性是有效的SqlCommand对象,这样才能正常添加参数。
  • 如果PO_No是数值类型(比如int),需要把cmbPO.Text转换成对应类型后再传入参数,避免类型转换错误。
  • 始终在finally块中关闭数据库连接,防止连接池耗尽。

内容的提问来源于stack exchange,提问作者Kith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:19:13