T-SQL标识种子表达式
是否可以在T-SQL中使用标识种子的表达式? 我们将一组表放在一起,对ID列使用T-SQL标识种子表达式,sql,sql-server,tsql,expression,identity,Sql,Sql Server,Tsql,Expression,Identity,是否可以在T-SQL中使用标识种子的表达式? 我们将一组表放在一起,对ID列使用BIGINT,但希望交错种子,以便表不会重叠其ID号空间 使用十六进制值更容易做到这一点,因此我们可以屏蔽最高的两个字节左右,例如表1的seed1*0x10000000000,表2的seed2*0x10000000000,等等,从而仍然为每个表留下大量可用的ID 这里的问题是,SQL不喜欢在IDENTITY语句中看到十六进制值或乘法,因此我们尝试手动将它们转换为BIGINT,但错误仍然存在:“语法不正确,需要整数或数
BIGINT
,但希望交错种子,以便表不会重叠其ID号空间
使用十六进制值更容易做到这一点,因此我们可以屏蔽最高的两个字节左右,例如表1的seed1*0x10000000000
,表2的seed2*0x10000000000
,等等,从而仍然为每个表留下大量可用的ID
这里的问题是,SQL不喜欢在IDENTITY
语句中看到十六进制值或乘法,因此我们尝试手动将它们转换为BIGINT
,但错误仍然存在:“语法不正确,需要整数或数字。”
似乎T-SQL不希望看到任何东西,除了一个十进制(而不是十六进制)的文本值之外,没有任何数学运算。我们可以通过自己计算并将数字转换为十进制来解决这个问题,但如果可能的话,我们希望避免这种情况,因为数字更难以十进制格式进行跟踪——容易出现错误等等 (我应该解释一下,容易出现错误,因为我们使用这些值来确定一个对象属于哪个表,仅仅基于它的ID值在适当的数字空间中——前两个字节是一种“表ID”) 然而,在使用T-SQL可以接受的一些奇怪语法的同时,是否还有其他方法可以实现我所描述的使用十六进制值和乘法的功能?
我知道这是一个不便之处,而不是阻塞问题,但我想确保在解决此解决方案之前确实没有任何替代方案。创建表时,可以设置初始种子值
创建表Table1(Id int-Identity(10000000,1),名称varchar(255))代码>
也可以对已创建的表使用此语句
DBCC CHECKIDENT('dbo.Table1',重新设定,20000000)
下一个条目将是2000001,假设您在创建表时有步骤=1,您可以设置初始种子值
创建表Table1(Id int-Identity(10000000,1),名称varchar(255))代码>
也可以对已创建的表使用此语句
DBCC CHECKIDENT('dbo.Table1',重新设定,20000000)
下一个条目将是2000001,假设您在创建表时有步骤=1,您可以设置初始种子值
创建表Table1(Id int-Identity(10000000,1),名称varchar(255))代码>
也可以对已创建的表使用此语句
DBCC CHECKIDENT('dbo.Table1',重新设定,20000000)
下一个条目将是2000001,假设您在创建表时有步骤=1,您可以设置初始种子值
创建表Table1(Id int-Identity(10000000,1),名称varchar(255))代码>
也可以对已创建的表使用此语句
DBCC CHECKIDENT('dbo.Table1',重新设定,20000000)
下一个条目将是2000001,假设您有步骤=1只需使用动态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;
我相信正则表达式会改进它。只需使用动态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;
我相信正则表达式会改进它。只需使用动态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;
我相信正则表达式会改进它。只需使用动态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;
我相信正则表达式会改进它。为此表创建一个触发器(在插入之前),并禁用标识
将十六进制转换为整数:
例如:
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
为此表创建触发器(在插入之前),并禁用标识
将十六进制转换为整数:
例如:
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
为此表创建触发器(在插入之前),并禁用标识
将十六进制转换为整数:
例如:
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
为此表创建触发器(在插入之前),并禁用标识
将十六进制转换为整数:
例如:
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
这是我听说过的最奇怪的事情之一?你到底为什么要那样做?我怀疑,如果您想这样做,您的表结构设计得很糟糕。我建议更好的解决方案是按预期使用标识。如果您需要一个字段来明确某个表来自哪个表,那么创建一个计算列,在每个id字段的开头添加一个字母,并让字母确定该表。这种想法是最糟糕的。你不应该那样贬低你的身份。你实际上是在试图将意义插入一个无意义的值中。如果你真的认为你需要这样做,那么你应该考虑为每个表格使用一个序列。这是我听过的最怪异的事情之一。你到底为什么要那样做?我怀疑,如果您想这样做,您的表结构设计得很糟糕。我建议更好的解决方案是按预期使用标识。如果您需要一个字段来明确某个表来自哪个表,那么创建一个计算列,在每个id字段的开头添加一个字母,并让字母确定该表。这种想法是最糟糕的。你不应该那样贬低你的身份。你实际上是在试图将意义插入一个无意义的值中。如果你真的认为你需要这样做,那么你应该考虑为每个表格使用一个序列。这是我听过的最怪异的事情之一。你到底为什么要那样做?我怀疑,如果您想这样做,您的表结构设计得很糟糕。我建议更好的解决方案是按预期使用标识。如果您需要一个字段来明确某个表来自哪个表,那么创建一个计算列,在每个id字段的开头添加一个字母,并让字母确定该表。这种想法是最糟糕的。你