2016-06-08 5 views
0

У меня есть таблица, которая содержит всю информацию о игроке. Я хотел бы сделать эту информацию и разделить данные на разные таблицы. Например:Вставить в ... Выбрать - получить и использовать автоинкремент ID

Таблица PlayerData имеет всю информацию. В таблице Address содержится информация о месте проживания игрока, а в таблице Info содержится информация, такая как имя, дата рождения и идентификатор адреса (указывается на таблице Address).

Я могу использовать INSERT INTO...SELECT для копирования данных через. Тем не менее, моя проблема заключается в том, чтобы сделать это последовательно, чтобы правильный идентификатор, выводимый из таблицы Address, был вставлен в таблицу 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 

Извещение т hat PlayerID в последних двух таблицах теперь можно связать с PlayerNum, чтобы получить ваши данные.

Как мы используем внешние ключи, вы не можете иметь игрока с информацией в AddressData или PlayerPersonalInfo без соответствующей записи в PlayerNum

+0

Отличный ответ, спасибо! Но что касается дополнительного столбца PlayerID, есть ли разница в простоте использования параметра AddressData.AddressID как PK и FK для таблицы PlayerPersonalInfo, в которой есть столбец AddressID? Поскольку адрес уникален, я использую 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

Спасибо. Я просто попробовал это, но я получаю «Нарушение ограничения PRIMARY KEY» PK_Info. Невозможно вставить дубликат ключа в объект 'dbo.Info'. Дублированное значение ключа - (12). Кажется, код работает в цикле, поскольку сама таблица изначально пуста – TryNCode

Смежные вопросы