为什么 SQL INSERT INTO SELECT 语句重复行?

Why SQL INSERT INTO SELECT statement duplicates the rows?

我正在使用 C# windows 应用程序,我创建了这个存储过程来保存旧结果和新结果,但是该过程将每一行重复 2 次,为旧结果保存一行,为新结果保存一行,我只需要为每个结果插入一行,这只是旧结果

这是存储过程代码:

CREATE proc [dbo].[UPDATED_RESULTS]
@ORDER_ID int,
@TESTID int,
@APPROVED_BY varchar(50),
@APPROVED_DATE datetime, 
@RESULT_NUMBER varchar(50),
@MACHINE_ID int,
@patient_no int,
@custid int,
@CORRECTED_BY varchar(50),
@CORRECTED_DATE datetime,
@messageid int
AS
INSERT INTO [dbo].[LAB_RESULTS_UPDATED]
           ([ORDER_ID]
           ,[TESTID]
           ,[APPROVED_BY]
           ,[APPROVED_DATE]
           ,[RESULT_NUMBER]
           ,[machine_id]
           ,[patient_no]
           ,[custid]
           ,[CORRECTED_BY]
           ,[CORRECTED_DATE]
           ,[messageid])
     SELECT DISTINCT ORDER_ID,TESTID ,APPROVED_BY ,APPROVED_DATE ,RESULT_NUMBER ,MACHINE_ID ,patient_no,custid,@CORRECTED_BY,@CORRECTED_DATE,@messageid
     FROM LAB_RESULTS 
     WHERE ORDER_ID = @ORDER_ID 
     AND RESULT_NUMBER IS NOT NULL 
     AND RESULT_NUMBER != '' 
     EXCEPT SELECT [ORDER_ID],[TESTID],[APPROVED_BY],[APPROVED_DATE],[RESULT_NUMBER],[machine_id],[patient_no],[custid],[CORRECTED_BY]
           ,[CORRECTED_DATE]
           ,[messageid]
     FROM LAB_RESULTS_UPDATED

这是单击保存按钮时 C# 应用程序中的 class 代码:

for (int i = 0; i < dgvResult.Rows.Count; i++)
{
    if (!String.IsNullOrEmpty(dgvResult.Rows[i].Cells[3].Value.ToString()))
    {
        result.UPDATED_RESULTS(
            Convert.ToInt32(txtOrder.Text),
            Convert.ToInt32(dgvResult.Rows[i].Cells[0].Value),
            txtApprovedby.Text,
            DateTime.Parse(dateTimeApprove.Value.ToString()),
            dgvResult.Rows[i].Cells[3].Value.ToString(),
            Convert.ToInt32(dgvResult.Rows[i].Cells[4].Value.ToString()),
            Convert.ToInt32(txtMRN.Text),
            Convert.ToInt32(textCustId.Text),
            txtApprovedby.Text,
            DateTime.Parse(dateTimeApprove.Value.ToString()),1);
        result.APPROVE_ALLLAB_RESULTS_NEW(
            Convert.ToInt32(txtOrder.Text),
            txtApprovedby.Text,
            DateTime.Parse(dateTimeApprove.Value.ToString()),
            Convert.ToInt32(dgvResult.Rows[i].Cells[0].Value),
            dgvResult.Rows[i].Cells[3].Value.ToString(),
            "No Report",
            Convert.ToInt32(dgvResult.Rows[i].Cells[4].Value.ToString()),
            Convert.ToInt32(txtMRN.Text),
            Convert.ToInt32(textCustId.Text),
            Convert.ToInt32(txtUpdateCount),
            txtExamUser.Text,
            DateTime.Parse(DateTimeExamined.Value.ToString()),6);
    }
}

如何更新存储过程以仅保存旧结果的一行?

我相信这就是你想要的:

INSERT INTO [dbo].[LAB_RESULTS_UPDATED]
           ([ORDER_ID]
           ,[TESTID]
           ,[APPROVED_BY]
           ,[APPROVED_DATE]
           ,[RESULT_NUMBER]
           ,[machine_id]
           ,[patient_no]
           ,[custid]
           ,[CORRECTED_BY]
           ,[CORRECTED_DATE]
           ,[messageid])
     SELECT DISTINCT ORDER_ID,TESTID ,APPROVED_BY ,APPROVED_DATE ,RESULT_NUMBER ,MACHINE_ID ,patient_no,custid,@CORRECTED_BY,@CORRECTED_DATE,@messageid
     FROM LAB_RESULTS 
     LEFT JOIN (SELECT [ORDER_ID],[TESTID] FROM LAB_RESULTS_UPDATED) EX 
       ON LAB_RESULTS.ORDER_ID = EX.ORDER_ID AND LAB_RESULTS.TESTID = EX.TESTID
     WHERE ORDER_ID = @ORDER_ID 
     AND RESULT_NUMBER IS NOT NULL 
     AND RESULT_NUMBER != '' 
     AND EX.ORDER_ID IS NULL 

我在这里进行左连接,并且只使用空项——这与“NOT EXISTS”相同,但它允许您在两个字段上进行连接

注意:这假设只有 order_id 和 testid 的任意组合之一(这将是标准的关系设计)

NOT EXIST 解决了重复项,我在 where 语句中添加了这一行:

AND NOT EXISTS (SELECT TESTID FROM [LAB_RESULTS_UPDATED] WHERE ORDER_ID = @ORDER_ID)

和 select 首先是不同的 TESTID,而不是 ORDER_ID 并删除了 EXCEPT SELECT

这是完整的存储过程:

ALTER proc [dbo].[UPDATED_RESULTS]
@ORDER_ID int,
@TESTID int,
@APPROVED_BY varchar(50),
@APPROVED_DATE datetime, 
@RESULT_NUMBER varchar(50),
@MACHINE_ID int,
@patient_no int,
@custid int,
@CORRECTED_BY varchar(50),
@CORRECTED_DATE datetime,
@messageid int
AS
INSERT INTO [dbo].[LAB_RESULTS_UPDATED]
           ([TESTID]
           ,[ORDER_ID]
           ,[APPROVED_BY]
           ,[APPROVED_DATE]
           ,[RESULT_NUMBER]
           ,[machine_id]
           ,[patient_no]
           ,[custid]
           ,[CORRECTED_BY]
           ,[CORRECTED_DATE]
           ,[messageid])
     SELECT DISTINCT TESTID , ORDER_ID ,APPROVED_BY ,APPROVED_DATE ,RESULT_NUMBER ,MACHINE_ID ,patient_no,custid,@CORRECTED_BY,@CORRECTED_DATE,@messageid
     FROM LAB_RESULTS 
     WHERE ORDER_ID = @ORDER_ID 
     AND RESULT_NUMBER IS NOT NULL 
     AND RESULT_NUMBER != '' 
     AND NOT EXISTS (SELECT TESTID FROM [LAB_RESULTS_UPDATED] WHERE ORDER_ID = @ORDER_ID)