Đặt lại hạt giống nhận dạng sau khi xóa các bản ghi trong SQL Server


682

Tôi đã chèn các bản ghi vào bảng cơ sở dữ liệu SQL Server. Bảng có khóa chính được xác định và hạt giống nhận dạng gia tăng tự động được đặt thành Có Có. Điều này được thực hiện chủ yếu vì trong SQL Azure, mỗi bảng phải có khóa chính và danh tính được xác định.

Nhưng vì tôi phải xóa một số bản ghi khỏi bảng, hạt giống nhận dạng cho các bảng đó sẽ bị xáo trộn và cột chỉ mục (được tạo tự động với mức tăng 1) sẽ bị xáo trộn.

Làm cách nào tôi có thể đặt lại cột danh tính sau khi tôi xóa các bản ghi để cột có thứ tự tăng dần theo thứ tự số?

Cột định danh không được sử dụng làm khóa ngoại ở bất kỳ đâu trong cơ sở dữ liệu.


4
"trong SQL Azure" - "mỗi bảng phải có khóa chính" - đúng - "và Xác định danh tính" - sai. Danh tính và khóa chính là các khái niệm trực giao. Một cột định danh không phải là PK của bảng. Khóa chính không phải là cột nhận dạng.
Damien_The_Unbeliever 17/214

ĐỒNG Ý. Khái niệm của tôi có thể sai. Nhưng bây giờ tôi đã xác định cấu trúc bảng với PK và Nhận dạng hạt giống. Nếu tôi phải xóa một số hàng, làm cách nào tôi có thể đặt lại Hạt giống nhận dạng theo thứ tự tăng dần số chính xác
xorpower

29
Tôi sẽ luôn lập luận rằng nếu bạn quan tâm đến các giá trị số thực tế được tạo trong một cột định danh, thì bạn đang sử dụng sai chúng. Tất cả những gì bạn cần quan tâm với một cột danh tính là nó tự động tạo ra các giá trị duy nhất (yay!) Và bạn có thể lưu trữ các giá trị này trong một cột số (bit này chỉ có liên quan để khai báo các cột để giữ các giá trị này). Bạn không nên hiển thị chúng cho bất cứ ai, vì vậy việc họ đảm nhận những giá trị nào không quan trọng.
Damien_The_Unbeliever 17/214

bạn có thể sử dụng kiểm tra dbcc xác định như đã đề cập khác nhưng xin lưu ý rằng khóa chính không bắt buộc đối với sql db v12
Satya_MSFT

Câu trả lời:


1099

Lệnh DBCC CHECKIDENTquản lý được sử dụng để thiết lập lại bộ đếm danh tính. Cú pháp lệnh là:

DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value ]}}])
[ WITH NO_INFOMSGS ]

Thí dụ:

DBCC CHECKIDENT ('[TestTable]', RESEED, 0);
GO

Nó không được hỗ trợ trong các phiên bản trước của Cơ sở dữ liệu Azure SQL, nhưng hiện được hỗ trợ.


Xin lưu ý rằng new_reseed_valueđối số được thay đổi trên các phiên bản SQL Server theo tài liệu :

Nếu các hàng có mặt trong bảng, hàng tiếp theo được chèn với giá trị new_reseed_value . Trong phiên bản SQL Server 2008 R2 trở về trước, hàng tiếp theo được chèn sử dụng new_reseed_value + giá trị gia tăng hiện tại.

Tuy nhiên, tôi thấy thông tin này sai lệch (thực sự sai) vì hành vi được quan sát chỉ ra rằng ít nhất SQL Server 2012 vẫn sử dụng new_reseed_value + logic giá trị gia tăng hiện tại. Microsoft thậm chí còn mâu thuẫn với chính nó Example Cđược tìm thấy trên cùng một trang:

C. Buộc giá trị nhận dạng hiện tại thành một giá trị mới

Ví dụ sau đây buộc giá trị nhận dạng hiện tại trong cột addressTypeID trong bảng addressType thành giá trị 10. Vì bảng có các hàng hiện có, hàng tiếp theo được chèn sẽ sử dụng 11 làm giá trị, nghĩa là giá trị gia tăng hiện tại mới được xác định cho giá trị cột cộng 1.

USE AdventureWorks2012;  
GO  
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);  
GO

Tuy nhiên, tất cả điều này để lại một tùy chọn cho hành vi khác nhau trên các phiên bản SQL Server mới hơn. Tôi đoán cách duy nhất để chắc chắn, cho đến khi Microsoft làm rõ mọi thứ trong tài liệu của riêng mình, là thực hiện các thử nghiệm thực tế trước khi sử dụng.


23
Cú pháp sẽ là ... DBCC CHECKIDENT ('[TestTable]', RESEED, 0) GO
Biki

2
Có vẻ như DBCC CHECKIDENTđược hỗ trợ kể từ phiên bản sắp phát hành (V12 / Sterling): azure.microsoft.com/en-us/documentation/articles/ trộm Mặc dù, đối với tình huống cụ thể này, tôi vẫn sẽ đề xuất TRUNCATE TABLE :)
Solomon Rutzky

1
Nó không hoạt động với tôi cho đến khi "GO" ở một dòng khác.
mrówa

1
Cú pháp đang bị gắn cờ vì từ khóa GO trong cùng một dòng, tôi không biết tại sao. Bạn có thể di chuyển nó xuống một dòng Tôi đã sao chép và dán dòng này 50 lần và bây giờ tôi phải quay lại và sửa nó.
AnotherDeveloper

4
Làm việc hoàn hảo cho tôi. Thật đáng để chỉ ra rằng khi gieo lại một bảng, nếu bạn muốn đổi lại sao cho bản ghi đầu tiên của bạn là ID 1 thì lệnh rese phải đổi thành 0, để bản ghi tiếp theo là ID 1.
Mike Upjohn

215
DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO

Trong đó 0 là identitygiá trị Bắt đầu


15
Nếu bảng trống, chẳng hạn như nếu bạn vừa gọi TRUNCATE, thì giá trị seed mới sẽ là giá trị cho lần sử dụng tiếp theo (tức là 1 không 0). Nếu bảng không trống, nó sẽ sử dụng new_reseed_value + 1. MSDN
kjbartel

2
@kjbartel, Anil và những người khác: không đơn giản chỉ là "nếu bàn trống". Tài liệu bị thiếu trong trường hợp khi bảng trống DELETE, không TRUNCATE, trong trường hợp đó cũng là new_reseed+value + 1. Tôi đã viết một bài về điều này, cho thấy hành vi thực tế thông qua một số thử nghiệm và cập nhật tài liệu thực tế (bây giờ chúng ta có thể nhờ nó trên GitHub): DBCC CHECKIDENT thực sự hoạt động như thế nào khi đặt lại Hạt giống nhận dạng (RESEED)? .
Solomon Rutzky

87

Cần lưu ý rằng NẾU tất cả dữ liệu đang bị xóa khỏi bảng thông qua DELETE(nghĩa là không có WHEREmệnh đề), miễn là a) quyền cho phép và b) không có FK nào tham chiếu bảng (dường như là trường hợp ở đây), sử dụng TRUNCATE TABLEsẽ được ưu tiên vì nó hiệu quả hơn DELETE đặt lại IDENTITYhạt giống cùng một lúc. Các chi tiết sau đây được lấy từ trang MSDN cho TRUNCATE TABLE :

So với câu lệnh XÓA, TRUNCATE TABLE có các ưu điểm sau:

  • Không gian nhật ký giao dịch ít hơn được sử dụng.

    Câu lệnh DELETE xóa từng hàng một và ghi lại một mục trong nhật ký giao dịch cho mỗi hàng bị xóa. TRUNCATE TABLE xóa dữ liệu bằng cách sắp xếp lại các trang dữ liệu được sử dụng để lưu trữ dữ liệu bảng và chỉ ghi lại các giao dịch trang trong nhật ký giao dịch.

  • Ít khóa thường được sử dụng.

    Khi câu lệnh DELETE được thực thi bằng cách sử dụng khóa hàng, mỗi hàng trong bảng sẽ bị khóa để xóa. TRUNCATE TABLE luôn khóa bảng (bao gồm khóa lược đồ (SCH-M)) và trang nhưng không phải mỗi hàng.

  • Không có ngoại lệ, không có trang nào được để lại trong bảng.

    Sau khi một câu lệnh XÓA được thực thi, bảng vẫn có thể chứa các trang trống. Ví dụ: các trang trống trong một đống không thể được xử lý mà không có ít nhất một khóa bảng (LCK_M_X) độc quyền. Nếu thao tác xóa không sử dụng khóa bảng, bảng (heap) sẽ chứa nhiều trang trống. Đối với các chỉ mục, thao tác xóa có thể để lại các trang trống phía sau, mặc dù các trang này sẽ được xử lý nhanh chóng bằng quy trình dọn sạch nền.

Nếu bảng chứa một cột định danh, bộ đếm cho cột đó được đặt lại về giá trị hạt giống được xác định cho cột. Nếu không có hạt giống nào được xác định, giá trị mặc định 1 được sử dụng. Để giữ lại bộ đếm danh tính, sử dụng XÓA thay thế.

Vì vậy, sau đây:

DELETE FROM [MyTable];
DBCC CHECKIDENT ('[MyTable]', RESEED, 0);

Trở thành chỉ:

TRUNCATE TABLE [MyTable];

Vui lòng xem TRUNCATE TABLEtài liệu (được liên kết ở trên) để biết thêm thông tin về các hạn chế, v.v.


8
Mặc dù hiệu quả hơn trong các trường hợp chính xác, điều này không phải lúc nào cũng là một lựa chọn. Truncate sẽ không thực thi trên một bảng có FK được xác định đối với nó. Ngay cả khi không có hồ sơ phụ thuộc, cắt ngắn sẽ thất bại nếu tồn tại ràng buộc. Ngoài ra cắt ngắn yêu cầu quyền ALTER trong đó Xóa chỉ cần XÓA.
Rozwel

3
@Rozwel Đúng, nhưng tôi đã đủ điều kiện trả lời cho biết rằng cần phải có quyền thích hợp. Ngoài ra, câu hỏi cụ thể nói rằng không có FK. Tuy nhiên, để rõ ràng, tôi đã cập nhật để chỉ định hạn chế "không FK". Cảm ơn đã chỉ ra rằng.
Solomon Rutzky

1
chỉ phân minh là bất kỳ FK nào sẽ chặn cắt ngắn. Có thể (mặc dù không bình thường) có FK chống lại một ràng buộc duy nhất không phải là một phần của cột PK hoặc cột định danh.
Rozwel

1
@Rozwel Một lần nữa đúng, nhưng có vẻ hợp lý khi giả định từ câu hỏi rằng không có ràng buộc duy nhất nào cho rằng PK chỉ tồn tại do sự hiểu biết của OP (chính xác hay không) mà Cơ sở dữ liệu Azure SQL yêu cầu. Bất kể, tôi là tất cả để giảm sự mơ hồ vì vậy tôi đã cập nhật lại. Cảm ơn.
Solomon Rutzky

Không có gì lạ thường khi có khóa ngoại trên bàn và sự hiện diện của BẤT K key khóa ngoại nào đều cấm BẢNG TRUNCATE. Tôi mới phát hiện ra điều này một cách khó khăn vào đầu ngày hôm nay khi tôi cố chạy TRUNCATE TABLE trên một bảng có khóa ngoại được thi hành theo hai cột khác trong bảng và một chỉ mục duy nhất trong bảng ngoại.
David A. Gray

83

Mặc dù hầu hết các câu trả lời đều đề xuất RESEED thành 0, nhưng nhiều lần chúng ta chỉ cần chuyển sang Id tiếp theo có sẵn

declare @max int
select @max=max([Id])from [TestTable]
if @max IS NULL   //check when max is returned as null
  SET @max = 0
DBCC CHECKIDENT ('[TestTable]', RESEED,@max)

Điều này sẽ kiểm tra bảng và đặt lại ID tiếp theo.


2
Đây là câu trả lời duy nhất hoạt động 100% thời gian
Kỹ sư đảo ngược

3
declare @max int select @max=ISNULL(max([Id]),0) from [TestTable]; DBCC CHECKIDENT ('[TestTable]', RESEED, @max );
Ngắn

61

Tôi đã thử @anil shahstrả lời và nó thiết lập lại danh tính. Nhưng khi một hàng mới được chèn vào, nó đã nhận được identity = 2. Vì vậy, thay vào đó tôi đã thay đổi cú pháp thành:

DELETE FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED, 0)
GO

Sau đó, hàng đầu tiên sẽ nhận được danh tính = 1.



16

Mặc dù hầu hết câu trả lời đang đề xuất RESEEDđể 0, và trong khi một số coi đây là một lỗ hổng cho TRUNCATEDbảng, Microsoft đã có một giải pháp mà không bao gồm cácID

DBCC CHECKIDENT ('[TestTable]', RESEED)

Điều này sẽ kiểm tra bảng và thiết lập lại tiếp theo ID. Điều này đã có sẵn từ MS SQL 2005 đến nay.

https://msdn.microsoft.com/en-us/l Library / ms176057.aspx


1
Thật không may, điều đó không đúng. Chỉ cần kiểm tra rằng cho máy chủ MS SQL 2014.
alehro

1
Trên thực tế, nó đúng với SQL 2014. Tôi vừa thử nghiệm nó và nó hoạt động với tôi.
Daniel Dyson

2
Điều này hoạt động không nhất quán với tôi trên SQL 2012. Đôi khi, nó sử dụng cái có sẵn tiếp theo như tôi mong đợi, đôi khi nó dường như bị kẹt vào một giá trị cũ từ bảng. Chỉ định các hạt giống alwasy hoạt động.
Dan Field

Nó không hoạt động với tôi trên SQL 2016 - nó chỉ để lại hạt giống nhận dạng. Nó có thể đã hoạt động chính xác với tôi một lần, nhưng nó cũng có thể là vấn đề ngón tay của tôi. Không thể làm cho nó hoạt động trở lại
Kỹ sư đảo ngược

Thông báo cho biết thành công, Checking identity information: current identity value '[incorrect seed]', current column value '[correct seed]'.nhưng khi chèn mới, nó vẫn sử dụng hạt giống không chính xác.
Denziloe

7

ban hành 2 lệnh có thể thực hiện thủ thuật

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

lần đầu tiên đặt lại danh tính về 0 và tiếp theo sẽ đặt nó thành giá trị khả dụng tiếp theo - jacob


2
KIỂM TRA DBCC ('[TestTable]', RESEED) không được chuyển sang giá trị khả dụng tiếp theo
Atal Kishore

Đây là phương pháp được sử dụng bởi RedGate Data So sánh khi tùy chọn "Cột nhận dạng được định dạng lại" được bật. Tôi đã thử nghiệm nó một cách rộng rãi (ý tôi là trong mã SQL, không phải trong công cụ RedGate) và nó hoạt động đáng tin cậy. (Tôi không có liên quan đến RedGate ngoài việc là người dùng không thường xuyên của các phiên bản dùng thử của họ)
Kỹ sư đảo ngược

6

@jacob

DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)

Làm việc cho tôi, tôi chỉ cần xóa tất cả các mục đầu tiên khỏi bảng, sau đó thêm ở trên vào một điểm kích hoạt sau khi xóa. Bây giờ bất cứ khi nào tôi xóa một mục được lấy từ đó.


DBCC CHECKIDENT chỉ hoạt động sau khi xóa. Bạn cũng có thể sử dụng cắt ngắn. Tuy nhiên nếu bạn cần phần còn lại của dữ liệu thì đừng sử dụng nó. Ngoài ra cắt ngắn không cung cấp một số lượng hồ sơ đã bị xóa.
dùng763539

6

Truncate bảng được ưa thích vì nó xóa các bản ghi, đặt lại bộ đếm và lấy lại không gian đĩa.

DeleteCheckIdentchỉ nên được sử dụng khi khóa ngoại không ngăn bạn cắt ngắn.


5

Đặt lại cột danh tính với id mới ...

DECLARE @MAX INT
SELECT @MAX=ISNULL(MAX(Id),0) FROM [TestTable]

DBCC CHECKIDENT ('[TestTable]', RESEED,@MAX)

4

Đây là một câu hỏi phổ biến và câu trả lời luôn luôn giống nhau: đừng làm điều đó. Các giá trị nhận dạng nên được coi là tùy ý và, do đó, không có thứ tự "chính xác".


15
Điều đó đúng với môi trường sản xuất, nhưng trong khi phát triển, tôi muốn nhớ rằng một số thực thể nhất định có một Id nhất định, được tạo từ tập lệnh seeding. Nó làm cho nó dễ dàng hơn nhiều để điều hướng thông qua cơ sở dữ liệu trong khi đang phát triển.
Francois Botha

7
Những câu trả lời như thế này hoàn toàn là lý thuyết và hiếm khi chúng tuân thủ nhu cầu của thế giới thực. Còn về việc thay vì tẩy não mọi người bằng giáo điều của bạn, bạn trả lời câu hỏi OP ...
Serj Sagan

1
Câu chuyện hay, anh bạn. Sự tranh chấp của tôi là thế này: nếu bạn muốn chỉ định giá trị cho một cột, đừng chọn một thuộc tính trên cột khiến việc đó trở nên khó khăn. Mùi mã là thế này: nếu mỗi lần bạn chèn một bản ghi vào bảng bạn chỉ định một giá trị cho cột định danh, bạn không có cột nhận dạng. Toàn bộ điểm nhận dạng là để máy chủ tạo ra một giá trị cho bạn. Vì vậy, nếu bạn ghi đè lên thời gian đó, bạn sẽ không thu được gì với chi phí khác không. Ngoài ra, làm việc tốt trên các đối số hominem quảng cáo.
Ben Thul

5
Tôi chắc chắn đồng ý với sự tranh chấp của bạn. Nhìn vào mệnh giá, OP chắc chắn đã làm sai, nhưng có lẽ có một nhu cầu sâu sắc hơn không được nêu trong bài đăng mà OP không nghĩ là có liên quan để trả lời câu hỏi của anh ta. Do đó, trả lời câu hỏi và đưa ra lời khuyên "làm và không nên làm" như một phần của câu trả lời. Nhân tiện, tôi chưa bao giờ tấn công nhân vật của bạn ... quảng cáo hominem có nghĩa là tôi gọi bạn là đồ ngốc hay gì đó ...
Serj Sagan

1
Mặc dù chắc chắn đúng trong hầu hết các trường hợp, vẫn tồn tại trường hợp hợp pháp để gieo lại bảng. Ví dụ: tôi đang làm việc trên một dự án trường xanh phải bắt đầu từ một điểm nhất định để tính đến các hàng hiện có trong tiền thân mà nó đang thay thế. Bắt đầu lại trong quá trình phát triển là một trường hợp sử dụng hợp pháp, IMO.
David A. Gray

3

Chạy đoạn script này để thiết lập lại cột nhận dạng. Bạn sẽ cần phải thực hiện hai thay đổi. Thay thế bảngXYZ bằng bất cứ bảng nào bạn cần cập nhật. Ngoài ra, tên của cột nhận dạng cần được thả từ bảng tạm thời. Điều này là tức thời trên một bảng với 35.000 hàng & 3 cột. Rõ ràng, sao lưu bảng và trước tiên hãy thử điều này trong môi trường thử nghiệm.


select * 
into #temp
From tableXYZ

set identity_insert tableXYZ ON

truncate table tableXYZ

alter table #temp drop column (nameOfIdentityColumn)

set identity_insert tableXYZ OFF

insert into tableXYZ
select * from #temp

3
Điều này không hoàn toàn chính xác: SET IDENTITY_INSERT nằm sai vị trí. Nó không đi xung quanh TRUNCATE, nó đi xung quanh INSERT INTO (do đó nhận dạng_ INSERT ). Ngoài ra, đây là để được sử dụng chỉ khi dữ liệu cần phải được lưu giữ, ngược lại nó là rất không hiệu quả so với chỉ chạy báo cáo kết quả TRUNCATE duy nhất.
Solomon Rutzky

1
DBCC CHECKIDENT (<TableName>, reseed, 0)

Điều này sẽ đặt giá trị nhận dạng hiện tại thành 0.

Khi chèn giá trị tiếp theo, giá trị nhận dạng được tăng lên 1.


1

Sử dụng thủ tục được lưu trữ này:

IF (object_id('[dbo].[pResetIdentityField]') IS NULL)
  BEGIN
    EXEC('CREATE PROCEDURE [dbo].[pResetIdentityField] AS SELECT 1 FROM DUMMY');
  END
GO

SET  ANSI_NULLS ON
GO
SET  QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[pResetIdentityField]
  @pSchemaName NVARCHAR(1000)
, @pTableName NVARCHAR(1000) AS
DECLARE @max   INT;
DECLARE @fullTableName   NVARCHAR(2000) = @pSchemaName + '.' + @pTableName;

DECLARE @identityColumn   NVARCHAR(1000);

SELECT @identityColumn = c.[name]
FROM sys.tables t
     INNER JOIN sys.schemas s ON t.[schema_id] = s.[schema_id]
     INNER JOIN sys.columns c ON c.[object_id] = t.[object_id]
WHERE     c.is_identity = 1
      AND t.name = @pTableName
      AND s.[name] = @pSchemaName

IF @identityColumn IS NULL
  BEGIN
    RAISERROR(
      'One of the following is true: 1. the table you specified doesn''t have an identity field, 2. you specified an invalid schema, 3. you specified an invalid table'
    , 16
    , 1);
    RETURN;
  END;

DECLARE @sqlString   NVARCHAR(MAX) = N'SELECT @maxOut = max(' + @identityColumn + ') FROM ' + @fullTableName;

EXECUTE sp_executesql @stmt = @sqlString, @params = N'@maxOut int OUTPUT', @maxOut = @max OUTPUT

IF @max IS NULL
  SET @max = 0

print(@max)

DBCC CHECKIDENT (@fullTableName, RESEED, @max)
go

--exec pResetIdentityField 'dbo', 'Table'

Chỉ cần xem lại câu trả lời của tôi. Tôi đã bắt gặp một hành vi kỳ lạ trong máy chủ sql 2008 r2 mà bạn nên biết.

drop table test01

create table test01 (Id int identity(1,1), descr nvarchar(10))

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

delete from test01

execute pResetIdentityField 'dbo', 'test01'

insert into test01 (descr) values('Item 1')

select * from test01

Lựa chọn đầu tiên tạo ra 0, Item 1.

Cái thứ hai sản xuất 1, Item 1. Nếu bạn thực hiện thiết lập lại ngay sau khi bảng được tạo, giá trị tiếp theo là 0. Thành thật mà nói, tôi không ngạc nhiên khi Microsoft không thể có được thứ này ngay. Tôi phát hiện ra nó bởi vì tôi có một tệp script chứa các bảng tham chiếu mà đôi khi tôi chạy sau khi tôi tạo lại các bảng và đôi khi khi các bảng đã được tạo.


1

Tôi sử dụng kịch bản sau đây để làm điều này. Chỉ có một kịch bản trong đó nó sẽ tạo ra một "lỗi", đó là nếu bạn đã xóa tất cả các hàng khỏi bảng và IDENT_CURRENThiện được đặt thành 1, tức là chỉ có một hàng trong bảng để bắt đầu.

DECLARE @maxID int = (SELECT MAX(ID) FROM dbo.Tbl)
;

IF @maxID IS NULL
    IF (SELECT IDENT_CURRENT('dbo.Tbl')) > 1
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 0)
    ELSE
        DBCC CHECKIDENT ('dbo.Tbl', RESEED, 1)
    ;
ELSE
    DBCC CHECKIDENT ('dbo.Tbl', RESEED, @maxID)
;

0

Đối với một hàng XÓA hoàn chỉnh và đặt lại số IDENTITY, tôi sử dụng điều này (SQL Server 2008 R2)

USE mydb

-- ##################################################################################################################
-- DANGEROUS!!!! USE WITH CARE
-- ##################################################################################################################

DECLARE
  db_cursor CURSOR FOR
    SELECT TABLE_NAME
      FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_TYPE = 'BASE TABLE'
       AND TABLE_CATALOG = 'mydb'

DECLARE @tblname VARCHAR(50)
SET @tblname = ''

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @tblname

WHILE @@FETCH_STATUS = 0
BEGIN
  IF CHARINDEX('mycommonwordforalltablesIwanttodothisto', @tblname) > 0
    BEGIN
      EXEC('DELETE FROM ' + @tblname)
      DBCC CHECKIDENT (@tblname, RESEED, 0)
    END

  FETCH NEXT FROM db_cursor INTO @tblname
END

CLOSE db_cursor
DEALLOCATE db_cursor
GO

0

Sắp xếp lại thành 0 không thực tế lắm trừ khi bạn đang dọn dẹp toàn bộ bàn.

khôn ngoan khác câu trả lời được đưa ra bởi Anthony Raymond là hoàn hảo. Lấy tối đa cột nhận dạng trước, sau đó gieo hạt với max.


0

Tôi đã cố gắng hoàn thành nó cho một số lượng lớn các bảng trong quá trình phát triển và điều này hoạt động như một cơ duyên.

DBCC CHECKIDENT('www.newsType', RESEED, 1);
DBCC CHECKIDENT('www.newsType', RESEED);

Vì vậy, trước tiên bạn buộc nó được đặt thành 1, sau đó bạn đặt nó thành chỉ mục cao nhất của các hàng có trong bảng. Phần còn lại nhanh chóng và dễ dàng của idex.


-2

Luôn luôn tốt hơn để sử dụng TRUNCATE khi có thể thay vì xóa tất cả các bản ghi vì nó cũng không sử dụng không gian nhật ký.

Trong trường hợp chúng ta cần xóa và cần thiết lập lại hạt giống, hãy luôn nhớ rằng nếu bảng không bao giờ được điền và bạn đã sử dụng DBCC CHECKIDENT('tablenem',RESEED,0) thì bản ghi đầu tiên sẽ nhận được danh tính = 0 như đã nêu trong tài liệu msDN

Trong trường hợp của bạn, chỉ xây dựng lại chỉ mục và đừng lo lắng về việc mất chuỗi danh tính vì đây là một tình huống phổ biến.


3
Âm thanh với tôi như ý tưởng là chỉ xóa một số hồ sơ.
Drumbeg

6
Điều này hoàn toàn sai - Không phải là <i> LUÔN </ i> tốt hơn để sử dụng cắt ngắn và trên thực tế, chỉ tốt hơn trong một số trường hợp rất hạn chế và cụ thể. Trời cấm ai đó làm theo lời khuyên của bạn và sau đó cần phải quay lại.
Thronk

1
@Thronk Tại sao bạn ngụ ý rằng TRUNCATEsẽ ngăn chặn ROLLBACKhành vi như mong đợi? ROLLBACK vẫn cuộn lại. Ngay cả khi DB được đặt thành BULK_LOGGED.
Solomon Rutzky

2
TRUNCATE là hoạt động DDL và nó không được đăng nhập vào tệp nhật ký. Trừ khi nó là một phần của giao dịch (không được đề cập ở bất kỳ đâu trong câu hỏi hoặc trong câu trả lời này). Bất cứ khi nào bất cứ ai nói điều gì đó LUÔN là đúng, đó là đặt cược khá an toàn, họ đã sai.
Thronk

Đây là câu trả lời duy nhất cho thấy có sự khác biệt trong hành vi RESEED tùy thuộc vào việc trình tự đã được sử dụng trước đó hay chưa. Một rese có cùng giá trị trên nhiều bảng trống , trong đó một số bảng đã được điền trước đó, sẽ dẫn đến các giá trị ban đầu khác nhau cho bản ghi đầu tiên được chèn vào mỗi bảng.
simon coleman

-4

Đầu tiên: Đặc tả danh tính Chỉ cần: "Không" >> Lưu dự án thực thi cơ sở dữ liệu

Sau đó: Đặc tả danh tính Chỉ cần: "CÓ" >> Lưu dự án thực thi cơ sở dữ liệu

ID cơ sở dữ liệu của bạn, PK Bắt đầu từ 1 >>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.