我已经开始研究一个项目了。除基本信息外,我没有太多经验。我只想问我可以在主键列中使用符号,如2015/1234
等。这些是文件编号,必须是唯一的,所以我决定将它们作为主键,但我不确定是否可以使用符号,如果我可以使用,我可以使用像
2015/1234, 2015/1235 ... etc.
2015年是年份数。第二个序列号必须在每个新年重置为1。
编辑:如果可以使用我应该使用的所有数据类型?
答案 0 :(得分:1)
您可以将FileNumber
的类型更改为VARCHAR(x)
,但假设您需要sequence part
(即1234
),则可以将您的文件编号设为主键每年要重置的文件号,你将无法利用标识列(Sql Server的自动递增值),因为这将在每年后继续增加。
你可以保留一个VARCHAR FileNumber
PK并自己管理文件编号生成,但我建议不要这样做 - 它对并发性有害,因为两个同时插入的编写器需要争用的“下一个”值。序列号 - 这通常会导致插入前的可怕锁定SELECT MAX...
查询或外部“下一个值”表,尽管在Sql Server 2012+中,a Sequence会为您管理此问题。
相反,我建议只使用代理积分标识(例如ID INT IDENTITY(1,1)
作为PK - Sql Server将处理并发性,其他FK引用您的表格的范围更窄。
然后,添加您编码的自然/复合FileNumber
字段,并包含一个额外的唯一键约束列,或者更好,只需将FileNumber
作为两个单独的列分隔为Year int
,即{{1 }和SequenceInYear int
。然后,您始终可以使用计算列重新生成完整的FileNumber
字符串。
<强>实施强>
绝对假设您无法将新文件插入OLD年,以下是我将如何执行此操作:
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
上的唯一键约束将防止在序列号重置后插入旧年。
答案 1 :(得分:1)
最好的解决方案是使用
ID INT IDENTITY(1,1)
列,以使SQL Server处理数值的自动增量所以试试这个:
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 Server将自动且安全地增加ID
值,而YourCompoundID
将包含00001/2015
,00002/2015
等值。 ....等等 - 自动,安全,可靠。
答案 2 :(得分:0)
自动增量(T-SQL中的identity
)只能用于整数。它还限制了列的插入方式。解决您的要求的一种方法可能是将数字范围分配给特定年份(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
但总的来说,我认为最好使用单独的编号表,如
mumtbl:
----------
year mxidx_used
---------------------
2014 234
2015 1678
并将其用作查找要生成的新密钥(并且不要忘记随后更新其中的最大值)。
答案 3 :(得分:0)
你必须在你的情况下创建一个主键设置初始值1233并根据你的要求制定你的FileID只需在你的数据库中运行我的查询并尝试在表中插入manuaaly你看到你得到你的结果我希望这将帮助你
/****** 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