【问题标题】:Error when trying to update a field in datagridview which is outer join尝试更新外部联接的 datagridview 中的字段时出错
【发布时间】:2014-01-29 14:57:12
【问题描述】:

我有两个表,称为约会和患者,它们彼此有关系。我在约会表单上使用外连接来显示患者表的 pFirstName 字段而不是患者 ID。现在我想尝试在约会表格中更新 pFirstName 等,将亚当名称更改为其他名称并单击更新按钮,但它给了我无效的列名“pFirstName”。只有这个字段不能工作,因为它是外连接。 aStatus、aDate 等其他字段工作正常。以前我使用 commandbuilder 来生成更新,所以不能用于外部连接进行更新,所以我必须切换到手动输入更新查询的这种方法。有什么帮助???

预约表

预约和病床

列 'patientid' 不属于表,遵循 @Ralf 的建议

private void LoadAppointmentRecords()
        {

            //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 appointmentID, aDate, aTime, aStatus, aContact, aHeight, aWeight, pat.pFirstName, cen.mcCentre, nur.nFirstName FROM APPOINTMENT AS app";
            strCommandText += " LEFT OUTER JOIN PATIENT as pat on app.patientid = pat.patientid";
            strCommandText += " LEFT OUTER JOIN MEDICALCENTRE as cen on app.mcid = cen.mcid";
            strCommandText += " LEFT OUTER JOIN NURSE as nur on app.nurseid = nur.nurseid";

            /*
            string strCommandText = "SELECT appointmentID, aDate, aTime, aStatus, aContact, aHeight, aWeight, p.pFirstName , m.mcCentre , n.nFirstName FROM APPOINTMENT";
            strCommandText += " AS a LEFT OUTER JOIN Nurse AS n ON a.nurseID = n.NurseID";
            strCommandText += " Left outer join Patient as p on a.patientid = p.patientId";
            strCommandText += " left outer join medicalcentre as m on a.mcID = m.mcid";
            */

            AppointmentAdapter = new SqlDataAdapter(strCommandText, myConnect);

            //command builder generates Select, update, delete and insert SQL
            // statements for MedicalCentreAdapter

            // Empty Employee Table first
            Appointment.Clear();
            // Fill Employee Table with data retrieved by data adapter
            // using SELECT statement
            AppointmentAdapter.Fill(Appointment);

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

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            string strQuery = string.Empty;
            string strQuery2 = string.Empty;
            DataTable dtChanges;
            //
            // Get the Updated DataTable back from the DataGridView
            DataTable dtAppointment = (DataTable)grdApp.DataSource;
            //
            // Get the Connection string from App.config.
            string strConn = ConfigurationManager.ConnectionStrings["SACPConnection"].ConnectionString;
            SqlConnection objConn = new SqlConnection(strConn);
            SqlCommand objCmd = new SqlCommand();
            //
            // Get the Modified Rows by filtering on their RowState
            dtChanges = dtAppointment.GetChanges(DataRowState.Modified);
            if (dtChanges != null)
            {
                //
                // Form the UPDATE Query to Update the Rows.
                objConn.Open();
                objCmd.Connection = objConn;
                for (int i = 0; i < dtChanges.Rows.Count; i++)
                {
                    strQuery = "UPDATE APPOINTMENT SET ";
                    strQuery += "aDate = '" + dtChanges.Rows[i]["aDate"].ToString() + "',";
                    strQuery += "pFirstName = '" + dtChanges.Rows[i]["pFirstName"].ToString() + "',";
                    strQuery += "aStatus = '" + dtChanges.Rows[i]["aStatus"].ToString() + "'";
                    strQuery += "WHERE appointmentID = '" + dtChanges.Rows[i]["appointmentID"].ToString() + "'";

                    //strQuery2 = "UPDATE APPOINTMENT SET ";
                    //strQuery2 += "pFirstName = '" + dtChanges.Rows[i]["pFirstName"].ToString() + "'";
                    //strQuery2 += "WHERE appointmentID = '" + dtChanges.Rows[i]["appointmentID"].ToString() + "'";

                    //
                    // Execute the Update Query.
                    objCmd.CommandText = strQuery;
                    objCmd.ExecuteNonQuery();
                }
                objConn.Close();
                dtChanges = null;
                MessageBox.Show("Record Updated");
            }

            else
            {
                MessageBox.Show("No update to change");
            }                   
        }

尝试遵循@Ralf 的建议 我删除了每行 using (var objCmd = objConn.CreateCommand()) 中的 var,因为它给了我一个名为 'objCmd' 的局部变量不能在这个范围,因为它会给'objCmd'赋予不同的含义,'objCmd'已经在'父或当前'范围中用于表示其他东西。但是现在我有这个错误,列'patientid'不属于表,无论我尝试更新什么。

    private void btnUpdate_Click(object sender, EventArgs e)
{
    string strQuery = string.Empty;
    string strQuery2 = string.Empty;
    DataTable dtChanges;
    //
    // Get the Updated DataTable back from the DataGridView
    DataTable dtAppointment = (DataTable)grdApp.DataSource;
    //
    // Get the Connection string from App.config.
    string strConn = ConfigurationManager.ConnectionStrings["SACPConnection"].ConnectionString;
    SqlConnection objConn = new SqlConnection(strConn);
    SqlCommand objCmd = new SqlCommand();
    //
    // Get the Modified Rows by filtering on their RowState
    dtChanges = dtAppointment.GetChanges(DataRowState.Modified);
    if (dtChanges != null)
    {
        using (objConn = new SqlConnection(strConn))
        {
            objConn.Open();
            for (int i = 0; i < dtChanges.Rows.Count; i++)
            {
                long? patientid = (long?)dtChanges.Rows[i]["patientid"]; // you must return the id in your sql to distinguish a needed INSERT from an UPDATE

                if (!patientid.HasValue)
                {
                    using (objCmd = objConn.CreateCommand())
                    {
                        objCmd.CommandText = "INSERT INTO Patient(pFirstName) VALUES(@pFirstName); SELECT SCOPE_IDENTITY();";
                        objCmd.Parameters.AddWithValue("@pFirstName", (string)dtChanges.Rows[i]["pFirstName"]);
                        patientid = (long)objCmd.ExecuteScalar();
                    }
                }
                else
                {
                    using (objCmd = objConn.CreateCommand())
                    {
                        objCmd.CommandText = "UPDATE Patient SET pFirstName = @pFirstName WHERE patientid = @patientid";
                        objCmd.Parameters.AddWithValue("@pFirstName", (string)dtChanges.Rows[i]["pFirstName"]);
                        objCmd.Parameters.AddWithValue("@patientid", patientid);
                        objCmd.ExecuteNonQuery();
                    }
                }

                using (objCmd = objConn.CreateCommand())
                {
                    objCmd.CommandText = "UPDATE APPOINTMENT SET aDate = @date, aStatus = @status, patientid = @patientid WHERE appointmentID = @appointmentID";
                    objCmd.Parameters.AddWithValue("@date", (DateTime)dtChanges.Rows[i]["aDate"]);
                    objCmd.Parameters.AddWithValue("@status", (string)dtChanges.Rows[i]["aStatus"]);
                    objCmd.Parameters.AddWithValue("@patientid", patientid);
                    objCmd.Parameters.AddWithValue("@appointmentID", (long)dtChanges.Rows[i]["appointmentID"]);
                    objCmd.ExecuteNonQuery();
                }
            }

            objConn.Close();
            dtChanges = null;
            MessageBox.Show("Record Updated");
        }
    }

    else
    {
        MessageBox.Show("No update to change");
    }            
}

【问题讨论】:

  • 您正在更新 APPOINTMENT,但 pFirstName 不是 APPOINTMENT 的一部分。如果 pFirstName 列已更改,您需要在 PATIENT 上更新、插入甚至删除。首先插入或更新 Patient 检索患者 ID,然后使用检索到的患者 ID 更新 APPOINTMENT。
  • 嗯,不知道怎么做。呃,现在我在更新按钮上有一个 strQuery,我需要创建另一个 strQuery2 来更新患者并检索患者 ID 是吗? @Ralf
  • 是的。仅当之前没有 Patient 并且您需要在 Patient Table 上执行 INSERT 时才需要检索 patientid。在另一种情况下,当需要更新时,您应该已经拥有它。只需在初始选择时也获取患者 ID。
  • 我更新了我的帖子。是这样吗?在预约表 pFirstName 之后也更新患者表 pFirstName?但我不知道如何检索患者 ID .. @Ralf
  • 不,您仍然尝试在约会中更新 pFirstName 约会没有 pFirstName 它只有一个可能会更新的患者 ID,如果创建新患者并将其附加到约会顶部。而且您应该在预约前更新患者,因为患者可能是新的。我尝试了一点猜测并把它放在一个答案中。

标签: c# windows datagridview sql-update outer-join


【解决方案1】:

我猜到了您的 DataTable 中的数据类型并清理了代码(尤其是使用 Usings 和 Parameteres)。您还需要在选择语句中返回患者 ID 以使其以这种方式工作。

if (dtChanges != null)
{
    using(var objConn = new SqlConnection(strConn))
    {
        objConn.Open();
        for (int i = 0; i < dtChanges.Rows.Count; i++)
        {
            long? patientid = (long?)dtChanges.Rows[i]["patientid"]; // you must return the id in your sql to distinguish a needed INSERT from an UPDATE

            if (!patientid.HasValue) 
            {
                using (var objCmd = objConn.CreateCommand())
                {
                    objCmd.CommandText = "INSERT INTO Patient(pFirstName) VALUES(@pFirstName); SELECT SCOPE_IDENTITY();";
                    objCmd.Parameters.AddWithValue("@pFirstName", (string)dtChanges.Rows[i]["pFirstName"]);
                    patientid = (long)objCmd.ExecuteScalar();
                }                            
            }
            else
            {
                using (var objCmd = objConn.CreateCommand())
                {
                    objCmd.CommandText = "UPDATE Patient SET pFirstName = @pFirstName WHERE patientid = @patientid";
                    objCmd.Parameters.AddWithValue("@pFirstName", (string)dtChanges.Rows[i]["pFirstName"]);
                    objCmd.Parameters.AddWithValue("@patientid", patientid);
                    objCmd.ExecuteNonQuery();
                }
            }

            using (var objCmd = objConn.CreateCommand())
            {
                objCmd.CommandText = "UPDATE APPOINTMENT SET aDate = @date, aStatus = @status, patientid = @patientid WHERE appointmentID = @appointmentID";
                objCmd.Parameters.AddWithValue("@date", (DateTime)dtChanges.Rows[i]["aDate"]);
                objCmd.Parameters.AddWithValue("@status", (string)dtChanges.Rows[i]["aStatus"]);
                objCmd.Parameters.AddWithValue("@patientid", patientid);
                objCmd.Parameters.AddWithValue("@appointmentID", (long)dtChanges.Rows[i]["appointmentID"]);
                objCmd.ExecuteNonQuery();
            }
       }
  }

}

【讨论】:

  • Omg 无法理解,无论如何我已经更新了我的代码并在上面添加了一张图片,有什么问题吗?我收到错误@Ralf
  • 不要删除 var。删除代码中预定义的 objCmd 对象。它没有使用。命令在 using 块中定义和初始化。
  • 并且要解决屏幕截图中显示的问题,您需要更改 LoadAppointmentRecords 方法中的 select 语句。它必须返回 patientid。
猜你喜欢
  • 1970-01-01
  • 2021-04-05
  • 2018-05-16
  • 2019-08-27
  • 2015-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多