0

假设我有这些表:

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,新用户的 ID 也将为 50,并且连续更新为 51。

我会使用外键来做,但显然我不能将主键设置为外键。

我找不到办法做到这一点。
有人可以帮我吗?

4

2 回答 2

2

您所描述的称为一对一关系
您可以通过使用引用其主键(或唯一索引)的外键连接两个表来创建此类关系。
然而,由于这是一对一的关系,只有主表实际上需要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 和事务部分已从演示中删除)

于 2019-03-15T07:08:18.877 回答
0

你有没有试过设置身份插入?此链接可能会对您有所帮助。要使用身份插入,用户需要一些更改表权限。

于 2019-03-15T06:04:24.357 回答