在 SQL 服务器自动递增键列中包含其他字符和符号
Including other characters and symbols in a SQL Server auto incrementing key column
我已经开始做一个项目了。除了基本信息,我没有太多经验。我只想问我可以在主键列中使用符号,如 2015/1234
等。这些是文件编号,必须是唯一的,所以我决定将它们设为主键,但我不确定我是否可以使用符号和如果我可以使用,我可以使用像
这样的自动递增吗
2015/1234, 2015/1235 ... etc.
其中 2015 是年份数字。每个新的一年第二个序列号必须重置为1。
编辑:如果可以,我应该使用哪种数据类型?
自动递增(identity
in T-SQL)只能用于整数。它还限制了列的插入方式。解决您的要求的一种方法可能是将数字范围分配给特定年份(2014、2015 等),然后在查询中将这些数字转换回文件名,例如:2014 年为 1-1000000,2015 年为 1000001-2000000 等等在。在 select 语句中,您可以使用类似
的语句
Select cast(floor(id/1000000)+2014 as char(4))+'/'+cast(id % 1000000 as varchar(6)) mykey ... from table
但一般来说,我认为最好使用单独的编号 table,例如
mumtbl:
----------
year mxidx_used
---------------------
2014 234
2015 1678
并将其用作要生成的新密钥的查找(并且不要忘记之后更新那里的最大值)。
您可以通过将 FileNumber
的类型更改为 VARCHAR(x)
,使您的文件编号成为主键,但假设您想要 sequence part
(即 1234
)每年要重置的文件编号的一部分,您将无法利用标识列(Sql 服务器的自动递增值),因为这将在每年之后继续增加。
您可以保留 VARCHAR FileNumber
PK 并自己管理文件编号生成,但我建议不要这样做 - 它不利于并发,因为同时插入的两个编写器需要竞争 'next' 序列号的值——这通常会导致在插入之前出现可怕的、锁定的 SELECT MAX...
查询,或者外部 'next value' table,尽管在 Sql Server 2012+ 中, a Sequence 会为您管理。
相反,我建议只使用代理积分身份(例如 ID INT IDENTITY(1,1)
作为 PK - Sql 服务器将处理并发性,其他 FK 引用你的 table.
然后,添加编码的自然/复合 FileNumber
字段,并包含一个额外的唯一键约束列,或者更好的是,将 FileNumber
分成两个单独的列的组成部分,即 Year int
和 SequenceInYear int
。然后,您始终可以使用计算列重新生成完整的 FileNumber
字符串。
实施
绝对假设您不能将新文件插入旧年份,我会这样做:
CREATE SEQUENCE NextValueForCurrentYear
START WITH 1
INCREMENT BY 1 ;
CREATE TABLE MyTable
(
-- Narrow surrogate key managed by Sql
ID INT IDENTITY(1,1) NOT NULL CONSTRAINT PK_MyTable PRIMARY KEY,
-- Provided during insert, or retrieved from some config table
[Year] INT NOT NULL,
-- Auto incrementing sequence
SequenceNoInYear INT NOT NULL CONSTRAINT DF_SequenceNoInYear
DEFAULT NEXT value FOR NextValueForCurrentYear,
-- Computed column - can be read, generated automatically
FileNumber AS CAST([Year] AS VARCHAR(4)) + '/' +
CAST(SequenceNoInYear AS VARCHAR(10)),
-- Other Columns here
-- Ensure filenumber is unique
CONSTRAINT UQ_MyTable UNIQUE([Year], SequenceNoInYear)
);
您只需提供年份,其余的将自动生成,即
INSERT INTO MyTable(Year) VALUES (2015);
如果您需要每年从 1 开始序列号,那么您每年都需要 reset the Sequence。
[Year], SequenceNoInYear
上的唯一键约束将防止在重置序列号后插入旧年份。
最好的解决方案是使用
- 一个
ID INT IDENTITY(1,1)
列获取SQL服务器来处理你的数值的自动递增
- 一个计算的、持久的列,用于将该数值转换为您需要的值
所以试试这个:
CREATE TABLE dbo.YourTable
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
SomeDateColumn DATE,
YourCompoundID AS RIGHT('00000' + CAST(ID AS VARCHAR(5)), 5) + '/' + CAST(YEAR(SomeDateColumn) AS VARCHAR(4)) PERSISTED,
.... your other columns here....
)
现在,每次在 tblCompany
中插入一行而不指定 ID
或 CompanyID
的值时:
INSERT INTO dbo.YourTable(SomeDateColumn, Col1, Col2, ..., ColN)
VALUES ('20150725', Val1, Val2, ....., ValN)
然后 SQL 服务器将 自动安全地 增加您的 ID
值,并且 YourCompoundID
将包含像 00001/2015
这样的值, 00002/2015
,......等等 - 自动、安全、可靠。
你必须在你的情况下创建一个主键设置初始值 1233 并根据你的要求制定你的 FileID 只是 运行 我在你的数据库中的查询并尝试在 table 中手动插入名称你看到你得到了你的结果我希望这会帮助你
/****** Object: Table [dbo].[tblStringPrimaryKey] Script Date: 7/25/2015 3:32:42 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tblStringPrimaryKey](
[Id] [int] IDENTITY(1233,1) NOT NULL,
[FileId] AS ((CONVERT([nvarchar](10),datepart(year,getdate()))+'/')+CONVERT([nvarchar](22),[Id])),
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_tblStringPrimaryKey] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [IX_tblStringPrimaryKey] UNIQUE NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
我已经开始做一个项目了。除了基本信息,我没有太多经验。我只想问我可以在主键列中使用符号,如 2015/1234
等。这些是文件编号,必须是唯一的,所以我决定将它们设为主键,但我不确定我是否可以使用符号和如果我可以使用,我可以使用像
2015/1234, 2015/1235 ... etc.
其中 2015 是年份数字。每个新的一年第二个序列号必须重置为1。
编辑:如果可以,我应该使用哪种数据类型?
自动递增(identity
in T-SQL)只能用于整数。它还限制了列的插入方式。解决您的要求的一种方法可能是将数字范围分配给特定年份(2014、2015 等),然后在查询中将这些数字转换回文件名,例如:2014 年为 1-1000000,2015 年为 1000001-2000000 等等在。在 select 语句中,您可以使用类似
Select cast(floor(id/1000000)+2014 as char(4))+'/'+cast(id % 1000000 as varchar(6)) mykey ... from table
但一般来说,我认为最好使用单独的编号 table,例如
mumtbl:
----------
year mxidx_used
---------------------
2014 234
2015 1678
并将其用作要生成的新密钥的查找(并且不要忘记之后更新那里的最大值)。
您可以通过将 FileNumber
的类型更改为 VARCHAR(x)
,使您的文件编号成为主键,但假设您想要 sequence part
(即 1234
)每年要重置的文件编号的一部分,您将无法利用标识列(Sql 服务器的自动递增值),因为这将在每年之后继续增加。
您可以保留 VARCHAR FileNumber
PK 并自己管理文件编号生成,但我建议不要这样做 - 它不利于并发,因为同时插入的两个编写器需要竞争 'next' 序列号的值——这通常会导致在插入之前出现可怕的、锁定的 SELECT MAX...
查询,或者外部 'next value' table,尽管在 Sql Server 2012+ 中, a Sequence 会为您管理。
相反,我建议只使用代理积分身份(例如 ID INT IDENTITY(1,1)
作为 PK - Sql 服务器将处理并发性,其他 FK 引用你的 table.
然后,添加编码的自然/复合 FileNumber
字段,并包含一个额外的唯一键约束列,或者更好的是,将 FileNumber
分成两个单独的列的组成部分,即 Year int
和 SequenceInYear int
。然后,您始终可以使用计算列重新生成完整的 FileNumber
字符串。
实施
绝对假设您不能将新文件插入旧年份,我会这样做:
CREATE SEQUENCE NextValueForCurrentYear
START WITH 1
INCREMENT BY 1 ;
CREATE TABLE MyTable
(
-- Narrow surrogate key managed by Sql
ID INT IDENTITY(1,1) NOT NULL CONSTRAINT PK_MyTable PRIMARY KEY,
-- Provided during insert, or retrieved from some config table
[Year] INT NOT NULL,
-- Auto incrementing sequence
SequenceNoInYear INT NOT NULL CONSTRAINT DF_SequenceNoInYear
DEFAULT NEXT value FOR NextValueForCurrentYear,
-- Computed column - can be read, generated automatically
FileNumber AS CAST([Year] AS VARCHAR(4)) + '/' +
CAST(SequenceNoInYear AS VARCHAR(10)),
-- Other Columns here
-- Ensure filenumber is unique
CONSTRAINT UQ_MyTable UNIQUE([Year], SequenceNoInYear)
);
您只需提供年份,其余的将自动生成,即
INSERT INTO MyTable(Year) VALUES (2015);
如果您需要每年从 1 开始序列号,那么您每年都需要 reset the Sequence。
[Year], SequenceNoInYear
上的唯一键约束将防止在重置序列号后插入旧年份。
最好的解决方案是使用
- 一个
ID INT IDENTITY(1,1)
列获取SQL服务器来处理你的数值的自动递增 - 一个计算的、持久的列,用于将该数值转换为您需要的值
所以试试这个:
CREATE TABLE dbo.YourTable
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
SomeDateColumn DATE,
YourCompoundID AS RIGHT('00000' + CAST(ID AS VARCHAR(5)), 5) + '/' + CAST(YEAR(SomeDateColumn) AS VARCHAR(4)) PERSISTED,
.... your other columns here....
)
现在,每次在 tblCompany
中插入一行而不指定 ID
或 CompanyID
的值时:
INSERT INTO dbo.YourTable(SomeDateColumn, Col1, Col2, ..., ColN)
VALUES ('20150725', Val1, Val2, ....., ValN)
然后 SQL 服务器将 自动安全地 增加您的 ID
值,并且 YourCompoundID
将包含像 00001/2015
这样的值, 00002/2015
,......等等 - 自动、安全、可靠。
你必须在你的情况下创建一个主键设置初始值 1233 并根据你的要求制定你的 FileID 只是 运行 我在你的数据库中的查询并尝试在 table 中手动插入名称你看到你得到了你的结果我希望这会帮助你
/****** Object: Table [dbo].[tblStringPrimaryKey] Script Date: 7/25/2015 3:32:42 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tblStringPrimaryKey](
[Id] [int] IDENTITY(1233,1) NOT NULL,
[FileId] AS ((CONVERT([nvarchar](10),datepart(year,getdate()))+'/')+CONVERT([nvarchar](22),[Id])),
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_tblStringPrimaryKey] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [IX_tblStringPrimaryKey] UNIQUE NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO