T-SQL身份种子表达

时间:2015-06-25 17:55:33

标签: sql sql-server tsql expression identity

是否可以在T-SQL中使用表达式来识别种子? 我们将一堆表放在一起,使用BIGINT作为ID列,但是想要错开种子,以便表格不与ID号空格重叠。

使用十六进制值更容易做到这一点,因此我们可以屏蔽最高的两个字节左右,例如table1的种子1 * 0x1000000000000和table2的种子2 * 0x1000000000000等 - 从而仍然离开每张桌子都有很多可用的ID。

这里的问题是,SQL不喜欢在IDENTITY语句中看到十六进制值或乘法,所以我们尝试将它们手动转换为BIGINT,但错误仍然存​​在:&#34 ;语法不正确,预期为INTEGER或NUMERIC。"

似乎T-SQL不希望看到除单个文字值之外的任何内容,十进制(非十六进制),没有数学运算。
我们可以通过自己进行数学处理并将数字转换为十进制来处理这个问题 - 但是如果可能的话,我们希望避免这种情况,因为数字更难以跟踪十进制格式 - 容易出错等等。

(我应该解释一下,容易出错,因为我们使用这些值来确定一个对象属于哪个表,完全基于它的ID值在适当的数字空间中 - 前两个字节是一个排序"表ID")

然而,是否有其他方法可以实现我使用十六进制值和乘法的描述,同时使用T-SQL可以接受的一些奇怪的语法?
我知道这是一个不便,而不是阻塞问题,但我想确保在我们解决这个问题之前确实没有任何替代方案。

3 个答案:

答案 0 :(得分:2)

Just blend bad ideas by using dynamic SQL: declare @Bar as BigInt = 0x1000000000000; declare @Foo as NVarChar(1000) = 'dbcc checkident(''Foo'', RESEED, ' + cast( 2 * @Bar as NVarChar(64) ) + ')'; exec sp_executesql @Foo; I'm sure a RegEx would improve it.

答案 1 :(得分:0)

When you create the table you can set the initial seed value.

create table Table1(Id int Identity(10000000,1), Name varchar(255));

or you can use this statement on a table that is already created

DBCC CHECKIDENT ('dbo.Table1', RESEED, 20000000);

The next entry will be 20000001 assuming you have the step = 1

答案 2 :(得分:0)

为此表创建一个触发器(在插入之前),并禁用标识。

将Hex转换为int:Convert integer to hex and hex to integer

示例:

CREATE TRIGGER TRIGGER_NAME 
ON TABLE_NAME 
INSTEAD OF INSERT
AS
BEGIN
    IF (SELECT ID FROM INSERTED) IS NULL
    BEGIN
        DECLARE @INITIAL_ID BIGINT = (SELECT CONVERT(BIGINT, 0x1000000000000) * 2)
        DECLARE @NEW_ID BIGINT = 
            ISNULL( (SELECT MAX(ID) FROM TABLE_NAME) + 1, @INITIAL_ID )
        SELECT * INTO #INSERTED FROM INSERTED
        UPDATE #INSERTED SET ID = @NEW_ID
        INSERT INTO TABLE_NAME SELECT * FROM #INSERTED
    END
    ELSE
    BEGIN
        INSERT INTO TABLE_NAME SELECT * FROM INSERTED
    END
END
GO