1对多Sql插入

1对多Sql插入,sql,tsql,one-to-many,Sql,Tsql,One To Many,我在计算如何将行插入数据库时遇到问题。我有一个实验台,它有以下几列 CREATE TABLE [dbo].[Experiment] ( [ExperimentId] INT IDENTITY (1, 1) NOT NULL, [Experiment] VARCHAR (100) NOT NULL, [Account] VARCHAR (100) NOT NULL, [Profile] VARCHAR (100) NOT

我在计算如何将行插入数据库时遇到问题。我有一个实验台,它有以下几列

CREATE TABLE [dbo].[Experiment] (
    [ExperimentId] INT           IDENTITY (1, 1) NOT NULL,
    [Experiment]   VARCHAR (100) NOT NULL,
    [Account]      VARCHAR (100) NOT NULL,
    [Profile]      VARCHAR (100) NOT NULL,
    [Property]     VARCHAR (100) NOT NULL,
    [BucketId]     INT           NULL,
    CONSTRAINT [PK_Experiment] PRIMARY KEY CLUSTERED ([ExperimentId] ASC),
    CONSTRAINT [FK_Experiment_Bucket] FOREIGN KEY (BucketId) REFERENCES Bucket (BucketId)
);
我还有一张桶形桌

CREATE TABLE [dbo].[Bucket] (
    [BucketId]   INT      IDENTITY (1, 1) NOT NULL,
    [BucketName] CHAR (1) NOT NULL,
    CONSTRAINT [PK_BucketId] PRIMARY KEY CLUSTERED ([BucketId] ASC)
);
一个实验可以有很多存储桶A-Z,但是,我不确定如何插入数据。 我假设我必须首先插入桶信息

INSERT INTO Bucket (BucketName) VALUES (@BucketName)

然后我必须在实验表中插入数据。但是,在填充实验表时,如何从bucket表中获取bucket id呢?我需要做一个select语句吗?如果有任何帮助,我们将不胜感激。

是的,您将在插入到实验中时执行子选择以从桶表中获取BucketId

INSERT
...
(SELECT TOP 1 BucketId FROM Bucket WHERE BucketName=@BucketName)
...
一个实验可以有很多桶A-Z

考虑到这一点,您的外键不正确。 您希望使用N个桶进行1次实验。 在本例中,您将使用一个铲斗进行一个实验

为了解决这个问题,您需要修改实验,并删除BucketId列。 除此之外,您还应该将ExperimentId列添加到Bucket中

当然,还有外键约束

完成后,您将能够在每个实验中使用多个桶

INSERT
...
(SELECT TOP 1 BucketId FROM Bucket WHERE BucketName=@BucketName)
...
-

为了添加行,您必须首先创建实验,然后创建所需数量的bucket


希望这能有所帮助。

首先,我们称之为一对多外键关系:一个实验可以有多个存储桶。在这种情况下,设置键的方法是在Bucket表中有一个外键,它引用了实验ID。 由于实验可以有多个bucket,因此实验表中会有一行对应于bucket表中的多行

CREATE TABLE [dbo].[Experiment] (
[ExperimentId] INT           IDENTITY (1, 1) NOT NULL,
[Experiment]   VARCHAR (100) NOT NULL,
[Account]      VARCHAR (100) NOT NULL,
[Profile]      VARCHAR (100) NOT NULL,
[Property]     VARCHAR (100) NOT NULL,
// No bucket id[BucketId]     INT           NULL,
CONSTRAINT [PK_Experiment] PRIMARY KEY CLUSTERED ([ExperimentId] ASC),
);

CREATE TABLE [dbo].[Bucket] (
[BucketId]   INT      IDENTITY (1, 1) NOT NULL,
[BucketName] CHAR (1) NOT NULL,
[ExperimentId] INT 
CONSTRAINT [PK_BucketId] PRIMARY KEY CLUSTERED ([BucketId] ASC)
CONSTRAINT [FK_ExperimentBucket] FOREIGN KEY (ExperimentId)
REFERENCES Experiment(ExperimentId)
);
一旦你有了它,你就可以插入实验了

INSERT INTO Experiment VALUES (your experiment data)
然后找出你最后做了什么实验

SELECT @experimentid = top 1 ExperimentID from Experiments order by ExperimentID
然后插入具有铲斗ID的铲斗

INSERT INTO Buckets VALUES (your data with @experimentid)

如果一个实验只有一个桶

Declare @bucketID Int;
INSERT INTO [Bucket] (BucketName) VALUES (@BucketName);
set @bucketID = (select SCOPE_IDENTITY());
insert into [Experiment] (bucketID) values (@bucketID);
但这确实存在问题,因为它会为每个值创建一个新的bucket,而不检查该值是否存在。 实际的问题陈述是什么? 如果这是您想要的,那么只需在实验中使用BucketName,而不使用单独的表或FK

如果您希望在一个BucketName中包含ID和as,则: 为此,应在BucketName上声明唯一约束

Declare @bucketID Int;
set @bucketID = (select bucketID from bucket where BucketName = @BucketName);
if @bucketID = null;
begin
  INSERT INTO [Bucket] (BucketName) VALUES (@BucketName);
  set @bucketID = (select SCOPE_IDENTITY());      
end
insert into [Experiment] (bucketID) values (@bucketID);
下面假设一个实验可以有多个桶

在当前形式中,它不是3NF 您将遇到在实验中重复数据以及每行的唯一[ExperimentId]的问题

一对多关系需要第三个表

您需要一个第三个table ExperimentBucket,其中包含对每个表的复合PK和FK引用,并从实验中删除BucketID

CREATE TABLE [dbo].[ExperimentBucket] (
[BucketId]   INT,
[ExperimentId] INT 
CONSTRAINT [PK_BucketId] PRIMARY KEY CLUSTERED ([BucketId] ASC, [ExperimentId] ASC)
CONSTRAINT [FK_ExperimentBucket_Experiment] FOREIGN KEY (ExperimentId)
REFERENCES Experiment(ExperimentId)
CONSTRAINT [FK_ExperimentBucket_Bucket] FOREIGN KEY (BucketId)
REFERENCES Bucket(BucketId)
);

BucketName不是唯一的。当您请求与2行或更多行匹配的bucketname时,您将获得哪个ID?前1行没有ORDER BY?您知道有可靠的方法可以检索您刚才插入的标识值,但这不是其中之一。OP从未指定他将始终希望获取最近插入的Bucket,这就是我放弃涉及标识的解决方案的原因。他没有明确指出Bucketname是唯一的,是真的,但如果不是这样的话,那将是糟糕的设计,因为就像你说的,如果有重复的名称,你想要哪个BucketId?这对OP来说是个问题,但至少在TOP 1中,子选择不会出错。这是正确的,但仍然是一个错误。一个正确的方法是按订单进行排序。但是SCOPE_IDENTITY、@@IDENTITY、IDENT_当前的“tablename”在这种情况下有什么问题?如果我不能读懂OP的心思,我会为订单提出什么建议?同样,我认为您也在对原始问题文本不支持的所需解决方案进行假设。如何从实验中选择@experimentid=experimentid?为什么不使用SCOPE_标识?不,他没有1对多,你也没有。该PK只允许一行。即使你做了一个复合PK,你也有重复[BucketName]的问题,它不是3NF。我没有投你反对票。@BARM这个答案在实验和桶之间确实有1对多。FK_实验_桶显然是错放在那里了。@ypercube OK它是1对多。我没有投反对票。但它允许重复BucketName,我怀疑这是问题的意图,即使不是在问题中。我同意此coe允许重复bucket name,但在某些情况下这是有用的,问题并没有表明bucket name必须是唯一的。SCOPE_IDENTITY是一个很好的选项,而不是选择experimentid。是的,FK_实验_桶是错误的。我将删除如果您添加了实验ID,您使用重复的BucketName违反了3NF,如果插入了相同的名称,则违反了3NF。你是对的,但如果他保持这种方式,他将不能有1-n的关系,而是1-1。正如其他人所指出的,如果一个实验可以有多个桶,你没有正确地设置你的表。P
请重新访问并相应地编辑您的问题。这让那些认为自己能读懂你心思的评论者感到很苦恼。不要发布模糊的问题,也不要在8小时内不回答问题-1.