Как установить значение идентификатора из другой таблицы - PullRequest
0 голосов
/ 15 марта 2019

Допустим, у меня есть эти таблицы:

CREATE TABLE [dbo].[Users]
(
    [User_ID] [int] IDENTITY(1,1)PRIMARY KEY NOT NULL ,
    [LogIn] [varchar](100) NULL,
    [Pass] [varchar](100) NOT NULL,

)

CREATE TABLE [dbo].[Consecutives]
(
    [Consecutives_ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Name] [varchar](100) NULL,
    [Value] [int] NOT NULL,

)

Меня просят установить возможность редактирования User_ID, которое будет использоваться следующим при добавлении нового пользователя, используя значение, указанное в таблице Consecutive.

Таким образом, если, например, значение Consecutive равно 50, даже если последний добавленный пользователь имеет User_ID, установленный на 8, идентификатор нового пользователя будет равен 50, а последующий - 51.

Я бы сделал это с использованием внешнего ключа, но, очевидно, я не могу установить первичный ключ в качестве внешнего ключа.

Я не могу найти способ сделать это.
Кто-нибудь может мне помочь?

Ответы [ 2 ]

2 голосов
/ 15 марта 2019

То, что вы описываете, называется отношение один к одному .
Такое отношение создается путем соединения обеих таблиц с внешним ключом, ссылающимся на их первичные ключи (или уникальный индекс).
Однако, поскольку это отношение «один к одному», только главная таблица действительно нуждается в спецификации 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 и транзакции удалены из демонстрации)

0 голосов
/ 15 марта 2019

Вы когда-нибудь пробовали установить идентификационную вставку? Эта ссылка может вам помочь. Чтобы использовать идентификационную вставку, пользователю необходимы некоторые разрешения на изменение таблицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...