在SQL Server应用中使用OUTPUT子句(下)

日期: 2009-09-29 作者:Roman Rehak翻译:曾少宁 来源:TechTarget中国 英文

下一步,我们将来自INSERT语句的输出实时地插入到一个表中。例如,Susan结婚后变更了她的姓。这时,我们需要更新她的员工信息。公司政策规定我们必须保留所有员工的历史数据,因此我们需要存档旧的员工数据。

这样我们就创建了一个表Employee_Archive及一些附加域:   REATE TABLE dbo.Employees   (   EmployeeID INT NOT NULL IDENTITY(1, 1),   FirstName VARCHAR(50) NOT NULL,   Las……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

下一步,我们将来自INSERT语句的输出实时地插入到一个表中。例如,Susan结婚后变更了她的姓。这时,我们需要更新她的员工信息。公司政策规定我们必须保留所有员工的历史数据,因此我们需要存档旧的员工数据。这样我们就创建了一个表Employee_Archive及一些附加域:

  REATE TABLE dbo.Employees
  (
  EmployeeID INT NOT NULL IDENTITY(1, 1),
  FirstName VARCHAR(50) NOT NULL,
  LastName VARCHAR(50) NOT NULL,
  [Status] VARCHAR(20) DEFAULT 'Single'
  ChangedBy VARCHAR(300) NOT NULL,
  ChangedDatetime DATETIME NOT NULL
  )
  现在我们可以更新Susan的信息记录了,同时使用OUTPUT子句和DELETED虚拟表将旧的记录行插入到Employee_Archive表中:

  UPDATE dbo.Employees
  SET LastName = 'Jones',
  Status = 'Married'
  OUTPUT DELETED.*, system_user, getdate()
  INTO dbo.Employees_Archive
  WHERE EmployeeID = 1
  在执行这个查询后,我们会在Employee表中得到这些数据:

EmployeeIDFirstNameLastNameStatus
1SusanJonesMarried

  Employee_Archive表包含了一个有旧数据值、用户名和数据修改时间的记录行。这是我的计算机上的输出,你电脑上的输出可能有些不一样:

EmployeeIDFirstNameLastNameStatusChangedBYChangedDatetime
1SusanKelleySinglerrehak2008-04-21 02:04:18.310

  另一个OUTPUT子句的实践用法是保存一系列受影响的记录以备后续处理。这在更新一组记录的时候是很有用的,在做一些额外的处理后再重新更新相同的记录集——我在使用一组INSERT/UPDATE/DELETE语句同步2个不同数据库时经常这样做。因为我们有了一列ID,我们就不必再次执行第一次的查询。相反,我们可以在WHERE子句中使用这些ID,从而避免再做一次复杂和大开销的查询去取回相同的数据集。下面的例子创建了一个临时表并将修改的员工记录的ID保存起来:

  CREATE TABLE #EmployeeIDs
  (
  EmployeeID INT NOT NULL
  )
  GO
  UPDATE dbo.Employees
  SET LastName = LastName
  OUTPUT INSERTED.EmployeeID
  INTO #EmployeeIDs

  在UPDATE语句执行后,临时表包含了ID和所有修改的记录。

  如果需要从一个表清除大量的数据并转存到一个存档表中,OUTPUT子句是能够有效地节省处理时间的。大多数有经验的DBA都会将删除操作拆分成一组更小的删除操作,可能是100,000个或更多。所以真正的删除数据的代码可能会是这样的:

  WHILE 1 = 1
  BEGIN
  BEGIN TRANSACTION
  INSERT INTO ArchiveTable
  SELECT *
  FROM MainTable
  WHERE ID BETWEEN @MinID AND @MaxID
  DELETE FROM MainTable
  WHERE ID BETWEEN @MinID AND @MaxID
  COMMIT TRANSACTION
  END
  如果使用OUTPUT子句,我们就能够在一条语句中完成这个操作,并且可以节省很多处理时间,因为配置记录行只需要进行一次:

  WHILE 1 = 1
  BEGIN
  DELETE FROM MainTable
  OUTPUT DELETED.*
  INTO ArchiveTable
  WHERE ID BETWEEN @MinID AND @MaxID
  END
  我们可以看到,使用OUTPUT子句来简化代码和替代触发器有很多种可能的用法。在本文中,我介绍了如何使用OUTPUT语句去审计和存档数据、获取一组被修改的记录行和简化数据删除程序。

翻译

曾少宁
曾少宁

TechTarget中国特约技术编辑,某高校计算机科学专业教师和网络实验室负责人,曾任职某网络国际厂商,关注数据中心、开发运维、数据库及软件开发技术。有多本关于思科数据中心和虚拟化技术的译著,如《思科绿色数据中心建设与管理》和《基于IP的能源管理》等。

相关推荐