在SQL Server中插入多对多表

时间:2014-05-29 21:02:36

标签: sql sql-server

这是我的Tag表:

CREATE TABLE [dbo].[Tag](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NULL,
    [CreationDate] [datetime] NOT NULL,
    [TagSlug] [nvarchar](max) NOT NULL,

    PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

这是我的Post表:

CREATE TABLE [dbo].[Post](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Title] [nvarchar](400) NOT NULL,
    [Body] [nvarchar](max) NOT NULL,
    [Summary] [nvarchar](max) NOT NULL,
    [CreationDate] [datetime] NOT NULL,
    [UrlSlug] [nvarchar](max) NOT NULL,
    [Picture] [nvarchar](max) NULL,
    [TagId] [int] NOT NULL,

    PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

ALTER TABLE [dbo].[Post]  WITH CHECK ADD  CONSTRAINT [Post_Tag] FOREIGN KEY([TagId])
REFERENCES [dbo].[Tag] ([Id])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[Post] CHECK CONSTRAINT [Post_Tag]
GO

我只想将Id中的TagPostId中的Post插入到名为Post_Tag的新表中,该表是多对多关系,这是我Post_Tag表的脚本:

CREATE TABLE [dbo].[Post_Tag](
    [PostId] [int] NOT NULL,
    [TagId] [int] NOT NULL,

    CONSTRAINT [PK_dbo.Post_Tag] PRIMARY KEY CLUSTERED ([PostId] ASC, [TagId] ASC)
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Post_Tag]  WITH CHECK 
ADD CONSTRAINT [FK_dbo.Post_Tag_dbo.Post_PostId] 
FOREIGN KEY([PostId]) REFERENCES [dbo].[Post] ([Id])
   ON DELETE CASCADE
GO

ALTER TABLE [dbo].[Post_Tag] CHECK CONSTRAINT [FK_dbo.Post_Tag_dbo.Post_PostId]
GO

ALTER TABLE [dbo].[Post_Tag] WITH CHECK 
ADD CONSTRAINT [FK_dbo.Post_Tag_dbo.Tag_TagId] 
FOREIGN KEY([TagId]) REFERENCES [dbo].[Tag] ([Id])
   ON DELETE CASCADE
GO

ALTER TABLE [dbo].[Post_Tag] CHECK CONSTRAINT [FK_dbo.Post_Tag_dbo.Tag_TagId]
GO

现在,为此,我尝试了以下查询:

insert into [Blog].[dbo].[Post_Tag] (PostId,TagId)
   select [Id] as [PostId] from [OldBlog].[dbo].[Tag]
   select [TagId] from [OldBlog].[dbo].[Post]

但运行脚本时出现此错误:

  

INSERT语句的选择列表包含的项目少于插入列表。 SELECT值的数量必须与INSERT列的数量匹配。

我的查询有什么问题?感谢

2 个答案:

答案 0 :(得分:3)

正在分别处理2个选择查询。您必须想出一种方法将[OldBlog].[dbo].[Tag]加入[OldBlog].[dbo].[Post],以便您可以从这个新的表格表格中将字段PostId,TagId插入[Blog].[dbo].[Post_Tag]

答案 1 :(得分:2)

为此,您可以使用两个select语句中每行的行号作为链接,这样您就可以加入它们并从它们中选择所需的行。

SELECT POST.[PostId], TAG.[TagId]
FROM (
select ROW_NUMBER() OVER (ORDER BY [Id])  AS Link, [Id] as [PostId] from [OldBlog].[dbo].[Tag]) AS POST
JOIN (
select ROW_NUMBER() OVER (ORDER BY [TagId]) AS Link, [TagId] from [OldBlog].[dbo].[Post]) AS TAG ON POST.Link = TAG.Link

重要说明: 这只是强迫"的一种手段。表之间的关系,彼此之间没有任何关系。这确实是一件危险的事情,因为我们基于行号而不是实际键强制表之间的关系。只有在没有明确的预期输出时才能使用,或者如果没有其他方法可以链接两个或多个不相关的表,其中每个选定列的关系不重要,则应该使用此选项。