0

我有两张桌子:

create table Clients
(
     id_client int not null identity(1,1) Primary Key,
     name_client varchar(10) not null,
     phone_client int not null
)

create table Sales
(
     id_sale int not null identity(1,1) Primary Key,
     date_sale date not null, 
     total_sale float not null
     id_clients int not null identity(1,1) Foreign Key references Clients
)

因此,让我们插入 Clients ('Ralph', 00000000),id_client 将是 1(显然)。问题是:我怎样才能将那个 1 插入到 Sales 中?

4

2 回答 2

1

首先 - 你不能在任何表中定义两列identity- 你会得到一个错误

消息 2744,级别 16,状态 2,第 1 行为
表“销售”指定了多个标识列。每个表只允许一个标识列。

因此,您将无法实际创建该Sales表。

表中的id_clients引用了一个列——但它本身不应定义为标识——它会获取您的客户所拥有的任何价值。Salesidentity

create table Sales
(
     id_sale int not null identity(1,1) Primary Key,
     date_sale date not null, 
     total_sale float not null
     id_clients int not null foreign key references clients(id_client)
)

-- insert a new client - this will create an "id_client" for that entry
insert into dbo.Clients(name_client, phone_client)
values('John Doe', '+44 44 444 4444')

-- get that newly created "id_client" from the INSERT operation
declare @clientID INT = SCOPE_IDENTITY()

-- insert the new "id_client" into your sales table along with other values
insert into dbo.Sales(......, id_clients)
values( ......., @clientID)
于 2015-11-19T05:40:36.610 回答
0

这对我来说就像一个魅力,因为据我了解,如果我从数据库的旧副本迁移用户或客户数据等 - 身份列和 UId(用户 ID)或 CId(客户 ID)用于给每一行它自己的唯一标识 - 将变得不同步,因此我使用包含标识列值副本的第二列(TId/UId 等)纯粹通过应用程序逻辑流关联我的数据。

当迁移发生时,我可以偏移实际的 SQL 标识列 (IdColumn)通过使用虚拟插入将标识列向上推到旧数据值,标识列避免在新插入上出现重复,因此新客户或用户等将在填充后在新插入时继续从标识列获取唯一值旧数据仍将包含第二列中的旧身份值,以便其他表中的其他数据(交易等)仍将与与所述数据相关的客户/用户同步,无论是交易还是其他.但没有重复,因为虚拟数据会推高 IdColumn 值以匹配旧数据。

因此,如果我说 920 条用户记录并且最大的 UId 是 950,因为 30 被删除了。然后在添加旧的 920 条记录之前,我将在新表中虚拟插入和删除 31 行,以确保 UId 没有重复项。它非常绕圈子,但它适用于我对 SQL XD 的有限理解

这也允许我做的是稍后使用原始 UId/CId/TId(身份副本)删除迁移的用户/客户/事务,并且不必担心如果我删除它不会是正确的项目没有副本,并且要针对实际的身份列,如果数据是迁移的数据(从旧数据库插入到数据库中),该列将不同步。拥有一份副本 = 快乐的日子。我可以使用 (SET IDENTITY_INSERT [dbo].[UserTable] ON) 但我最终可能会搞砸,所以这种方式对我来说是安全的。

本质上使数据实例在一定程度上是不可知的。

我使用 OUTPUT Inserted.IdColumn 来保存任何与文件名相关的图片,并且能够专门为图片查看器调用它们,并且该数据也是迁移安全的。

为此,一个副本,特别是在插入时,工作得很好。

声明@userId INT = SCOPE_IDENTITY() 以存储新的身份值-UPDATE dbo.UserTable 选择在同一事务中更新所有内容的位置-SET UId = @userId 将其设置为我的第二列-WHERE IdColumn = @userId; 瞄准正确的行

USE [DatabaseName]
GO
/****** Object:  StoredProcedure [dbo].[spInsertNewUser]    Script Date: 
2022/02/04 12:09:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[spInsertNewUser]
@Name varchar(50),
@PhoneNumber varchar(20),
@IDNumber varchar(50),
@Address varchar(200),
@Note varchar(400),
@UserPassword varchar(MAX),
@HideAccount int,
@UserType varchar(50),
@UserString varchar(MAX)


AS
BEGIN

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
INSERT INTO dbo.UserTable
    ([Name],
    [PhoneNumber],
    [IDNumber],
    [Address],
    [Note],
    [UserPassword],
    [HideAccount],
    [UserType],
    [IsDeleted],
    [UserString])
    OUTPUT inserted.IdColumn
VALUES
    (@Name,
    @PhoneNumber,
    @IDNumber,
    @Address,
    @Note,
    @UserPassword,
    @HideAccount,
    @UserType,
    @UserString);

    declare @userId INT = SCOPE_IDENTITY()
    
    UPDATE  dbo.UserTable
    SET     UId = @userId
    WHERE   IdColumn = @userId;

END

这是用于测试的表的创建

CREATE TABLE [dbo].[UserTable](
[IdColumn] [int] IDENTITY(1,1) NOT NULL,
[UId] [int] NULL,
[Name] [varchar](50) NULL,
[PhoneNumber] [varchar](20) NULL,
[IDNumber] [varchar](50) NULL,
[Address] [varchar](200) NULL,
[Note] [varchar](400) NULL,
[UserPassword] [varchar](max) NULL,
[HideAccount] [int] NULL,
[UserType] [varchar](50) NULL,
[IsDeleted] [int] NULL,
[UserString] [varchar](max) NULL,
 CONSTRAINT [PK_UserTable] PRIMARY KEY CLUSTERED 
(
[IdColumn] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
于 2022-02-04T10:29:55.907 回答