假设我有这些表格:
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。
我会使用外键来完成此操作,但是显然我不能将主键设置为外键。
我找不到办法。
有人可以帮我吗?
答案 0 :(得分: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'
You can see a live demo on rextester.(请注意,extrester不允许使用事务,因此会从那里的演示中删除try ... catch和transaction部分)
答案 1 :(得分:0)
您是否尝试过设置身份插入? This link可能会为您提供帮助。要使用标识插入,用户需要一些更改表权限。