SQL Server 序列设置当前值

问题描述 投票:0回答:3

我正在使用 SQL Server 2012 (v11.0.2100),我想创建一个以随机(动态)数字开头的序列,但我无法做到这一点,我也努力为此找到一个好的解决方案但我还没有找到令我满意的东西。

我尝试过但失败的案例:

 DECLARE @sth bigint

 SET @sth = 1000

 ALTER SEQUENCE StreamEntrySequence
 RESTART WITH @sth;

错误:

“@sth”附近的语法不正确

一个丑陋的解决方案

 declare @sth bigint;
 declare @i bigint;

 SET @sth = 100000    ; 

 while @i<@sth;
 BEGIN
    SET @i= next value for StreamEntrySequence;
 END

还有其他方法可以将当前值或起始值设置为随机值吗?也许使用服务器程序?

sql-server sequence
3个回答
34
投票

正如已经提到的,这将需要动态 SQL,因为 alterequence 需要

restart
参数的常量。

你可能会做这样的事情,然后:

DECLARE @sth bigint;
SET @sth = 1000;
DECLARE @sql nvarchar(max);
SET @sql = N'ALTER SEQUENCE StreamEntrySequence RESTART WITH ' + cast(@sth as nvarchar(20)) + ';';
EXEC SP_EXECUTESQL @sql;

18
投票

尝试

ALTER SEQUENCE foo.fee
RESTART

或者:

ALTER SEQUENCE foo.fee
RESTART WITH 1

http://msdn.microsoft.com/en-us/library/ff878572.aspx


0
投票

这是一种替代解决方案(它保留原始参数,并且仍然不需要循环来一次递增序列一个)。基本上,分三步进行;将 INCREMENT 值更改为所需 CURRENT_VALUE 与实际 CURRENT_VALUE 之间的差值,调用序列将其增加差值,然后恢复原始 INCRMENT 值。

DECLARE @SchemaName VARCHAR(255) = 'SCHEMA'
DECLARE @SequenceName VARCHAR(255) = 'SEQUENCE'

DECLARE @CurrentValueRequired INT
SELECT @CurrentValueRequired = 1000000 --could be assigned from a SELECT query as well
PRINT '@CurrentValueRequired=' + CAST(@CurrentValueRequired AS VARCHAR(20))

DECLARE @CurrentValueActual BIGINT
DECLARE @LastUsedValue BIGINT
DECLARE @IncrementValue BIGINT
DECLARE @CurrentValueDifference BIGINT
SELECT @CurrentValueActual = CAST(CURRENT_VALUE AS BIGINT),
       @LastUsedValue = CAST(LAST_USED_VALUE AS BIGINT),
       @IncrementValue = CAST(INCREMENT AS BIGINT)
FROM   SYS.SEQUENCES
WHERE  NAME = @SequenceName
SET @CurrentValueDifference = @CurrentValueRequired - @CurrentValueActual
PRINT '@CurrentValueActual=' + CAST(@CurrentValueActual AS VARCHAR(30))
PRINT '@LastUsedValue=' + CASE WHEN @LastUsedValue IS NULL THEN 'NULL' ELSE CAST(@LastUsedValue AS VARCHAR(30)) END
PRINT '@IncrementValue=' + CAST(@IncrementValue AS VARCHAR(30))
PRINT '@CurrentValueDifference=' + cast(@CurrentValueDifference AS VARCHAR(30))

IF @CurrentValueDifference > 0
BEGIN
    DECLARE @sql NVARCHAR(MAX)

    -- If LAST_USED_VALUE is NULL, then the sequence has NEVER been accessed since it's creation. Call it once so that it's START_WITH value becomes the LAST_USED_VALUE.
    IF @LastUsedValue IS NULL
    BEGIN
        PRINT '@LastUsedValue IS NULL'
        SET @sql = N'DECLARE @NextValue BIGINT; SELECT @NextValue = NEXT VALUE FOR ' + @SchemaName + '.' + @SequenceName
        PRINT @sql
        EXEC SP_EXECUTESQL @sql;
        SELECT @CurrentValueActual = CAST(CURRENT_VALUE AS BIGINT), @LastUsedValue = CAST(LAST_USED_VALUE AS BIGINT) FROM SYS.SEQUENCES WHERE NAME = @SequenceName
        PRINT '@CurrentValueActual=' + CAST(@CurrentValueActual AS VARCHAR(30))
        PRINT '@LastUsedValue=' + CASE WHEN @LastUsedValue IS NULL THEN 'NULL' ELSE CAST(@LastUsedValue AS VARCHAR(30)) END
    END

    -- Set the INCREMENT value to the difference between the required CURRENT_VALUE and the actual CURRENT_VALUE
    SET @sql = N'ALTER SEQUENCE ' + @SchemaName + '.' + @SequenceName + ' INCREMENT BY ' + CAST(@CurrentValueDifference AS NVARCHAR(30)) + ';'
    PRINT @sql
    EXEC SP_EXECUTESQL @sql;

    -- Now call the sequence to increment it once by the difference value
    SET @sql = N'DECLARE @NextValue BIGINT; SELECT @NextValue = NEXT VALUE FOR ' + @SchemaName + '.' + @SequenceName
    PRINT @sql
    EXEC SP_EXECUTESQL @sql;
    SELECT @CurrentValueActual = CAST(CURRENT_VALUE AS BIGINT), @LastUsedValue = CAST(LAST_USED_VALUE AS BIGINT) FROM SYS.SEQUENCES WHERE NAME = @SequenceName
    PRINT '@CurrentValueActual=' + CAST(@CurrentValueActual AS VARCHAR(30))
    PRINT '@LastUsedValue=' + CASE WHEN @LastUsedValue IS NULL THEN 'NULL' ELSE CAST(@LastUsedValue AS VARCHAR(30)) END

    -- Set the INCREMENT back to the original value
    SET @sql = N'ALTER SEQUENCE ' + @SchemaName + '.' + @SequenceName + ' INCREMENT BY ' + CAST(@IncrementValue AS NVARCHAR(30)) + ';'
    PRINT @sql
    EXEC SP_EXECUTESQL @sql;
END
ELSE
BEGIN
    PRINT 'NOTHING TO DO!'
END
© www.soinside.com 2019 - 2024. All rights reserved.