如何根据位移生成一个int主键

时间:2018-03-01 10:08:47

标签: sql sql-server bit-shift

我在sql server和VB.net上工作 我经常在int主键上使用identity(1,1)。 但今天我想创建一个表来替换枚举。我在我的程序中使用它,比如标志可以添加的内容(这是一个关于疾病的枚举,在我治疗几种疾病之前,你可以有几种疾病......但现在我想能够增加更多的疾病。)

我可以在我的vb代码中执行此操作,但我更喜欢我的SQL服务器单独关注他的密钥。但我找不到说下一个键=最后一个键<<的方法1 ???

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

SQL Server没有位移操作符 对于低至15条记录,我建议您只使用tinyint作为主键,并在输入下一行时手动输入值。

您可以让SQL Server自动为您计算,但这样做是错误的。

天真的方法会是这样的:

CREATE TABLE disease 
(
    ident tinyint identity(1,1),
    name varchar(100),
    id AS (POWER(2, ident)) PERSISTED PRIMARY KEY
)

测试:

INSERT INTO disease (name) VALUES 
('flu'), ('diabetes'), ('tonsillitis')

SELECT id, name
FROM disease

结果:

id  name
2   flu
4   diabetes
8   tonsillitis

但它很天真,因为它假定身份栏中没有间隙。 SQL Server根本不保证。

为了正确执行,您必须使用用户定义的函数计算id列,该函数实际上会计算在当前值之前输入的记录数,然后返回2的幂按这个数字。
请注意,在这种情况下,您不能保留计算列,因此它不能成为主键。

CREATE TABLE disease 
(
    ident tinyint identity(1,1) PRIMARY KEY,
    name varchar(100),
);
GO

CREATE FUNCTION fn_CalculateDiseaseId 
(
    @ident tinyint
)
returns smallint
AS
BEGIN

    RETURN
    POWER(2, 
    (
        SELECT COUNT(*)
        FROM disease
        WHERE ident < @ident
    ) +1
    )

END;
GO


ALTER TABLE disease
    ADD id AS dbo.fn_CalculateDiseaseId(ident);
GO

与以前相同的测试:

INSERT INTO disease (name) VALUES 
('flu'), ('diabetes'), ('tonsillitis')


SELECT id, name
FROM disease

结果:

id  name
2   flu
4   diabetes
8   tonsillitis

You can see a live demo of both on rextester.