左外连接代码的不明确列名

Posted

技术标签:

【中文标题】左外连接代码的不明确列名【英文标题】:Ambiguous column name for left outer join code 【发布时间】:2014-02-08 17:14:21 【问题描述】:

我在表单上有一个 datagridview 来显示处方表数据。我想将处方表中的 paymentID 字段更改为付款表中存在的金额字段。但是在我的选择语句中编写了左外连接代码后,当我调试时,我在第二张图片中得到了错误。

付款和处方表

不明确的列名

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Configuration;

namespace GRP_02_03_SACP

    public partial class prescription : Form
    

        // Data Table to store employee data
        DataTable Prescription = new DataTable();

        // Keeps track of which row in Gridview
        // is selected
        DataGridViewRow currentRow = null;

        SqlDataAdapter PrescriptionAdapter;

        public prescription()
        
            InitializeComponent();
        

        private void btnSubmit_Click(object sender, EventArgs e)
        
            if (btnSubmit.Text == "Clear")
            
                btnSubmit.Text = "Submit";
                ClearTextBoxes();
                txtmedicationID.Focus();
            
            else
            
                btnSubmit.Text = "Clear";
                int result = AddPrescriptionRecord();
                if (result > 0)
                    MessageBox.Show("Insert Successful");
                else
                    MessageBox.Show("Insert Fail");

            
        

        private void ClearTextBoxes()
        
            txtmedicationID.Clear();
            txtappointmentID.Clear();
        

        private int AddPrescriptionRecord()
        
            int result = 0;
            // TO DO: Codes to insert customer record
            //retrieve connection information info from App.config
            string strConnectionString = ConfigurationManager.ConnectionStrings["sacpConnection"].ConnectionString;
            //STEP 1: Create connection
            SqlConnection myConnect = new SqlConnection(strConnectionString);
            //STEP 2: Create command
            String strCommandText = "INSERT Prescription(medicationID, appointmentID) "
                + " VALUES (@NewmedicationID, @NewappointmentID)";

            SqlCommand updateCmd = new SqlCommand(strCommandText, myConnect);

            updateCmd.Parameters.AddWithValue("@NewmedicationID", txtmedicationID.Text);
            updateCmd.Parameters.AddWithValue("@NewappointmentID", txtappointmentID.Text);
            //updateCmd.Parameters["@clientid"].Direction = ParameterDirection.Output; 
            // STEP 3 open connection and retrieve data by calling ExecuteReader
            myConnect.Open();
            // STEP 4: execute command
            // indicates number of record updated.
            result = updateCmd.ExecuteNonQuery();

            // STEP 5: Close
            myConnect.Close();
            return result;

        

        private void prescription_Load(object sender, EventArgs e)
        
            LoadPrescriptionRecords();
        

        private void LoadPrescriptionRecords()
        

            //retrieve connection information info from App.config
            string strConnectionString = ConfigurationManager.ConnectionStrings["sacpConnection"].ConnectionString;
            //STEP 1: Create connection
            SqlConnection myConnect = new SqlConnection(strConnectionString);
            //STEP 2: Create command
            string strCommandText = "SELECT prescriptionID, medicationID, appointmentID, c.amount  FROM PRESCRIPTION AS a left outer join payment as c on a.paymentid = c.paymentId";

            PrescriptionAdapter = new SqlDataAdapter(strCommandText, myConnect);

            //command builder generates Select, update, delete and insert SQL
            // statements for MedicalCentreAdapter
            SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(PrescriptionAdapter);
            // Empty Employee Table first
            Prescription.Clear();
            // Fill Employee Table with data retrieved by data adapter
            // using SELECT statement
            PrescriptionAdapter.Fill(Prescription);

            // if there are records, bind to Grid view & display
            if (Prescription.Rows.Count > 0)
                grdPrescription.DataSource = Prescription;
        

        private void btnUpdate_Click(object sender, EventArgs e)
        
            int modifiedRows = 0;
            // Get changes
            DataTable UpdatedTable = Prescription.GetChanges();
            if (UpdatedTable != null)
            
                // there are changes
                // Write modified data to database 
                modifiedRows = PrescriptionAdapter.Update(UpdatedTable);
                // accept changes
                Prescription.AcceptChanges();
            
            else
                MessageBox.Show("there are no changes to update");

            if (modifiedRows > 0)
            
                MessageBox.Show("There are " + modifiedRows + " records updated");
                LoadPrescriptionRecords();
            
        
    

【问题讨论】:

【参考方案1】:

查询应该是这样的:

string strCommandText = "SELECT prescriptionID, medicationID, a.appointmentID,
                         c.amount  FROM PRESCRIPTION AS a
                         left outer join payment as c
                         on a.paymentid = c.paymentId";

由于两个表中都存在appointmentID,因此您需要通过将appointmentID 替换为a.appointmentID 来解决歧义。

【讨论】:

【参考方案2】:

由于不止一个表包含appointmentID 列,因此您需要在选择语句中指定要获取的列

select ... a.appointmentID

select ... c.appointmentID

如果两个表都包含相同的appointmentID 值,那么您选择哪一个都没有关系。由于您做了left outer join,这表明payment 条目不必存在,当c.appointmentID 为空时,您可能会发现a.appointmentID 包含一些值

【讨论】:

您有两个表 PRESCRIPTION AS apayment as c 并且由于两者都包含 appointmentID 列,因此您需要指定表的别名以从中获取appointmentID。如果两个表都包含相同的appointmentID 值,那么没关系,但由于您离开外连接而不是内连接,您可能因此 c 不必存在,您需要决定取哪个值 谢谢我明白了,这意味着如果我把 a.appointmentID 是的,你需要指定选择哪个表【参考方案3】:

在两个表中都找到了名称,始终尝试在连接操作中使用别名作为表名:

Select ... From Table1 t1
LEFT JOIN table2 t2
on t1.Key = t2.FKey

【讨论】:

以上是关于左外连接代码的不明确列名的主要内容,如果未能解决你的问题,请参考以下文章

Linq中的lambda /方法语法中的左外连接[重复]

如何使用 Laravel 进行左外连接?

左外连接和右外连接的区别

Linq to SQL 左外连接不是

3 个表,左外连接,SUM

关于数据库的左外连接 右外连接的意思是啥