基本上我需要将所有表的Identity Increment重置为原始表。 在这里,我尝试了一些代码,但它失败了。
来自链接的实际代码:
USE World00_Character
GO
-- Create a cursor to loop through the System Ojects and get each table name
DECLARE TBL_CURSOR CURSOR
-- Declare the SQL Statement to cursor through
FOR ( SELECT Name FROM Sysobjects WHERE Type='U' )
-- Declare the @SQL Variable which will hold our dynamic sql
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = '';
-- Declare the @TblName Variable which will hold the name of the current table
DECLARE @TblName NVARCHAR(MAX);
-- Open the Cursor
OPEN TBL_CURSOR
-- Setup the Fetch While that will loop through our cursor and set @TblName
FETCH NEXT FROM TBL_CURSOR INTO @TblName
-- Do this while we are not at the end of the record set
WHILE (@@FETCH_STATUS <> -1)
BEGIN
-- Appeand this table's select count statement to our sql variable
SET @SQL = @SQL + ' ( SELECT '''+@TblName+''' AS Table_Name,COUNT(*) AS Count FROM '+@TblName+' ) UNION';
-- Delete info
EXEC('DBCC CHECKIDENT ('+@TblName+',RESEED,(SELECT IDENT_SEED('+@TblName+')))');
-- Pull the next record
FETCH NEXT FROM TBL_CURSOR INTO @TblName
-- End the Cursor Loop
END
-- Close and Clean Up the Cursor
CLOSE TBL_CURSOR
DEALLOCATE TBL_CURSOR
-- Since we were adding the UNION at the end of each part, the last query will have
-- an extra UNION. Lets trim it off.
SET @SQL = LEFT(@SQL,LEN(@SQL)-6);
-- Lets do an Order By. You can pick between Count and Table Name by picking which
-- line to execute below.
SET @SQL = @SQL + ' ORDER BY Count';
--SET @SQL = @SQL + ' ORDER BY Table_Name';
-- Now that our Dynamic SQL statement is ready, lets execute it.
EXEC (@SQL);
GO
错误讯息:
Error: Msg 102, Level 15, State 1, Line 1 Incorrect syntax near '('.
如何修复SQL或将所有表的标识重置为原始值?
答案 0 :(得分:59)
你有很多没有种子和增量为1的表吗?
如果不是(默认情况下,所有表都有),请使用以下代码:
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT(''?'', RESEED, 1)'
MSforeachtable
是一个未记录但非常方便的存储过程,它对数据库中的所有表执行给定的命令。
如果您需要绝对准确,请使用此语句 - 它将生成一个SQL语句列表,以将所有表重新设置为其原始SEED值:
SELECT
IDENT_SEED(TABLE_NAME) AS Seed,
IDENT_INCR(TABLE_NAME) AS Increment,
IDENT_CURRENT(TABLE_NAME) AS Current_Identity,
TABLE_NAME,
'DBCC CHECKIDENT(' + TABLE_NAME + ', RESEED, ' + CAST(IDENT_SEED(TABLE_NAME) AS VARCHAR(10)) + ')'
FROM
INFORMATION_SCHEMA.TABLES
WHERE
OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), 'TableHasIdentity') = 1
AND TABLE_TYPE = 'BASE TABLE'
抓住输出中的最后一列,然后执行这些语句就完成了! : - )
(灵感来自Pinal Dave的blog post)
答案 1 :(得分:12)
对marc_s回答稍作调整。
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'', RESEED)'
那些单引号?性格很重要。该语句将导致SQL Server自动重新计算每个表的下一个标识值。
答案 2 :(得分:6)
使用此命令时要小心,如果您的表包含数据,则所有新插入都将导致重复错误
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT(''?'', RESEED,1)'
解决你需要在那之后运行它的问题
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT(''?'', RESEED)'
如果数据存在,这会将种子重置为最后一个列标识
答案 3 :(得分:5)
处理架构的轻微变化更好......
SELECT
IDENT_SEED(TABLE_SCHEMA+'.'+TABLE_NAME) AS Seed,
IDENT_INCR(TABLE_SCHEMA+'.'+TABLE_NAME) AS Increment,
IDENT_CURRENT(TABLE_SCHEMA+'.'+TABLE_NAME) AS Current_Identity,
TABLE_SCHEMA+'.'+TABLE_NAME,
'DBCC CHECKIDENT('''+TABLE_SCHEMA+'.'+TABLE_NAME+''', RESEED, '+CAST(IDENT_SEED(TABLE_SCHEMA+'.'+TABLE_NAME) AS VARCHAR(10))+')'
FROM
INFORMATION_SCHEMA.TABLES
WHERE
OBJECTPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME), 'TableHasIdentity') = 1
AND TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_SCHEMA, TABLE_NAME
答案 4 :(得分:3)
使用sp_MSForEachTable
并在重置之前检查表是否具有标识值的另一种方法:
EXEC sp_MSForEachTable '
Print ''?''
IF OBJECTPROPERTY(object_id(''?''), ''TableHasIdentity'') = 1
DBCC CHECKIDENT (''?'', RESEED, 0)
else
Print ''Table does not have an identity value''
'
注意:如果您希望标识值从1开始,则DBCC命令应使用CHECKIDENT (''?'', RESEED, 0)
而不是CHECKIDENT (''?'', RESEED, 1)
,如某些答案中所示。引自MS SQL Server documentation:
以下示例强制执行当前标识值 AddressType表中的AddressTypeID列的值为10。 因为表有现有行,所以插入的下一行将使用11 作为值,即为其定义的新当前增量值 列值加1
USE AdventureWorks2012;
GO
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);
GO
答案 5 :(得分:2)
一个简单的方法可能是使用sp_MSforeachtable命令,这是一个未记录但相对熟知的命令,可以查看您的表。
答案 6 :(得分:2)
要仅使用标识列重新设置表,可以使用下一个脚本。
它还使用了sp_MSforeachtable
,但考虑了正确的表格。
EXEC sp_MSforeachtable '
IF (SELECT COUNT(1)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = ''BASE TABLE''
AND ''[''+ TABLE_SCHEMA + ''].['' + TABLE_NAME + '']'' = ''?''
AND OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), ''TableHasIdentity'') = 1) > 0
BEGIN
DBCC CHECKIDENT (''?'', RESEED, 1)
END'
答案 7 :(得分:1)
我们在工作时计划停电,无论出于何种原因,我的一些桌子在他们的身份列中跃升了 1000。 我修改了此代码以制作一个选择字符串列表,以显示与当前标识相比的列的当前值。 然后我将这些行复制并粘贴到另一个选择中。
SELECT
Replace(CurrentValue,'FROM',','+ CAST(IDENT_CURRENT(TABLE_SCHEMA+'.'+TABLE_NAME)AS VARCHAR) + ' AS Current_Identity FROM')
FROM
INFORMATION_SCHEMA.TABLES T left join (select 'UNION SELECT ''DBCC CHECKIDENT(''''['+TABLE_SCHEMA+'].'+TABLE_NAME+''''', RESEED, ''+CAST( MAX('+COLUMN_NAME+') as VARCHAR)+'')'' as DBCC_String,MAX('+COLUMN_NAME+') as CurrentValue FROM [' + TABLE_SCHEMA+'].'+TABLE_NAME as CurrentValue,TABLE_SCHEMA+'.'+TABLE_NAME as TTABLE
from INFORMATION_SCHEMA.COLUMNS
where COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1
) as TT on T.TABLE_SCHEMA+'.'+T.TABLE_NAME = TT.TTABLE
WHERE
OBJECTPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME), 'TableHasIdentity') = 1
AND TABLE_TYPE = 'BASE TABLE'
ORDER BY T.TABLE_SCHEMA, T.TABLE_NAME
然后将选中的列复制进去
select DBCC_String,CurrentValue,Current_Identity from
(
*Paste Here and delete the first "UNION"*
) as T where CurrentValue < Current_Identity
然后您可以从数据库中复制 DBC_String 列 Table 修改你需要的表格
答案 8 :(得分:0)
使用以下代码
CREATE TABLE #tmptable
(
[seednvalue] int not null,
[tablename] [nvarchar] (100) NULL
)
declare @seedvalue AS INT
DECLARE @tablename AS VARCHAR(100)
Declare #tablesIdentityCursor CURSOR
for
SELECT
IDENT_CURRENT(TABLE_NAME)+1 AS Current_Identity,
TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), 'TableHasIdentity') = 1
AND TABLE_TYPE = 'BASE TABLE' --AND TABLE_NAME='test11'
delete from #tmptable
Open #tablesIdentityCursor
FETCH NEXT FROM #tablesIdentityCursor into @seedvalue, @tablename
WHILE @@FETCH_STATUS = 0 BEGIN
Insert into #tmptable Select @seedvalue , @tablename
DBCC CHECKIDENT (@tablename, reseed, @seedvalue)
FETCH NEXT FROM #tablesIdentityCursor into @seedvalue, @tablename
END
CLOSE #tablesIdentityCursor
DEALLOCATE #tablesIdentityCursor
SELECT * FROM #tmptable
DROP TABLE #tmptable
答案 9 :(得分:0)
(I'm reposting my answer from this other SO page)
也许最简单的方法(就像听起来一样疯狂,而且看起来像代码一样臭)只是像这样运行DBCC CHECKIDENT
两次:
-- sets all the seeds to 1
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'', RESEED, 1)'
-- run it again to get MSSQL to figure out the MAX/NEXT seed automatically
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')'
完成。
如果您愿意,可以再次运行它以查看所有种子的设置:
-- run it again to display what the seeds are now set to
exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT (''?'')'
这只是一种利用文档评论的创造性方法:
如果表的当前标识值小于最大值 身份值存储在标识列中,使用重置它 标识列中的最大值。