Sql server 我如何创建一个序列表,我可以使用它来给我一个序列值?

Sql server 我如何创建一个序列表,我可以使用它来给我一个序列值?,sql-server,Sql Server,我一直在使用以下序列表: CREATE SEQUENCE [dbo].[TestId1] AS BIGINT START WITH 301 INCREMENT BY 1 NO CACHE; 现在我意识到SQLAzure上不允许使用序列,我需要以某种方式从普通表生成序列表 有人对替代方案有什么想法吗?请注意,在获取序列值时,我总是从存储过程内部获取该值 更新: 使用建议的方法并按如下方式调用: DECLARE @outvalue INT; EXEC [dbo].[

我一直在使用以下序列表:

CREATE SEQUENCE [dbo].[TestId1]
    AS BIGINT
    START WITH 301
    INCREMENT BY 1
    NO CACHE;
现在我意识到SQLAzure上不允许使用序列,我需要以某种方式从普通表生成序列表

有人对替代方案有什么想法吗?请注意,在获取序列值时,我总是从存储过程内部获取该值

更新:

使用建议的方法并按如下方式调用:

DECLARE @outvalue INT; EXEC [dbo].[usp_NextLimitSequence] 'Order', 99999, @outvalue; 
Select @outvalue;
WITH
    B0 AS(SELECT 1 [C] UNION ALL SELECT 1),
    B1 AS(SELECT 1 [C] FROM B0 [A] CROSS JOIN B0 [B] CROSS JOIN B0 [C] CROSS JOIN B0 [D]),
    B2 AS(SELECT 1 [C] FROM B1 [A] CROSS JOIN B1 [B] CROSS JOIN B1 [C] CROSS JOIN B1 [D]),
    Tally AS(SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) [Id] FROM B2) 
SELECT *
FROM Tally
WHERE Id > 300

给我空值

使用带有标识列的表时,您可能会有一个包含大量记录的表,我认为这太过分了。我已经使用这个table/proc组合很多年了,直到MSSQL2012

CREATE TABLE [dbo].[SequenceTable]
(
[SequenceName] [varchar] (10) NOT NULL,
[Value] [int] NOT NULL
)
GO
ALTER TABLE [dbo].[SequenceTable] ADD CONSTRAINT [PK_Sequence] PRIMARY KEY CLUSTERED  ([SequenceName])
GO

create procedure [dbo].[usp_NextLimitSequence]
(
  @sequenceName varchar(10),
  @limit int,
  @value int out
)
as 
begin

  begin transaction

    update [SequenceTable]
    set [Value] = case when [Value] >= @limit then 0 else [Value] + 1 END,
        @value = case when [Value] >= @limit then 0 else [Value] + 1 END
    where SequenceName = @sequenceName;

    if ( @@ROWCOUNT = 0 ) begin
      insert into [dbo].[SequenceTable] ( SequenceName, Value )
      values ( @sequenceName, 1 );
      SET @value = 1;
    end;

  commit work

end;
编辑:这是一个更精简的过程,没有上限参数

ALTER procedure [dbo].[usp_NextLimitSequence]
(
  @sequenceName varchar(10),
  @value int out
)
as 
begin

  begin transaction

    update [SequenceTable]
    set [Value] = [Value] + 1,
        @value = [Value] + 1
    where SequenceName = @sequenceName;

    if ( @@ROWCOUNT = 0 ) begin
      insert into [dbo].[SequenceTable] ( SequenceName, Value )
      values ( @sequenceName, 1 );
      SET @value = 1;
    end;

  commit work

end;

如果您只想生成一系列数字,可以生成如下的理货表:

DECLARE @outvalue INT; EXEC [dbo].[usp_NextLimitSequence] 'Order', 99999, @outvalue; 
Select @outvalue;
WITH
    B0 AS(SELECT 1 [C] UNION ALL SELECT 1),
    B1 AS(SELECT 1 [C] FROM B0 [A] CROSS JOIN B0 [B] CROSS JOIN B0 [C] CROSS JOIN B0 [D]),
    B2 AS(SELECT 1 [C] FROM B1 [A] CROSS JOIN B1 [B] CROSS JOIN B1 [C] CROSS JOIN B1 [D]),
    Tally AS(SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) [Id] FROM B2) 
SELECT *
FROM Tally
WHERE Id > 300
这将返回高达65536的Id,如果您需要更多,只需继续添加交叉联接,例如,这将返回高达16777216的数字:

WITH
    B0 AS(SELECT 1 [C] UNION ALL SELECT 1),
    B1 AS(SELECT 1 [C] FROM B0 [A] CROSS JOIN B0 [B] CROSS JOIN B0 [C] CROSS JOIN B0 [D]),
    B2 AS(SELECT 1 [C] FROM B1 [A] CROSS JOIN B1 [B] CROSS JOIN B1 [C] CROSS JOIN B1 [D] CROSS JOIN B1 [E] CROSS JOIN B1 [F]),
    Tally AS(SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) [Id] FROM B2) 
SELECT *
FROM Tally
WHERE Id > 300

最简单的替代方法是标识列。这不是一个确切的替代品,但将为您提供所需的功能。谢谢,但我有很多理由不去身份栏路线。一个是我需要一个字符串作为序列号。首先,我从seq中得到一个整数,然后将其转换为字符串。至少在我尝试部署到SQL Azure之前我一直在这么做:-理货表是什么样子的?它不是一个实际的表,它是一个通用的表表达式,返回一个只包含一个名为Id的列的表。只需在management studio中运行上面的第一个脚本,您就会看到。第二个脚本需要一些时间,返回16 mil行:您的解决方案看起来很有趣。如何从存储过程中调用它;EXEC[dbo].[usp_NextLimitSequence]'OrderNumber',99999,@outvalue;可以重新写入以消除上限开关。是的,我不确定限制是什么。你能告诉我它是如何使用的,或者告诉我没有它的情况下程序会是什么样子吗。我尝试了您的代码来声明和获取值,但它抱怨了错误。然后我删除了它,但它返回一个null值作为序列值。我只是更新了这个问题,以显示当我使用你提到的方法调用它时会发生什么。你能让我知道,如果你有任何想法,为什么它是输出空。我做了检查,它似乎增加了表中的值。