我没有使用 Lightswitch 的经验,如果其中任何一个不相关,我深表歉意,但是从 SQL 方面来说,您可以用来删除重复项的存储过程是:
CREATE PROCEDURE dbo.DeleteDuplicatesFromT
AS
BEGIN
WITH CTE AS
( SELECT DocName,
DocUser,
DocType,
DocDate,
[RowNumber] = ROW_NUMBER() OVER(PARTITION BY DocName, DocUser, DocType ORDER BY DocDate DESC)
FROM T
)
DELETE CTE
WHERE RowNumber > 1;
END
SQLFiddle 上的示例
然而
我建议在插入阶段之前/期间进行管理,您可以在应用程序代码中执行此操作,并确保仅将唯一记录传递给表,或者再次使用过程来执行插入。要执行后者,您首先需要创建一个TYPE
来处理您的新记录:
CREATE TYPE dbo.TableTypeParameter AS TABLE
( DocName VARCHAR(5),
DocUser VARCHAR(5),
DocType VARCHAR(4),
DocDate DATETIME
);
您可以将其填写在您的客户端代码中(使用 System.Data.DataTable)并将其作为参数传递给您的存储过程:
CREATE PROCEDURE dbo.BulkInsert @NewRecords dbo.TableTypeParameter READONLY
AS
BEGIN
WITH NewRecords AS
( SELECT DocName, DocType, DocUser, DocDate = MAX(DocDate)
FROM @NewRecords
GROUP BY DocName, DocType, DocUser
)
MERGE INTO T
USING NewRecords nr
ON T.DocName = nr.DocName
AND T.DocType = nr.DocType
AND T.DocUser = nr.DocUser
WHEN MATCHED AND nr.DocDate > T.DocDate THEN UPDATE
SET DocDate = nr.DocDate
WHEN NOT MATCHED THEN INSERT (DocName, DocUser, DocType, DocDate)
VALUES (nr.DocName, nr.DocUser, nr.DocType, nr.DocDate);
END;
编辑
如果需要,插入过程可以很容易地转换为触发器:
CREATE TRIGGER dbo.T_InsteadOfInsert
ON T
INSTEAD OF INSERT
AS
BEGIN
WITH NewRecords AS
( SELECT DocName, DocType, DocUser, DocDate = MAX(DocDate)
FROM inserted
GROUP BY DocName, DocType, DocUser
)
MERGE INTO T
USING NewRecords nr
ON T.DocName = nr.DocName
AND T.DocType = nr.DocType
AND T.DocUser = nr.DocUser
WHEN MATCHED AND nr.DocDate > T.DocDate THEN UPDATE
SET DocDate = nr.DocDate
WHEN NOT MATCHED THEN INSERT (DocName, DocUser, DocType, DocDate)
VALUES (nr.DocName, nr.DocUser, nr.DocType, nr.DocDate);
END