如何声明带有十进制变量的表变量作为标识种子?

时间:2013-07-22 19:28:37

标签: sql sql-server-2008

我正在使用它,但我无法弄清楚为什么这不起作用。除了语法不正确之外,SSMS不会给我一个有用的消息:

DECLARE @columnSeed DECIMAL
SELECT  @columnSeed = MAX([seeded_column]) + 1 FROM [table] (nolock) WHERE [conditions]
DECLARE @Temp_Table TABLE ([seeded_column] varchar(35) IDENTITY(@columnSeed, 1), [more columns])

我想从一个表中的列中获取最大值,并创建一个临时表变量,其标识列以之前的最大值为单位。

编辑:好的,在深入了解动态SQL之后我觉得我应该有什么工作,但它仍然不是:

DECLARE @columnSeed DECIMAL
[@columnSeed set properly]
EXECUTE sp_executesql 
      N'DECLARE @Temp TABLE (seeded_column decimal IDENTITY(@seed, 1) NOT NULL [more columns])',
      N'@seed decimal',
      @seed = @columnSeed;

我现在获得的所有信息都是'@seed'附近的语法不正确

2 个答案:

答案 0 :(得分:1)

您不能将变量用作种子。这是无效的语法。在执行批处理之前已隐式创建表变量,并且无论如何都已分配变量。

这样做的唯一方法是连接所需的查询并执行它。表变量的所有用法都需要在子范围内。

DECLARE @columnSeed DECIMAL(18,0) = 10

DECLARE @sql NVARCHAR(MAX) = N'DECLARE @Temp TABLE (seeded_column decimal IDENTITY(' + CAST(@columnSeed AS NVARCHAR(19)) +', 1) NOT NULL)
        INSERT INTO @Temp DEFAULT VALUES;
        SELECT * FROM @Temp;'

EXECUTE sp_executesql 
      @sql,
      N'@seed decimal',
      @seed = @columnSeed;

我确信无论如何都有更好的方式去做你正在做的事情。

您可以使用种子0在外部作用域中声明表变量,并将所需的偏移量添加到SELECT查询中。例如。

DECLARE @columnSeed DECIMAL(18,0) = 10

DECLARE @Temp TABLE (seeded_column decimal(18,0) IDENTITY(0, 1) NOT NULL)

INSERT INTO @Temp DEFAULT VALUES;
INSERT INTO @Temp DEFAULT VALUES;

SELECT @columnSeed + seeded_column AS psuedo_seeded_column 
FROM @Temp;

虽然对此的全部需求似乎令人怀疑。您通常不应关心IDENTITY值是什么。如果这是准备稍后插入表中的数据,那么您正在计算@columnSeed,可能只是插入它并使用OUTPUT子句来插入ID值可能更合适,减少并发问题的风险。

答案 1 :(得分:0)

我认为你不能在DDL中使用参数。换句话说,您将无法在@seed子句中使用IDENTITY。将种子转换为字符串并手动将其推送到DDL中。这样的事情应该有效。 (我没有方便的SQL Server实例,所以如果有任何其他错误,我很抱歉。重点是:不要在DDL语句中使用参数。)

DECLARE @columnSeed DECIMAL
DECLARE @sql NVARCHAR(1024)

[@columnSeed set properly]

SET @sql = N'DECLARE @Temp TABLE (seeded_column decimal IDENTITY(' || CONVERT(NVARCHAR, @seed) || N', 1) NOT NULL [more  columns])';

EXECUTE sp_executesql @sql