2

我使用以下代码将旧数据ArchiveTable存档并从中删除存档数据SourceTable

DELETE FROM SourceTable 
OUTPUT 
    DELETED.[ID], 
    DELETED.[Code],
    DELETED.[Title]
INTO ArchiveTable([OldID], [Code], [Title])
WHERE Condition

表结构:

CREATE TABLE [SourceTable](
    [ID] [INT] IDENTITY(1,1) NOT NULL,
    [Code] [VARCHAR](16) NULL,
    [Title] [NVARCHAR](128) NULL,
    CONSTRAINT [PK_SourceTable] PRIMARY KEY CLUSTERED ([ID] ASC)
) 
GO

CREATE TABLE [ArchiveTable](
    [ID] [INT] IDENTITY(1,1) NOT NULL,
    [OldID] [INT] NOT NULL,
    [Code] [VARCHAR](16) NULL,
    [Title] [NVARCHAR](128) NULL,
    CONSTRAINT [PK_ArchiveTable] PRIMARY KEY CLUSTERED ([ID] ASC)
) 
GO

我需要返回已删除的记录并ArchiveTable.[ID]申请。我像这样更改代码:

DELETE FROM SourceTable 
OUTPUT 
    DELETED.[ID], 
    DELETED.[Code],
    DELETED.[Title]
INTO ArchiveTable([OldID], [Code], [Title])
OUTPUT DELETED.*
WHERE Condition

此代码返回已删除的记录,但我不知道如何获取 ArchiveTable此记录的 ID。查看ArchiveTable结构,它具有OldID引用的列SourceTable.IDID它是列的IdentityArchiveTable。我需要ArchiveTable.ID在最终结果中。

4

2 回答 2

3

您可以使用临时表

CREATE TABLE #DeletedRows(
    [ID] [INT] NOT NULL,
    [Code] [VARCHAR](16) NULL,
    [Title] [NVARCHAR](128) NULL
)

DELETE SourceTable 
OUTPUT 
    DELETED.[ID], 
    DELETED.[Code],
    DELETED.[Title]
INTO #DeletedRows([ID], [Code], [Title])
WHERE Condition

INSERT ArchiveTable([OldID], [Code], [Title])
OUTPUT INSERTED.*
SELECT [ID], [Code], [Title]
FROM #DeletedRows

DROP TABLE #DeletedRows

带有表变量的变体

DECLARE @DeletedRows TABLE(
    [ID] [INT] NOT NULL,
    [Code] [VARCHAR](16) NULL,
    [Title] [NVARCHAR](128) NULL
)

DELETE SourceTable 
OUTPUT 
    DELETED.[ID], 
    DELETED.[Code],
    DELETED.[Title]
INTO @DeletedRows([ID], [Code], [Title])
WHERE Condition

INSERT ArchiveTable([OldID], [Code], [Title])
OUTPUT INSERTED.*
SELECT [ID], [Code], [Title]
FROM @DeletedRows
于 2019-04-09T10:00:20.167 回答
0

我发现了一个有趣的变体,使用DMLwith OUTPUTinSPINSERT...EXEC...之后:

测试表:

CREATE TABLE TestTable(
  ID int NOT NULL PRIMARY KEY,
  Title varchar(10) NOT NULL
)

CREATE TABLE TestTableLog(
  LogID int NOT NULL IDENTITY,
  OperType char(1) NOT NULL,
  CHECK(OperType IN('I','U','D')),
  ID int NOT NULL,
  Title varchar(10) NOT NULL
)

DML 程序:

CREATE PROC InsTestTable
  @ID int,
  @Title varchar(10)
AS

  INSERT TestTable(ID,Title)
  OUTPUT inserted.ID,inserted.Title,'I' OperType
  VALUES(@ID,@Title)

GO

CREATE PROC UpdTestTable
  @ID int,
  @Title varchar(10)
AS

  UPDATE TestTable
  SET
    Title=@Title
  OUTPUT inserted.ID,inserted.Title,'U' OperType
  WHERE ID=@ID

GO

CREATE PROC DelTestTable
  @ID int
AS

  DELETE TestTable
  OUTPUT deleted.ID,deleted.Title,'D' OperType
  WHERE ID=@ID

GO

测试:

-- insert test
INSERT TestTableLog(ID,Title,OperType)
EXEC InsTestTable 1,'A'

INSERT TestTableLog(ID,Title,OperType)
EXEC InsTestTable 2,'B'

INSERT TestTableLog(ID,Title,OperType)
EXEC InsTestTable 3,'C'

-- update test
INSERT TestTableLog(ID,Title,OperType)
EXEC UpdTestTable 2,'BBB'

-- delete test
INSERT TestTableLog(ID,Title,OperType)
EXEC DelTestTable 3
GO

-- show resutls
SELECT *
FROM TestTableLog

也许对某人来说会很有趣。

于 2019-04-30T03:58:00.623 回答