Sql server 是否仍然需要重置表变量的标识?

Sql server 是否仍然需要重置表变量的标识?,sql-server,tsql,sql-server-2008,Sql Server,Tsql,Sql Server 2008,假设我有一个表变量: DECLARE @MyTableVar TABLE (ID INT IDENTITY(1,1), SomeData NVARCHAR(300)) 插入250行之后,我需要用表“重新开始”。我这样做: DELETE FROM @MyTableVar 我是否可以对表变量执行任何操作,以便: insert into @MyTableVar Values("TestData") select * from @MyTableVar 将返回此文件: _______________

假设我有一个表变量:

DECLARE @MyTableVar TABLE (ID INT IDENTITY(1,1), SomeData NVARCHAR(300))
插入250行之后,我需要用表“重新开始”。我这样做:

DELETE FROM @MyTableVar
我是否可以对表变量执行任何操作,以便:

insert into @MyTableVar Values("TestData")
select * from @MyTableVar
将返回此文件:

_______________________________ | ID | SomeData | |___________|_________________| | | | | 1 | TestData | |___________|_________________| _______________________________ |ID | SomeData| |___________|_________________| | | | |1 |测试数据| |___________|_________________| 与此相反:

_______________________________ | ID | SomeData | |___________|_________________| | | | | 251 | TestData | |___________|_________________| _______________________________ |ID | SomeData| |___________|_________________| | | | |251 |测试数据|
|___________|_________________| 与其依赖于一个标识,为什么不使用新的排名函数,比如Row_Number

Insert @MyTableVar( Id, Value )
Select Row_Number() Over ( Order By Value )
    , Value
From SomeOtherTable

你们能用临时桌子吗? 这是一个如何使用临时表执行此操作的示例

CREATE TABLE #MyTableVar (ID INT IDENTITY(1,1), SomeData NVARCHAR(300))

insert #MyTableVar(SomeData) values ('test1'), ('test2')

---doesn't work
DELETE FROM #MyTableVar 

insert #MyTableVar(SomeData) values ('test3'), ('test4')
select * from #MyTableVar 

--resets the identity
truncate table #MyTableVar
insert #MyTableVar(SomeData) values ('test3'), ('test4')
select * from #MyTableVar 
问候


Piotr

与其重新设定标识的种子,为什么不直接从@table变量中删除,然后对输入使用ROW_NUMBER()?e、 而不是懒惰的人

SELECT * FROM @MyTableVar;
…使用

SELECT ID = ROW_NUMBER() OVER (ORDER BY ID), SomeData FROM @MyTableVar;

现在,您不需要关心种子是什么,它是否从1开始,是否有任何间隙等。

您应该
截断表,而不是从表中删除所有行

但请注意,truncate不适用于某些表(从MSDN中列出):

我补充说:

You cannot truncate a table variable.
truncate的syntac为:

TRUNCATE TABLE 
    [ { database_name .[ schema_name ] . | schema_name . } ]
    table_name
[ ; ]
编辑:我没有注意到您正在询问表变量


据我所知,无法在表变量中重置标识列。您可以使用临时表。

是否可以在表变量上有另一个int列,并在插入完成后用模更新该列

declare @Mytablevar table
(
id int identity(1,1)
,id1 int
somedata nvarchar(300)
)

-- insert your data as you would.  After insert is finished, do the following:

update @mytablevar set id1 = case when id > 250 then id % 250 else id end

从中删除不会重置标识。
TRUNCATE有。

我在网上试过,但我无法得到任何关于表变量重置标识的解决方案

如果您能够使用temp table#MyTableVar而不是table@MyTableVar变量,则可以重置标识值

   DBCC CHECKIDENT('TableName', RESEED, NewValue)

   DBCC CHECKIDENT(#MyTableVar, RESEED, 0)
Newvalue必须比NewIdentityValue小一个

   NewValue= NewIdentity-1;
如果你还想了解更多,可以参考我的博客

如果您使用的是SQL Server,则使用此
DBCC CHECKIDENT('Customer',RESEED,0)
,其中Customer是表名。当您在此命令之后将记录插入表中时,primery键列值将再次从1开始

读这个

您不能对表变量重新设定标识值,但可以对临时表执行相同的操作:

CREATE  TABLE #TAB(ID INT IDENTITY,VALUE VARCHAR(10))
DECLARE @RESEED INT = 32
DBCC CHECKIDENT(#TAB,RESEED,@RESEED)
INSERT INTO #TAB  
SELECT 'TEST'
SELECT * FROM #TAB  

不幸的是,没有函数在表变量中重新设置标识列的种子,我知道这个问题很老了,但如果其他人遇到同样的问题,我想分享我解决这个问题的方法

/* declare another table variable with same structure and perform select insert*/

DECLARE @MyTableVar1 TABLE (ID INT IDENTITY(1,1), SomeData NVARCHAR(300))
insert into @MyTableVar1
select someData from @MyTableVar

但是,如果您想在循环内执行动态重新设定种子,我建议您使用一个表对象,因为您正在使用您的表,如果我没有弄错的话,您不将计数器初始化为1,而是将其作为一个例子,怎么样

DECLARE @ctr INT
IF @ctr IS NULL or @ctr <= 0 --this part is to control @ctr value on loops
   SET @ctr = 1
ELSE
   SELECT @ctr = MIN(id) FROM @tbl
DECLARE@ctr INT

如果@ctr为空或@ctr我刚刚有了这个想法,它就起作用了!!!:

declare @TableVariable table (
    IdentityColumn int identity(1,1),
    SomeOtherValue int,
    DesiredResult int
)
declare @FirstIdentityValueEachTimeYouLoadDataToTable int
declare @Count int
set @Count = 1

while @Count <= 5
begin
    delete @TableVariable

    insert into @TableVariable (SomeOtherValue) select 45
    insert into @TableVariable (SomeOtherValue) select 90
    insert into @TableVariable (SomeOtherValue) select 2

    select @FirstIdentityValueEachTimeYouLoadDataToTable = min(IdentityColumn) from @TableVariable

    Update @TableVariable set DesiredResult = IdentityColumn - @FirstIdentityValueEachTimeYouLoadDataToTable + 1

    select * from @TableVariable
    set @Count = @Count + 1
end 
declare@TableVariable表(
IdentityColumn int identity(1,1),
其他值int,
期望结果整数
)
声明@FirstIdentityValueEachTimeYouLoadDataToTable int
声明@countint
设置@Count=1

虽然@Count-mably-duplicate几乎可以工作,但它对我的结果集进行了重新排序(至少在我的示例中是这样)。在这种情况下,我插入东西的顺序非常重要。@Vaccano-我显示的顺序仅用于示例目的。你可以随意改变它。重点是说明方法,而不是具体的解决方案。在您的问题中,我们从未被告知您使用的是什么顺序。@Vaccano-还有一项,如果顺序很重要,那么当您将带有标识的var插入到表中时,您可能正在应用订单。在排名函数中也会使用相同的顺序。唉,我是从一个XML变量(使用XQuery)获取数据的,所以我没有任何orderby或强Id可供使用。它只是按照它在文件中的顺序(以及我需要它的顺序)出现。@Vaccano-首先,如果是这样的话,那么这是你问题的关键部分。你应该把这个问题加上去。也许还有一种方法可以下达命令。其次,我不确定我是否会依赖这样一个事实,即输入到表中的顺序与Xml代码段中的物理顺序完全匹配,而不明确地说明这一点。我怀疑这是一个受支持的“功能”,你可以依赖它,它在任何情况下或在未来的版本中都不会改变。正如你所说,这对表变量不起作用,正如我的标题所示,这正是我所寻找/希望的。只是澄清一下,这似乎类似,但与Thomas的建议不同,正如他所建议的那样,尝试插入数据时首先应用行号()。如果有多个insert语句独立发生,则首先应用行号()将不起作用,特别是因为insert语句本身可能没有明显的顺序。如果有多个insert语句发生,标识方法也会中断,不是吗?您可能会得到意外的间隙或顺序(例如,第一次插入A、B、C,其标识值为1、2、3。第二次插入A、B、D,其标识值为4、5、6,但与序列不同)。这实际上要归结为OP何时需要序列,我得到的印象是他们需要一个序列多次,因此问题是如何为标识重新设定种子。@Thomas,如果OP确保分配的标识值以正确的顺序出现(我假设他正在逐个插入行,并且“顺序”由表中尚未列出的内容决定),则此方法应能正常工作。op唯一的问题是,他从表中后续查询得到的值不是从1开始的。如果他保留身份栏,他可以
declare @TableVariable table (
    IdentityColumn int identity(1,1),
    SomeOtherValue int,
    DesiredResult int
)
declare @FirstIdentityValueEachTimeYouLoadDataToTable int
declare @Count int
set @Count = 1

while @Count <= 5
begin
    delete @TableVariable

    insert into @TableVariable (SomeOtherValue) select 45
    insert into @TableVariable (SomeOtherValue) select 90
    insert into @TableVariable (SomeOtherValue) select 2

    select @FirstIdentityValueEachTimeYouLoadDataToTable = min(IdentityColumn) from @TableVariable

    Update @TableVariable set DesiredResult = IdentityColumn - @FirstIdentityValueEachTimeYouLoadDataToTable + 1

    select * from @TableVariable
    set @Count = @Count + 1
end