架构更改:将字段转换为其他表上的外键

时间:2011-02-25 22:04:56

标签: sql-server

我目前有这样一张桌子:

    Stuff
    ----------
    StuffId identity int not null
    Description nvarchar(4000) null
    ...

我想将Description存储在一个专门为用户生成的内容预留的单独表中:

    Content
    ----------
    ContentId identity int not null
    Content nvarchar(max) not null
    ...

(此表已存在,其他表已引用其中的条目。)

所以我需要:

  1. 使用外键约束在Stuff表上创建一个DescriptionContentId字段。
  2. 将当前描述内容复制到内容表中。
  3. 将每个DescriptionContentId设置为具有在步骤2中插入值时自动生成的ContentId值。
  4. 删除“说明”列。
  5. 我知道如何做第1步和第4步,但第2步和第3步让我不知所措,因为它们需要同时完成。这似乎是一个相当常见的架构更改。最好的方法是什么?

    更新

    由于Output关键字,我离我更近了一步,但我仍然缺少一些东西。这就是我想做的事情:

    create table #tmp (StuffId int, ContentId int)
    
    insert into Content(Content)
    output s.StuffId, inserted.ContentId
    into #tmp(StuffId, ContentId)
        select Description
        from Stuff s
        where Description IS NOT NULL
    

    但我不能引用s.StuffId,因为它不是插入Content表的字段之一。当我为每个Stuff条目插入新的Content项时,如何将Stuff的ID与Content的ID相关联?

1 个答案:

答案 0 :(得分:1)

输出条款将为您解救。

它会将插入的描述和标识列输出到可变的表中,然后您可以使用该数据更新另一个表。

如果说明不是唯一的,您可能需要执行以下操作: 将stuffID列添加到内容表中。然后从insert输出stuffid和content id,使用stuffid更新表以确保唯一性,从内容表中删除stuffid列。

联机丛书中有关如何使用OUTPUT的示例

DECLARE @MyTableVar table(
  LastName     nvarchar(20) NOT NULL,
  FirstName    nvarchar(20) NOT NULL,
  CurrentSales money NOT NULL
  );

INSERT INTO dbo.EmployeeSales (LastName, FirstName, CurrentSales)
  OUTPUT INSERTED.LastName, 
         INSERTED.FirstName, 
         INSERTED.CurrentSales
  INTO @MyTableVar
    SELECT c.LastName, c.FirstName, sp.SalesYTD
    FROM HumanResources.Employee AS e
        INNER JOIN Sales.SalesPerson AS sp
        ON e.EmployeeID = sp.SalesPersonID 
        INNER JOIN Person.Contact AS c
        ON e.ContactID = c.ContactID
    WHERE e.EmployeeID LIKE '2%'
    ORDER BY c.LastName, c.FirstName;