U通过存储过程更新两个表中的值

本文关键字:两个 存储过程 更新 | 更新日期: 2023-09-27 17:58:09

我有两个表,需要通过存储过程更新其中的值。尝试了太多的更新,但有时它只更新第一个表,另一些只更新第二个表,甚至由于不允许重复而失败。此外,当它更新时,表中的WHOLE数据将与新更新的数据相同。在所有这些代码行之后,我现在已经找到了这个错误

无法将值NULL插入表"DatePics"的列"Emp_ID"中;列不允许为null。UPDATE失败。声明已终止

以下是SQL代码:

ALTER procedure [dbo].[UpdateEmp]
    @EmpName nvarchar(100),
    @Nationality nvarchar(30),    
    @Passport nvarchar(20),
    @ContractDate date,
    @HealthDate date
AS
BEGIN 
    set nocount on;
DECLARE @IDs table (ID int )
UPDATE Employee SET 
EmpName=@EmpName, Nationality=@Nationality, Visa=@Visa, Passport=@Passport,
ReceivedDate=@ReceivedDate,IDIssue=@IDIssue, IDExpiry=@IDExpiry, Sponsor=@Sponsor
output inserted.ID into @IDs (ID)
WHERE ID = @ID
UPDATE DatePics SET
FingerDate=@FingerDate, ContractDate=@ContractDate, HealthDate=@HealthDate
where Emp_ID in (select ID from @IDs);
END

在编写了存储过程代码之后,我编写了如下的C#代码:

private void updatebtn_Click(object sender, EventArgs e)
{
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = db.con;
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "UpdateEmp";
        cmd.Parameters.AddWithValue("@EmpName", NameSeartxt.Text);
        cmd.Parameters.AddWithValue("@Nationality", NatSeartxt.Text);            
        cmd.Parameters.AddWithValue("@Passport", PassSeartxt.Text);            
        cmd.Parameters.AddWithValue("@ContractDate", ContractSeartxt.Text);
        cmd.Parameters.AddWithValue("@HealthDate", HealthSeartxt.Text);
        db.con.Open();
        int up = cmd.ExecuteNonQuery();
        if (up > 0)
        {
            MessageBox.Show("Update done ", "DONE !");
            SearNametxt.Text = "";
        }
        else
        {
            MessageBox.Show("Failed to update", "FAIL !");
            SearNametxt.Text = "";
        }
        db.con.Close();
    }

有线索吗?

U通过存储过程更新两个表中的值

我可以看到您的查询有三个问题。1你声明了ID,但在使用它之前没有分配它,所以第一个查询的ID总是NULL,所以这永远不会更新任何行:

DECLARE @ID int 
UPDATE FrstTable SET 
EmpName=@EmpName, Nationality=@Nationality, Passport=@Passport
WHERE ID = @ID

其次,您正在使用SCOPE_IDENTITY来尝试获取已更新的记录的ID。您不能这样做,SCOPE_IDENTITY将返回最后插入的ID,它不受更新的影响。您需要使用OUTPUT来获得更新的ID:

DECLARE @IDs TABLE (ID INT);
UPDATE  FirstTable
OUTPUT inserted.ID INTO @Ids (ID)
SET     EmpName = @EmpName, 
        Nationality = @Nationality, 
        Passport = @Passport;

第三,您的第二个更新语句没有where子句,因此将更新整个表:

UPDATE  ScndTable 
SET     Emp_ID=@ID, ContractDate=@ContractDate, HealthDate=@HealthDate
WHERE   EmpID IN (SELECT ID FROM @Ids);

您的存储过程在我看来很奇怪。我认为第二个UPDATE应该有一个WHERE库,否则它将始终更新整个ScndTable表。set @ID = SCOPE_IDENTITY();在这里似乎是多余的。如果没有相应的Emp_ID,您是否试图执行插入ScndTable?Finnaly显式创建一个事务来更新两个表或不更新任何表。

希望它能有所帮助!

请在执行第一条更新语句之前,指定@ID变量的值。

我认为您正在尝试更新某一行,因此可以传递CSHARP代码中的"id"值。当您使用SCOPE_IDENTITY时,您将获得最后插入的值。尝试从前端传递ID值。