2016-06-08 139 views
0

我有一张表,其中包含有关玩家的所有信息。我想要做的就是获取这些信息并将数据分成不同的表格。例如:插入...选择 - 获取并使用自动增量ID

Table PlayerData包含所有信息。表Address保存关于玩家的住所的信息,表Info保存诸如姓名,出生日期和地址ID(指向Address表)的信息。

我可以使用INSERT INTO...SELECT跨数据复制。然而,我的问题是依次执行此操作,使得从地址表输出的正确ID被插入到Info表中,否则将在哪个地址属于哪个播放器之间混淆。我如何获得为地址插入创建的身份,并在随后的职员插入中使用该身份?

速度并不是一个优先事项,因为这只是一次初始化数据库,所以完整性至关重要。

感谢

+0

相应的条目BTW'Info'是不是真的为表一个好名字。它并没有真正描述表格的内容。 –

+0

对不起,我已经改变了这个问题的表的名称。真正的表名是不同的:) – TryNCode

回答

1

你真的应该使用外键引用主表。现在我保持这个简单,但如果你能遵循这个,那么你将能够编辑它以满足你的需求。

好的,我们来制作一些示例数据。这相当于你当前的表格;

CREATE TABLE PlayerData (PlayerID int, PlayerName varchar (20), DateOfBirth date, Address1 varchar(20), Address2 varchar(20)) 
INSERT INTO PlayerData (PlayerID, PlayerName, DateOfBirth, Address1, Address2) 
VALUES 
(1,'Mike Hunt','1980-01-01','Mike Street','Hunt Town') 
,(2,'Harry Dong','1970-02-02','Harry Street','Dong Town') 
,(3,'Hugh Gass','1960-03-03','Hugh Street','Gass Town') 
,(4,'Neil Down','1950-04-04','Neil Street','Down Town') 
,(5,'Seymore Butts','1940-05-05','Seymore Street','Butts Town') 

我要创建一个保存我的玩家ID号的唯一列表中的一个表,这是我会把不适合到其他表远一点的信息。对于这个例子,我只有一个领域;

CREATE TABLE PlayerNum (PlayerID int PRIMARY KEY CLUSTERED) 

我现在要创建我的新AddressData表。注意它有它自己的标识字段,但也有一个PlayerID来引用PlayerNum表;

CREATE TABLE AddressData (AddressID int identity(10,1) PRIMARY KEY CLUSTERED, PlayerID int, Address1 varchar(20), Address2 varchar(20), FOREIGN KEY (PlayerID) REFERENCES PlayerNum(PlayerID)) 

我打算对包含我的玩家的个人信息的表做同样的处理,

CREATE TABLE PlayerPersonalInfo (InfoID int identity(50,1) PRIMARY KEY CLUSTERED, PlayerID int, PlayerName varchar(20), DateOfBirth date, FOREIGN KEY (PlayerID) REFERENCES PlayerNum(PlayerID)) 

所以,现在我已经得到了我新的3个表是空的,一个表的数据插入到他们。我们首先填充我们的PlayerNum表,这需要首先是因为其他表上的外键约束;

INSERT INTO PlayerNum (PlayerID) 
SELECT PlayerID 
FROM PlayerData 

现在我已经完成了,让我们将数据插入到AddressData中。注意我没有将数据插入到AddressID字段中,因为它是一个标识字段。它将从10开始并按照表格定义递增1;

INSERT INTO AddressData (PlayerID, Address1, Address2) 
SELECT PlayerID, Address1, Address2 
FROM PlayerData 

我打算对我的PlayerPersonalInfo数据做同样的事情。该表格的身份将从50开始并增加1;

INSERT INTO PlayerPersonalInfo (PlayerID, PlayerName, DateOfBirth) 
SELECT PlayerID, PlayerName, DateOfBirth 
FROM PlayerData 

如果您确信不需要它,您现在可以摆脱PlayerData表。

DROP TABLE PlayerData 

你现在有3张表;

PlayerNum

PlayerID 
1 
2 
3 
4 
5 

AddressData

AddressID PlayerID Address1  Address2 
10   1   Mike Street  Hunt Town 
11   2   Harry Street Dong Town 
12   3   Hugh Street  Gass Town 
13   4   Neil Street  Down Town 
14   5   Seymore Street Butts Town 

PlayerPersonalInfo

InfoID PlayerID PlayerName  DateOfBirth 
50  1   Mike Hunt  1980-01-01 
51  2   Harry Dong  1970-02-02 
52  3   Hugh Gass  1960-03-03 
53  4   Neil Down  1950-04-04 
54  5   Seymore Butts 1940-05-05 

通知吨最后两个表中的PlayerID现在可以链接到PlayerNum以检索您的数据。

由于我们使用外键,你不能在AddressData或PlayerPersonalInfo信息的球员没有PlayerNum

+0

很好的答案,谢谢!但是关于额外的PlayerID列,与简单使用AddressData.AddressID作为具有AddressID列的PlayerPersonalInfo表的PK和FK有什么不同?因为地址是唯一的,所以我一直使用AddressID作为FK(和PK) – TryNCode

+0

这一切都取决于你需要存储哪些其他信息。我通常会把玩家当作唯一的领域,这样,如果他们搬家或者类似的话,你可以为一个人设置多个地址(作为例子)。它将允许您保留旧数据用于审计目的,并且只在您查找其当前地址时才加入最新数据。 –

+0

好吧,我明白了。我有一个审计表显示所有的变化,但我明白你的意思是因为它在一个地方。这需要对我进行相当多的重构(现有的存储过程等),以实现 – TryNCode

3

如果你正在学习如何做到这一点,那么学习的正确方法:在OUTPUT条款(记录here)。

这允许您将结果放入一个临时表(通常是一个表变量)。一个例子是:

DECLARE @ids TABLE (AddressId int); 

INSERT INTO ADDRESS(. . .) 
    OUTPUT inserted.AddressId INTO @ids 
    VALUES (. . .); 

INSERT INTO info(. . ., AddressId) 
    SELECT . . . , i.AddressId 
    FROM @ids i; 
+0

谢谢。我只是试过这个,但我得到了'违反主键约束'PK_Info'。不能在对象'dbo.Info'中插入重复键。重复的键值是(12).'看起来代码是循环运行的,因为表本身最初是空的 – TryNCode