То, что вы описываете, называется отношение один к одному .
Такое отношение создается путем соединения обеих таблиц с внешним ключом, ссылающимся на их первичные ключи (или уникальный индекс).
Однако, поскольку это отношение «один к одному», только главная таблица действительно нуждается в спецификации identity
для своего первичного ключа.
Ваше требование вставить запись в Users
для существующей записи в таблице Consecutives
мне кажется странным.Обычно, когда у вас есть отношение «один к одному», вы заполняете связанные записи в обеих таблицах в одной транзакции.
Чтобы создать отношение «один к одному», где Consecutives
- главная таблица,Ваш DDL должен выглядеть следующим образом:
CREATE TABLE [dbo].[Consecutives]
(
[Consecutives_ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](100) NULL,
[Value] [int] NOT NULL,
CONSTRAINT PK_Consecutives PRIMARY KEY (Consecutives_ID)
);
CREATE TABLE [dbo].[Users]
(
[User_ID] [int] NOT NULL,
[LogIn] [varchar](100) NULL,
[Pass] [varchar](100) NOT NULL,
CONSTRAINT PK_Users PRIMARY KEY (User_ID),
CONSTRAINT FK_Users_Consecutives FOREIGN KEY (User_ID) REFERENCES [dbo].[Consecutives]([Consecutives_ID])
);
Обратите внимание, что я удалил спецификацию identity
из столбца User_ID
, а также изменил способ объявления первичного ключа, чтобы я мог назвать еговручную.
Ограничения именования - это лучшая практика, поскольку, если вам когда-либо понадобится изменить их, гораздо проще, когда вы уже знаете их имена.
Теперь, чтобы вставить одну запись в обе таблицы в одной транзакции, вы можетесоздайте хранимую процедуру следующим образом:
CREATE PROCEDURE InsertUser
(
@Name varchar(100),
@Value int,
@LogIn varchar(100),
@Pass varchar(100)
)
AS
DECLARE @Consecutives AS TABLE
(
Id int
);
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO [dbo].[Consecutives] ([Name], [Value])
OUTPUT Inserted.Consecutives_ID INTO @Consecutives
VALUES (@Name, @Value)
INSERT INTO [dbo].[Users] ([User_ID], [LogIn], [Pass])
SELECT Id, @Login, @Pass
FROM @Consecutives
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLL BACK TRANSACTION
END CATCH
GO
и выполните ее следующим образом:
EXEC InsertUser 'Zohar Peled', 1, 'Zohar', 'Peled'
Вы можете увидеть живое демо на rextester. (Обратите внимание, чтоrextester не позволяет использовать транзакции, поэтому части try ... catch и транзакции удалены из демонстрации)