【问题标题】:Move SQL columns to new entries in a new table将 SQL 列移动到新表中的新条目
【发布时间】:2013-03-13 14:24:50
【问题描述】:

这是我在 C# 程序中很容易做到的事情,但在 SQL 中,好吧,我不知道你是否可以。

我有一个表格格式。该表具有“文件名”和“大小”。我想用外键将它们移动到新表 DigitalFormat 中。

到目前为止,我已经完成了简单的部分:

CREATE TABLE FormatDigital
(
FormatDigitalId uniqueidentifier NOT NULL,
Filename nvarchar(MAX) NOT NULL,
Size int NOT NULL
PRIMARY KEY (FormatDigitalId)
);

ALTER TABLE Formats
ADD FormatDigital uniqueidentifier
GO

ALTER TABLE Formats
ADD CONSTRAINT FK_FormatDigital_FormatDigital FOREIGN KEY (FormatDigital)
REFERENCES FormatDigital(FormatDigitalId);

我现在想要获取 Formats 中的所有记录,在 FormatDigital 中创建新条目,并确保 Format.FormatDigitalId 外键指向正确的 ID。

这是您可以在 SQL 中执行的操作吗?或者我应该只是连接一个 C# 程序并变得很棒?

【问题讨论】:

  • 格式中每一行的文件名和大小是否唯一?
  • 您是否有理由添加一个全新的表,但只是复制数据,而不是在“格式”中添加一个新列以指示该格式是数字格式?
  • 我认为文件名和大小不是唯一的?也许不是这样,好问题,杰森。
  • Formats 有唯一标识符吗?
  • Kyle:不,这只是一些随机数据(只是文本)。 Jason:是的,我们将有一些其他表格而不是数字表格,还有很多其他信息(否则基本上会一团糟) Lomak:谢谢 PinnyM:是的

标签: sql sql-server-2008 sql-update


【解决方案1】:

只是做一些类似的事情

INSERT INTO FormatDigital
Select Filename, Size from Format

然后

UPDATE F
SET
FormatDigital = FD.FormatDigitalID
FROM
Format F
Inner Join
FormatDigital FD
on FD.FileName = F.FileName and FD.Size = F.Size

如果您的文件名和大小不是唯一的,请在第一个查询中添加 DISTINCT。

【讨论】:

  • DISTINCT 将在 FormatDigital 中为多个 Format 行添加一条记录。
  • 如果两个 Format 记录共享相同的文件名和大小,它们应该指向相同的 FormatDigitalID。否则有一个子表有什么意义?
  • 那要看第二张表的用途了,还没有解释...
  • 表格的目的只是为了在一对一的关系中有额外的信息
【解决方案2】:

在创建 FormatDigital 表后,就像你一样,(除了使用整数主键,设置为身份)

   CREATE TABLE FormatDigital
    ( FormatDigitalId integer Identity Primary Key NOT NULL,
      Filename nvarchar(MAX) NOT NULL,
      Size int NOT NULL);


   Insert FormatDigital(FileName, Size)
   Select distinct FileName, Size From Formats
   -- ----------------------------------------
   Update F Set FormatDigital =
        D.FormatDigitalId 
   From Format F Join FormatDigital D 
      On  D.Filename = F.Filename
         And D.Size = F.Size

如果您真的想使用 Guid 作为键,(这样做有很多缺点。)
稍后添加,然后删除整数键

【讨论】:

  • 这与@KyleHale 的答案基本相同,但问题相同——不保证是一对一的
  • 是的,这就是 Distinct 所做的。
  • 如果存在 2 条具有相同文件名和大小的 Format 记录,则只会创建 1 条(共享)FormatDigital 记录。那是多对一,而不是一对一。
【解决方案3】:

首先,将您的 FormatDigitalId 更改为默认使用顺序 GUID:

FormatDigitalId uniqueidentifier NOT NULL DEFAULT newsequentialid()

现在您可以使用以下光标。请注意,此代码假定 Formats 有一个名为 Id 的整数主键 - 如果不是这种情况,请将 @nextId 更改为正确的类型并将 Id 更改为正确的名称:

DECLARE @nextId int
DECLARE @filename nvarchar(max)
DECLARE @size int
DECLARE @newId guid

DECLARE loop CURSOR FOR
SELECT Id, Filename, Size
FROM Formats

OPEN loop
FETCH NEXT FROM loop INTO @nextId, @filename, @size

WHILE @@FETCH_STATUS = 0
BEGIN

    INSERT INTO FormatsDigital (Filename, Size) 
            OUTPUT inserted.FormatDigitalID INTO @newId 
            VALUES (@filename, @size)

    UPDATE Formats SET FormatDigitalId = @newID WHERE Id = @nextId

    FETCH NEXT FROM loop INTO @nextId, @filename, @size
END

CLOSE loop
DEALLOCATE loop

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多