为什么 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)
我正在使用 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)