我有一个问题,如何在 MS SQL 中实现自动增量。到目前为止我知道的一种方法是在表格中进行修正,例如
CREATE TABLE Customer (
CUSId INT NOT NULL IDENTITY(1, 1) PRIMARY KEY
,CUSKey AS 'Cus' + RIGHT('000' + CONVERT(VARCHAR(5), CUSId), 6) PERSISTED
,CusName VARCHAR(50)
,mobileno INT
,Gender VARCHAR(10)
)
Run Code Online (Sandbox Code Playgroud)
我会得到类似的东西
Cus0001
Cus0002
Run Code Online (Sandbox Code Playgroud)
Cus9999 之后呢?
一些如何实现这样的自动增量
CUSAB000001
CUSAB000002
CUSAB000003
CUSAB000004
CUSAB000005
CUSAB000006
CUSAB000007
CUSAB000008
CUSAB999999
CUSCD000001
CUSYZ999999.
Run Code Online (Sandbox Code Playgroud)
为了增加开始于AA和结束于 的组ZZ,您需要将数字的左侧部分(高于您要保留为整数的位数)转换为基数 26。首先截断数字的右侧部分这样你就只有左边的部分,然后你除以 10 ^ IntegerDigits(例如 3 个整数数字 == 10 ^ 3 == 1000)得到A_边,然后在同一个 10 ^ IntegerDigits 上使用模来得到_A边。这些值将为我们提供与 ASCII 值的偏移量A。例如:
SELECT (123142 / 1000) AS [Truncated],
(123142 / 1000) / 26 AS [SetsOf26],
(123142 / 1000) % 26 AS [Remaining],
CHAR(65) AS [A];
-- Truncated = 123
-- SetsOf26 = 4
-- Remaining = 19
-- A = A
Run Code Online (Sandbox Code Playgroud)
我们可以将所有这些放在一个内联 TVF 中(用于演示目的,而不是用于表中的计算列),如下所示:
CREATE FUNCTION dbo.Base26 (@Base10 INT)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN
WITH truncated AS
(
SELECT (@Base10 / 1000) AS [Value]
)
SELECT @Base10 AS [Actual],
tr.Value AS [Truncated],
CHAR(65 + (tr.Value / 26)) AS [1stChar],
CHAR(65 + (tr.Value % 26)) AS [2ndChar],
CHAR(65 + (tr.Value / 26))
+ CHAR(65 + (tr.Value % 26))
+ RIGHT('00' + CONVERT(VARCHAR(20), @Base10 % 1000), 3) AS [EndResult]
FROM truncated tr;
GO
Run Code Online (Sandbox Code Playgroud)
然后我们可以测试:
SELECT * FROM dbo.Base26(142);
SELECT * FROM dbo.Base26(3142);
SELECT * FROM dbo.Base26(123142);
SELECT * FROM dbo.Base26(123999);
Run Code Online (Sandbox Code Playgroud)
返回:
SELECT (123142 / 1000) AS [Truncated],
(123142 / 1000) / 26 AS [SetsOf26],
(123142 / 1000) % 26 AS [Remaining],
CHAR(65) AS [A];
-- Truncated = 123
-- SetsOf26 = 4
-- Remaining = 19
-- A = A
Run Code Online (Sandbox Code Playgroud)
但是,我认为完全没有理由在您的情况下实施此操作。使用字符串“CusXXXXXX”值没有任何好处,其中“XXXXXX”实际上只是IDENTITY值。如果您打算通过散列或模块化乘法逆来混淆“XXXXXX”,那么它可能没问题,但我仍然不确定您是否想要存储它的“Cus”字符串部分。但在目前的形式下,你不会从这样做中获得任何好处。您只是在浪费数据库中的空间。
其他注意事项:
CustomerID, 和CustomerName。INT)来存储电话号码。不进行数学运算的数字应存储为字符串。这也适用于邮政编码、社会安全号码 (SSN) 等。就电话号码而言,它们通常具有扩展名或其他非数字选项,例如+如果它们位于基准国家/地区之外,则使用前缀。您不应该使用字符串类型(即VARCHAR(10))来存储重复的代码/标签,例如“性别”(假设正在存储完整的“男性”和“女性”或类似词,并且非二进制/_BIN2排序规则是正在使用)。你应该有一个“对接”查找表GenderID TINYINT列作为主键(而不是一个IDENTITY)。然后在Customer表中你也会有,GenderID TINYINT但它会是一个外键引用dbo.Gender (GenderID)。
或者:
您可以使用CHAR(1) COLLATE Latin1_General_100_BIN2 NOT NULL带有CHECK约束的列来强制执行M并且F是可接受的。这为您提供了一个人类可读的“代码”,同时在存储、内存和比较方面仍然像 a 一样高效TINYINT。
请阅读这篇优秀的文章。
http://www.sqlteam.com/article/custom-auto- generated-sequences-with-sql-server
请注意,dbID 列是标准的、数据库生成的标识,它将成为表的物理主键。但是,我们将添加一个 CustomerNumber 列,这将是我们以“C0000”格式向外界公开的列,如上所述。
让我们创建一个接受整数的函数,并使用该整数返回我们的 CustomerNumber:
create function CustomerNumber (@id int)
returns char(5)
as
begin
return 'C' + right('0000' + convert(varchar(10), @id), 4)
end
Run Code Online (Sandbox Code Playgroud)
使用该函数,我们可以简单地将计算列添加到表中,如下所示:
alter table Customers add CustomerNumber as dbo.CustomerNumber(dbID)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18652 次 |
| 最近记录: |