如何创建一个可以用来给我一个序列值的序列表?

时间:2014-07-24 12:00:59

标签: sql-server

我一直在使用这个序列表:

CREATE SEQUENCE [dbo].[TestId1]
    AS BIGINT
    START WITH 301
    INCREMENT BY 1
    NO CACHE;

现在我意识到SQL Azure上不允许“SEQUENCE”,我需要以某种方式从普通表中创建一个序列表

有没有人对替代方案有任何想法?请注意,获取序列值时,我总是从存储过程内部获取此值。

更新

使用建议的方法并像这样调用:

DECLARE @outvalue INT; EXEC [dbo].[usp_NextLimitSequence] 'Order', 99999, @outvalue; 
Select @outvalue;

给我空虚

2 个答案:

答案 0 :(得分:0)

使用带有标识列的表,您可能会有一个包含大量记录的表,我认为这些记录是过度的。我已经使用了这个表/ proc组合多年,直到MS SQL 2012。

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;

答案 1 :(得分:0)

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

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

这会将ID返回65536,如果您需要更多,只需继续添加交叉联接,例如这将返回最多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