기존 열에 ID 추가


445

테이블의 기본 키를 ID 열로 변경해야하며 테이블에 이미 많은 행이 있습니다.

ID를 정리하여 1부터 순차적으로 시작하고 테스트 데이터베이스에서 제대로 작동하는지 확인하는 스크립트가 있습니다.

ID 속성을 갖도록 열을 변경하는 SQL 명령은 무엇입니까?

답변:


482

식별을 위해 기존 열을 변경할 수 없습니다.

두 가지 옵션이 있습니다

  1. ID가있는 새 테이블을 만들고 기존 테이블을 삭제

  2. ID가있는 새 열을 만들고 기존 열을 삭제

접근법 1. ( 새 테이블 ) 여기에서 새로 작성된 ID 열에 기존 데이터 값을 보유 할 수 있습니다.

CREATE TABLE dbo.Tmp_Names
    (
      Id int NOT NULL
             IDENTITY(1, 1),
      Name varchar(50) NULL
    )
ON  [PRIMARY]
go

SET IDENTITY_INSERT dbo.Tmp_Names ON
go

IF EXISTS ( SELECT  *
            FROM    dbo.Names ) 
    INSERT  INTO dbo.Tmp_Names ( Id, Name )
            SELECT  Id,
                    Name
            FROM    dbo.Names TABLOCKX
go

SET IDENTITY_INSERT dbo.Tmp_Names OFF
go

DROP TABLE dbo.Names
go

Exec sp_rename 'Tmp_Names', 'Names'

접근 방식 2 ( 새 열 ) 새로 만든 신원 열의 기존 데이터 값을 유지할 수 없습니다. 신원 열에는 일련의 번호가 있습니다.

Alter Table Names
Add Id_new Int Identity(1, 1)
Go

Alter Table Names Drop Column ID
Go

Exec sp_rename 'Names.Id_new', 'ID', 'Column'

자세한 내용은 다음 Microsoft SQL Server 포럼 게시물을 참조하십시오.

열을 ID로 변경하는 방법 (1,1)


49
테이블 데이터가 작 으면이 옵션이 작동하지 않습니다. 테이블이 크면 선호하는 또 다른 옵션이 있습니다. ALTER TABLE ... SWITCH를 사용하여 테이블 스키마를 IDENTITY 열이 아닌 다른 버전으로 바꾸십시오. ALTER TABLE .... SWITCH 방식의 장점은 테이블 데이터를 복사하거나 변경할 필요가 없으므로 10 억 행 테이블의 경우 5 초 미만으로 빠르게 완료된다는 것입니다. 그러나 경고와 한계가 있습니다. 자세한 내용은 아래 답변을 참조하십시오.
저스틴 그랜트

7
@ 저스틴 그 라트 (Justin Grat) : 매우 흥미로운 대안과 내가 고려하지 않은 대안! 이것이 작동하는 이유는 IDENTITY가 데이터 유형이 아닌 열 특성이기 때문에 SWITCH 메소드는 두 테이블 (이전 및 새) 사이의 스키마를 IDENTITY 차이와 상관없이 식별 가능한 것으로 유효성 검증합니다. 공유해 주셔서 감사합니다!
John Sansom

데이터가 많지 않은 경우 SSMS에서 스크립트를 생성하여 "테이블 만들기"를 수행 할 수 있습니다. 테이블> 테이블 스크립팅> 테이블 생성>> (새 쿼리 편집기?)를 마우스 오른쪽 단추로 클릭하십시오. 그런 다음 그것을 삭제하고 해당 스크립트 안에 당신은 추가 할 수있는 IDENTITY(1, 1)기본 키 열이있는 부분을
goamn

SSMS를 사용하여이를 시행 할 수도 있습니다. 도구> 옵션> 디자이너로 이동하여 "테이블을 다시 작성해야하는 변경 사항 저장 방지"를 선택 취소하십시오. BTW 이것은 상당히 큰 테이블에는 권장되지 않습니다.
Zafar

PostgreSQL에서 다음 명령을 사용하여 기존 정수 열에 ID를 추가 할 있습니다. alter table {table_name} alter column {column_name} add는 항상 ID로 생성됩니다 ({number}로 다시 시작).
앤드류 맥키

209

SQL 2005 이상에서는 테이블의 데이터 페이지를 변경하지 않고이 문제를 해결하는 트릭이 있습니다. 이것은 모든 데이터 페이지를 터치하는 데 몇 분 또는 몇 시간이 걸릴 수있는 큰 테이블에 중요합니다. 트릭은 ID 열이 기본 키이거나 클러스터형 또는 비 클러스터형 인덱스의 일부이거나 더 단순한 "add / remove / rename column"솔루션을 트립 할 수있는 기타 문제의 경우에도 작동합니다.

트릭은 다음과 같습니다. SQL Server의 ALTER TABLE ... SWITCH 문을 사용하여 데이터를 변경하지 않고 테이블의 스키마를 변경할 수 있습니다. 즉, 테이블을 동일한 테이블 스키마로, IDENTITY 열없이 IDENTITY로 바꿀 수 있습니다. 동일한 방법으로 기존 열에 IDENTITY를 추가 할 수 있습니다.

일반적으로 ALTER TABLE ... SWITCH 는 분할 된 테이블의 전체 파티션을 새로운 빈 파티션으로 효율적으로 교체하는 데 사용됩니다. 그러나 파티션되지 않은 테이블에서도 사용할 수 있습니다.

이 트릭을 사용하여 5 초 이내에 25 억 행 테이블의 열을 IDENTITY에서 비 IDENTITY로 변환했습니다 (비 IDENTITY에 대해 쿼리 계획이 더 나은 다중 시간 쿼리를 실행하기 위해) 그런 다음 IDENTITY 설정을 다시 5 초 이내에 복원했습니다.

작동 방식에 대한 코드 샘플은 다음과 같습니다.

 CREATE TABLE Test
 (
   id int identity(1,1),
   somecolumn varchar(10)
 );

 INSERT INTO Test VALUES ('Hello');
 INSERT INTO Test VALUES ('World');

 -- copy the table. use same schema, but no identity
 CREATE TABLE Test2
 (
   id int NOT NULL,
   somecolumn varchar(10)
 );

 ALTER TABLE Test SWITCH TO Test2;

 -- drop the original (now empty) table
 DROP TABLE Test;

 -- rename new table to old table's name
 EXEC sp_rename 'Test2','Test';

 -- update the identity seed
 DBCC CHECKIDENT('Test');

 -- see same records
 SELECT * FROM Test; 

이것은 다른 답변의 솔루션보다 분명히 관련이 있지만 테이블이 크면 실제로 생명을 구할 수 있습니다. 몇 가지주의 사항이 있습니다.

  • 내가 아는 한,이 방법으로 테이블의 열에 대해 ID 만 변경할 수 있습니다. 열 추가 / 제거, Null 허용 변경 등은 허용되지 않습니다.
  • 전환하기 전에 foriegn 키를 삭제 한 후 복원해야합니다.
  • WITH SCHEMABINDING 함수, 뷰 등과 동일합니다.
  • 새 테이블의 인덱스는 정확히 일치해야합니다 (같은 열, 같은 순서 등).
  • 이전 테이블과 새 테이블은 동일한 파일 그룹에 있어야합니다.
  • SQL Server 2005 이상에서만 작동
  • 필자는 이전에이 트릭이 Enterprise 또는 Developer 버전의 SQL Server에서만 작동한다고 믿었지만 (파티션은 Enterprise 및 Developer 버전에서만 지원되므로) 아래 의견에서 Mason G. Zhwiti는 SQL Standard Edition에서도 작동한다고 말합니다. 이것은 Enterprise 또는 Developer에 대한 제한이 ALTER TABLE ... SWITCH에 적용되지 않는다는 것을 의미한다고 가정합니다.

위의 요구 사항을 자세히 설명하는 TechNet에 대한 좋은 기사 가 있습니다 .

업데이트 -Eric Wu 는 아래에이 솔루션에 대한 중요한 정보를 추가합니다. 더주의를 끌기 위해 여기에 복사하십시오.

여기에 언급 할만한 또 다른 경고가 있습니다. 새 테이블은 이전 테이블에서 데이터를 행복하게 수신하지만 모든 새 행은 ID 패턴에 따라 삽입되지만 1에서 시작하여 해당 열이 기본 키인 경우 중단 될 수 있습니다. DBCC CHECKIDENT('<newTableName>')전환 후 즉시 실행을 고려하십시오 . 자세한 내용은 msdn.microsoft.com/en-us/library/ms176057.aspx 를 참조 하십시오 .

테이블이 새 행으로 활발하게 확장되는 경우 (IDENTITY 추가와 새 행 추가 사이에 가동 중지 시간이 많지 않다는 것을 의미 함) 대신 DBCC CHECKIDENT새 테이블 스키마에서 ID 시드 값을 수동으로 설정하려고합니다. 예를 들어, 테이블에서 가장 큰 기존 ID보다 큽니다 (예 :) 트랜잭션에 와를 IDENTITY (2435457, 1)둘 다 포함 할 수 있지만 (테스트하지 않은 경우) 시드 값을 수동으로 설정하는 것이 더 쉽고 더 안전 할 것 같습니다.ALTER TABLE...SWITCHDBCC CHECKIDENT

분명히 새로운 행이 테이블에 추가되지 않거나 매일 ETL 프로세스와 같이 가끔씩 추가되는 경우이 경쟁 조건이 발생하지 않으므로 DBCC CHECKIDENT괜찮습니다.


5
내 기억이 맞다면이 기사에서 아이디어를 얻었습니다 : sqlservercentral.com/articles/T-SQL/61979
Justin Grant

2
참고로, 이는 표준 버전의 SQL 2008 R2에서도 작동하는 것으로 보입니다. 아마도 그들은 백업 압축을 켜는 기능을 활성화 한 것처럼이 기능을 활성화했을 것입니다.
메이슨 G. Zhwiti

3
@jbatista-OP의 질문에 따르면 이미 테이블에 기본 키가 있고 올바른 값을 보장 할 수 있지만 IDENTITY 열로 변경하기를 원했습니다. 위의 대답은 좁은 유스 케이스에 중점을 둡니다. 실제로 데이터를 변경하지 않고 IDENTITY를 열에 추가하는 방법. 위에서 설명한 접근 방식은 큰 테이블의 경우 시간을 크게 절약합니다. 데이터를 변경해야하는 경우 다른 솔루션을 사용해야합니다.
저스틴 그랜트

3
여기에 언급 할만한 또 다른 경고가 있습니다. 새 테이블은 이전 테이블에서 데이터를 행복하게 수신하지만 모든 새 행은 ID 패턴에 따라 삽입되지만 1에서 시작하여 해당 열이 기본 키인 경우 잠재적으로 중단됩니다. DBCC CHECKIDENT('<newTableName>')전환 후 즉시 실행을 고려하십시오 . 자세한 내용은 msdn.microsoft.com/en-us/library/ms176057.aspx 를 참조 하십시오 .
Eric Wu

3
이것은 좋은 답변입니다! 또한 열의 Null 허용 여부는 같아야합니다. 따라서 열 Null 허용 여부를 변경해야하는 경우 이후 단계에서 수행해야합니다. PK 제약 조건도 마찬가지입니다. 또한 테이블 작성의 ID 값을 현재 최대 값과 일치하도록 변경합니다. IDENTITY (maxID + 1, 1)
Philippe

71

열을 IDENTITY 열로 변경할 수 없습니다. 해야 할 일은 get-go에서 IDENTITY로 정의 된 새 열을 만든 다음 이전 열을 삭제하고 새 열의 이름을 이전 이름으로 바꾸는 것입니다.

ALTER TABLE (yourTable) ADD NewColumn INT IDENTITY(1,1)

ALTER TABLE (yourTable) DROP COLUMN OldColumnName

EXEC sp_rename 'yourTable.NewColumn', 'OldColumnName', 'COLUMN'

마크


\ @objname 매개 변수가 모호하거나 청구 된 \ @objtype (COLUMN)이 잘못되었습니다.
Jenny O'Reilly

1
@ JennyO'Reilly : 별도의 질문에 넣고 사용중인 모든 명령을 보여주세요 !
marc_s

2
실패한 sp_rename 프로 시저입니다. 오류 텍스트를 검색하여 stackoverflow에서 해결책을 찾았습니다. 내 테이블에는 이름에 특수 문자가 없지만 대괄호가있는 엄격한 구문 규칙 인 것 같습니다.
Jenny O'Reilly

1
나처럼 될 수있다 : 'ALTER TABLE (yourTable) DROP COLUMN에 OldColumnName'와, 왜 이름 바꾸기 'ALTER TABLE (yourTable) OldColumnName INT IDENTITY (1,1) ADD': P
RK 샤르마

마크, 나는 거대한 테이블 (~ 300mln 행) 에서이 정확한 명령을 시도했지만 ~ 10 분 후에 프로세스를 중지했습니다.
나오미

14

여기에 설명 된 멋진 솔루션이 있습니다. SQL SERVER – 열에서 ID 속성 추가 또는 제거

SQL Manager에서 테이블을 수동으로 간단히 편집하면 ID를 변경하고 변경 사항을 저장하지 말고 변경 사항에 대해 생성 할 스크립트를 표시하고 복사 한 다음 나중에 사용하십시오.

스크립트 (스크립트)에는 변경하는 테이블과 관련된 모든 외래 키, 인덱스 등이 포함되어 있기 때문에 시간을 크게 절약 할 수 있습니다. 이것을 수동으로 작성하는 것은 ... 신은 금지합니다.


이것이 내가 사용한 솔루션입니다-SSMS는 변경을 위해 T-SQL을 생성합니다 ... 동일한 스키마 디자인의 새 임시 테이블을 만든 다음 모든 행을 복사하여 오리지널을 제거하고 이름을 바꿉니다. . 완전히 실행하는 데 약간의 시간이 걸리지 만 완벽하게 작동했습니다.
mdelvecchio

Pinal Dave가 실제로 생성 한 스크립트를 실행해야한다고 말하는 것은 아니라고 생각합니다. UI를 통해 변경 한 내용이 무엇인지 보여주기위한 것입니다.
Zack

SSMS (테이블 정의 변경시)의 스크립팅 기능은 실제로 분할 된 테이블을 문서화 할 때 유일하게 올바른 기능입니다. 가장 적절한 위치 'task'-> 'script table'은 항상 분할 기능을 스크립팅하는 것을 잊어 버립니다!
Martijn van der Jagt

1
누군가에게 도움이 될 수 있습니다. 변경 후 변경 스크립트를 가져 오려면 SSMS의 디자인 모드에서 테이블을 마우스 오른쪽 단추로 클릭하고 "변경 스크립트 생성"옵션을 선택하고 스크립트를 로컬 드라이브
Vijai에서

11

IDENTITY 대신 SEQUENCE 를 사용하십시오 .

SQL Server 2014에서는 (낮은 버전에 대해서는 모르겠습니다) 시퀀스를 사용하여 간단하게 수행 할 수 있습니다.

CREATE SEQUENCE  sequence_name START WITH here_higher_number_than_max_existed_value_in_column INCREMENT BY 1;

ALTER TABLE table_name ADD CONSTRAINT constraint_name DEFAULT NEXT VALUE FOR sequence_name FOR column_name

여기에서 : 열의 기본값으로 시퀀스


6

간단한 설명

sp_RENAME을 사용하여 기존 열의 이름을 바꿉니다.

EXEC sp_RENAME 'Table_Name.Existing_ColumnName', 'New_ColumnName', 'COLUMN'

이름 바꾸기의 예 :

기존 열 UserID의 이름이 OldUserID로 바뀝니다.

EXEC sp_RENAME 'AdminUsers.UserID' , 'OldUserID', 'COLUMN'

그런 다음 alter query를 사용하여 새 열을 추가하여 기본 키 및 ID 값으로 설정하십시오.

ALTER TABLE TableName ADD Old_ColumnName INT NOT NULL PRIMARY KEY IDENTITY(1,1)

기본 키 설정의 예

새로 작성된 열 이름은 UserID입니다.

ALTER TABLE Users ADD UserID INT NOT NULL PRIMARY KEY IDENTITY(1,1)

그런 다음 이름이 바뀐 열을 삭제하십시오.

ALTER TABLE Table_Name DROP COLUMN Renamed_ColumnName

이름이 바뀐 열 삭제의 예

ALTER TABLE Users DROP COLUMN OldUserID

이제 테이블의 기존 열에 기본 키와 ID를 추가했습니다.


5

나는 DBA가없는 팀에 일한 Java 개발자이며 개발자로서 DBA 권한을 얻을 수없는 곳입니다. 두 데이터베이스간에 전체 스키마를 이동하는 작업을 수행 했으므로 DBA가 없어도 관리자 권한이 없기 때문에 SQL Server 2008에서 GUI를 사용할 수 없어 스크립트를 실행하여 스크립트를 실행하고 수행해야했습니다.

그러나 새로운 schema.table에서 저장 프로 시저를 실행할 때 모든 것이 문제없이 이동했지만 테이블에서 ID 필드를 잃어 버렸습니다. 테이블을 만든 스크립트를 두 번 확인했지만 거기에 있었지만 스크립트를 실행할 때 SQL Server가 얻지 못했습니다. 나는 DBA에 의해 나중에 같은 문제를 본 적이 있다고 들었다.

어쨌든 SQL Server 2008의 경우이 문제를 해결하기 위해 취한 단계는 다음과 같습니다. 따라서 누군가에게 도움이되기를 바랍니다. 이것이 더 어려운 다른 테이블에 대한 FK 종속성을 가지면서 내가 한 일입니다.

이 쿼리를 사용하여 ID가 ​​실제로 누락되었는지 확인하고 테이블에 대한 종속성을 확인했습니다.

1.) 테이블에서 통계를 찾습니다.

exec sp_help 'dbo.table_name_old';

2.) 이전의 PK 필드에 ID 필드를 추가하는 것을 제외하고는 동일한 동일한 새 테이블을 복제하십시오.

3.) ID를 비활성화하여 데이터를 이동하십시오.

SET IDENTITY_INSERT dbo.table_name ON 

4.) 데이터를 전송하십시오.

INSERT INTO dbo.table_name_new
(
field1, field2, etc...
)
SELECT 
field1, field2, etc...
FROM 
dbo.table_name_old;

5.) 데이터가 있는지 확인하십시오.

SELECT * FROM dbo.table_name_new

6.) ID를 다시 활성화하십시오.

SET IDENTITY_INSERT ToyRecP.ToyAwards.lkpFile_New OFF

7.) 이것은 원본 테이블이 종속성으로 참조하는 테이블을 확인하기 위해 모든 FK 관계를 얻는 가장 좋은 스크립트이며 많은 사람을 만났으므로 골키퍼입니다!

SELECT f.name AS ForeignKey,
   OBJECT_NAME(f.parent_object_id) AS TableName,
   COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
   OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
   COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
   ON f.OBJECT_ID = fc.constraint_object_id
   ORDER BY ReferenceTableName;

8.)이 다음 단계 전에 관련된 모든 테이블에 대한 모든 PK 및 FK 스크립트가 있는지 확인하십시오.

9.) SQL Server 2008을 사용하여 각 키를 마우스 오른쪽 단추로 클릭하고 스크립트로 작성할 수 있습니다.

10.) 다음 구문을 사용하여 종속성 테이블에서 FK를 삭제하십시오.

ALTER TABLE [dbo].[table_name] DROP CONSTRAINT [Name_of_FK]

11.) 원래 테이블을 삭제하십시오.

DROP TABLE dbo.table_name_old;

13.)이 다음 단계는 9 단계에서 SQL Server 2008에서 생성 한 스크립트에 의존합니다.

-새 테이블에 PK를 추가하십시오.

--FK를 새 테이블에 추가하십시오.

-FK를 다시 의존성 테이블에 추가하십시오.

14.) 모든 것이 정확하고 완전한지 확인하십시오. GUI를 사용하여 테이블을 보았습니다.

15.) 새 테이블의 이름을 원래 테이블 이름으로 바꿉니다.

exec sp_RENAME '[Schema_Name.OldTableName]' , '[NewTableName]';

마침내 모든 것이 작동했습니다!


4

그렇게 할 수 없습니다. 다른 열을 추가하거나 원래 열을 삭제하고 새 열의 이름을 바꾸거나 새 테이블을 만들거나 새 테이블을 만들고 데이터를 복사하고 이전 테이블을 삭제 한 다음 새 테이블의 이름을 이전 테이블로 변경해야합니다 표

SSMS를 사용하고 디자이너에서 identity 속성을 ON으로 설정하면 SQL Server가 배후에서 수행하는 작업이 있습니다. [user]라는 테이블이 있다면 UserID와 identity를 만들면 이런 일이 발생합니다.

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION

GO

GO
CREATE TABLE dbo.Tmp_User
    (
    UserID int NOT NULL IDENTITY (1, 1),
    LastName varchar(50) NOT NULL,
    FirstName varchar(50) NOT NULL,
    MiddleInitial char(1) NULL

    )  ON [PRIMARY]
GO

SET IDENTITY_INSERT dbo.Tmp_User ON
GO
IF EXISTS(SELECT * FROM dbo.[User])
 EXEC('INSERT INTO dbo.Tmp_User (UserID, LastName, FirstName, MiddleInitial)
    SELECT UserID, LastName, FirstName, MiddleInitialFROM dbo.[User] TABLOCKX')
GO
SET IDENTITY_INSERT dbo.Tmp_User OFF
GO

GO
DROP TABLE dbo.[User]
GO
EXECUTE sp_rename N'dbo.Tmp_User', N'User', 'OBJECT'
GO
ALTER TABLE dbo.[User] ADD CONSTRAINT
    PK_User PRIMARY KEY CLUSTERED 
    (
    UserID
    ) ON [PRIMARY]

GO
COMMIT

비트 값을 설정하여 시스템 테이블을 해킹하는 방법이 있지만 지원되지 않으며 그렇게하지 않을 것이라고 말했습니다.


4

일반적인 경우에 이해했듯이 Identity 속성 이 있는 기본 키 가 있는 테이블을 생성 하므로 이름 바꾸기 또는 기본 키 제약 조건 과 관련된 열 삭제 는 제약 조건 규칙이 열 구조의 유효성을 검사하기 때문에 불가능합니다. 우리는 다음과 같은 방법으로 몇 가지 단계를 처리 할 필요가이를 TTO : 우리가 가정하자 = '직원'TABLENAME을 하고 의 ColumnName = '직원 ID' '직원'테이블 1. 추가 새 열 'EmployeeId_new' ALTER TABLE 직원 ADD EmployeeId_new INT IDENTITY ( 1,1)





  1. 이제 'Employee'테이블에서 'EmployeeId'열을 제거하십시오.
    ALTER TABLE Employee DROP COLUMN EmployeeId

  2. 기본 키 제약 조건 규칙이 적용되고 열 구조를 확인하기 때문에 오류가 발생합니다.
    * ### ' 메시지 5074, 수준 16, 상태 1, 줄 1 개체 [PK_dbo.Employee]는 열 [EmployeeId]에 종속됩니다.' ###

  3. 따라서 'Employee'테이블에서 기본 키 제약 조건을 먼저 제거한 다음 ALTER TABLE Employee DROP 제약 조건[PK_dbo.Employee]을 제거 할 수 있습니다
    .

  4. 이제 오류가 발생한 이전 단계에서와 같이 'Employee'테이블에서 'EmployeeId'열을 제거 할 수 있습니다.
    ALTER TABLE Employee DROP COLUMN EmployeeId

  5. 이제 'EmployeeId'열이 테이블에서 제거되었으므로 새로 추가 된 새 열 'EmployeeId_new'의 이름을 'EmployeeId'로 변경합니다.
    sp_rename 'Employee.EmployeeId', 'EmployeeId_new', 'COLUMN'

  6. 동일한 형식으로 테이블을 재 배열하려면 'EmployeeId'열에 기본 키 제약 조건을 추가해야합니다.
    ALTER TABLE Employee add constraint [PK_dbo.Employee] 기본 키 (EmployeeId)

8. 이제 'EmployeeId'가있는 'Employee'테이블이 기존 기본 키 제약 조건과 함께 Identity 규칙에 대해 수정되었습니다.


3

설계 상 기존 열의 ID 기능을 켜거나 끄는 간단한 방법은 없습니다. 이 작업을 수행하는 유일한 방법은 새 열을 만들어 ID 열로 만들거나 새 테이블을 만들고 데이터를 마이그레이션하는 것입니다.

SQL Server Management Studio를 사용하여 "id"열의 ID 값을 제거하면 새 임시 테이블이 만들어지고 데이터가 임시 테이블로 이동되고 이전 테이블이 삭제되고 새 테이블의 이름이 바뀝니다.

Management Studio를 사용하여 변경 한 후 디자이너를 마우스 오른쪽 단추로 클릭하고 "변경 스크립트 생성"을 선택하십시오.

이것이 SQL Server가 백그라운드에서 수행하는 작업임을 알 수 있습니다.


2

슬프게도 하나도 없습니다. IDENTITY 속성은 열이 아닌 테이블에 속합니다.

가장 쉬운 방법은 GUI에서 수행하는 것이지만 이것이 옵션이 아닌 경우 데이터 복사, 열 삭제, ID로 다시 추가 및 데이터 다시 저장 등의 긴 작업을 수행 할 수 있습니다.

블로우 바이 계정에 대해서는 여기 를 참조 하십시오 .


2

개체 탐색기에서 테이블 이름을 마우스 오른쪽 버튼으로 클릭하십시오. 몇 가지 옵션이 제공됩니다. '디자인'을 클릭하십시오. 이 테이블에 대한 새 탭이 열립니다. 여기 '열 속성'에서 아이디 제약 조건을 추가 할 수 있습니다.


2

열의 아이디 속성을 수정하려면

  • 서버 탐색기에서 수정하려는 ID 속성이있는 테이블을 마우스 오른쪽 단추로 클릭하고 테이블 정의 열기를 클릭하십시오. 테이블이 테이블 디자이너에서 열립니다.
  • 변경하려는 열에 대해 널 허용 선택란을 지우십시오.
  • 열 특성 탭에서 ID 스펙 특성을 펼치십시오.
  • 아이덴티티 하위 속성의 그리드 셀을 클릭하고 드롭 다운 목록에서 예를 선택하십시오.
  • ID 시드 셀에 값을 입력하십시오. 이 값은 테이블의 첫 번째 행에 할당됩니다. 기본적으로 값 1이 할당됩니다.

그게 다야, 그것은 나를 위해 일했다.


2

Visual Studio 2017 이상을 사용하는 경우

  1. 서버 개체 탐색기에서 테이블을 마우스 오른쪽 버튼으로 클릭하고 "코드보기"를 선택하십시오.
  2. 열에 수정 자 "IDENTITY"추가
  3. 최신 정보

이것은 당신을 위해 모든 것을 할 것입니다.


예! 제안 해 주셔서 감사합니다! Windows 7 상자에 SSMS 버전이 없어 2017 년, SSMS는 2014, 2017 SSMS에는 Windows 10이 필요하기 때문에 프로덕션 서버의 테이블을 디자인으로 변경할 수 있습니다. VS 2017으로 이동> 서버 탐색기> 프로덕션 SQL Server에 새로 연결> 테이블을 마우스 오른쪽 단추로 클릭> "테이블 정의 열기"> Wala!
JustJohn

실제로 필드를 마우스 오른쪽 버튼으로 클릭하고 속성을 선택한 다음 예 또는 아니요를 선택하여 ID를 만들 수 있습니다.
JustJohn

1

원래 포스터가 실제로 기존 열을 PRIMARY KEY테이블에 대한 것으로 설정 하고 실제로 열이 열이 될 필요가없는 경우 IDENTITY(두 가지 다른 것) 다음과 같이 t-SQL을 통해 수행 할 수 있습니다.

ALTER TABLE [YourTableName]
ADD CONSTRAINT [ColumnToSetAsPrimaryKey] PRIMARY KEY ([ColumnToSetAsPrimaryKey])

PRIMARY KEY옵션 뒤에 열 이름을 괄호로 묶습니다 .

이 게시물은 오래되었지만 요청자의 요구에 대한 가정을하고 있지만이 추가 정보 가이 스레드를 겪는 사용자에게 도움이 될 수 있다고 생각했습니다. 대화로 인해 기존 열을 기본 키를 새 열로 먼저 추가하지 않으면 올바르지 않습니다.


1

현재 상태에 따라이 접근법을 따릅니다. 스크립트를 통해 데이터를 삽입 한 후 기본 테이블에 ID를 부여하고 싶습니다.

ID를 추가하고 싶기 때문에 항상 1에서 끝까지 원하는 레코드 수로 시작합니다.

--first drop column and add with identity
ALTER TABLE dbo.tblProductPriceList drop column ID 
ALTER TABLE dbo.tblProductPriceList add ID INT IDENTITY(1,1)

--then add primary key to that column (exist option you can ignore)
IF  NOT EXISTS (SELECT * FROM sys.key_constraints  WHERE object_id = OBJECT_ID(N'[dbo].[PK_tblProductPriceList]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblProductPriceList]'))
    ALTER TABLE [tblProductPriceList] ADD PRIMARY KEY (id)
GO

이것은 동일한 기본 키 열을 생성합니다

나는이 링크를 사용했다 : https://blog.sqlauthority.com/2014/10/11/sql-server-add-auto-incremental-identity-column-to-table-after-creating-table/

기존 테이블에 기본 키 추가


0

tsql을 사용하여 기존 열을 ID 열로 변경할 수 있다고 생각하지 않습니다. 그러나 Enterprise Manager 디자인보기를 통해이를 수행 할 수 있습니다.

또는 ID 열로 새 행을 만들고 이전 열을 삭제 한 다음 새 열의 이름을 바꿀 수 있습니다.

ALTER TABLE FooTable
ADD BarColumn INT IDENTITY(1, 1)
               NOT NULL
               PRIMARY KEY CLUSTERED

2
SSMS / Enterprise Manager를 통해이 작업을 수행하면 새 테이블을 만들고 데이터를 복사하고 이전 테이블을 삭제하고 새 테이블의 이름을 바꿉니다. 큰 테이블이 있으면 상당히 비쌀 수 있습니다 ...
Scott Ivey

0

기본적으로 네 가지 논리적 단계가 있습니다.

  1. 새 아이디 열을 만듭니다. 이 새 열에 대해 아이디 삽입을 설정하십시오.

  2. 소스 열 (ID로 변환하려는 열)의 데이터를이 새 열에 삽입합니다.

  3. 새 열의 아이디 삽입을 끕니다.

  4. 소스 열을 삭제하고 새 열의 이름을 소스 열의 이름으로 바꿉니다.

여러 서버에서 작업하는 등의 복잡성이 더있을 수 있습니다.

단계에 대해서는 다음 기사를 참조하십시오 (ssms 및 T-sql 사용). 이 단계는 T-SQL에 익숙하지 않은 초보자를위한 것입니다.

http://social.technet.microsoft.com/wiki/contents/articles/23816.how-to-convert-int-column-to-identity-in-the-ms-sql-server.aspx


0

아이덴티티 세트가없는 기본 키 = bigint를 가진 모든 테이블에 대한 스크립트를 생성합니다. 각 테이블과 함께 생성 된 스크립트 목록을 반환합니다.

SET NOCOUNT ON;

declare @sql table(s varchar(max), id int identity)

DECLARE @table_name nvarchar(max),
        @table_schema nvarchar(max);

DECLARE vendor_cursor CURSOR FOR 
SELECT
  t.name, s.name
FROM sys.schemas AS s
INNER JOIN sys.tables AS t
  ON s.[schema_id] = t.[schema_id]
WHERE EXISTS (
    SELECT
    [c].[name]
    from sys.columns [c]
    join sys.types [y] on [y].system_type_id = [c].system_type_id
    where [c].[object_id] = [t].[object_id] and [y].name = 'bigint' and [c].[column_id] = 1
) and NOT EXISTS 
(
  SELECT 1 FROM sys.identity_columns
    WHERE [object_id] = t.[object_id]
) and exists (
    select 1 from sys.indexes as [i] 
    inner join sys.index_columns as [ic]  ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
    where object_name([ic].[object_id]) = [t].[name]
)
OPEN vendor_cursor

FETCH NEXT FROM vendor_cursor 
INTO @table_name, @table_schema

WHILE @@FETCH_STATUS = 0
BEGIN

DELETE FROM @sql

declare @pkname varchar(100),
    @pkcol nvarchar(100)

SELECT  top 1
        @pkname = i.name,
        @pkcol = COL_NAME(ic.OBJECT_ID,ic.column_id)
FROM    sys.indexes AS [i]
INNER JOIN sys.index_columns AS [ic] ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
WHERE   i.is_primary_key = 1 and OBJECT_NAME(ic.OBJECT_ID) = @table_name

declare @q nvarchar(max) = 'SELECT  '+@pkcol+' FROM ['+@table_schema+'].['+@table_name+'] ORDER BY '+@pkcol+' DESC'

DECLARE @ident_seed nvarchar(max) -- Change this to the datatype that you are after
SET @q = REPLACE(@q, 'SELECT', 'SELECT TOP 1 @output = ')
EXEC sp_executeSql @q, N'@output bigint OUTPUT', @ident_seed OUTPUT

insert into  @sql(s) values ('BEGIN TRANSACTION')
insert into  @sql(s) values ('BEGIN TRY')

-- create statement
insert into  @sql(s) values ('create table ['+@table_schema+'].[' + @table_name + '_Temp] (')

-- column list
insert into @sql(s) 
select 
    '  ['+[c].[name]+'] ' +
    y.name + 

    (case when [y].[name] like '%varchar' then
    coalesce('('+(case when ([c].[max_length] < 0 or [c].[max_length] >= 1024) then 'max' else cast([c].max_length as varchar) end)+')','')
    else '' end)

     + ' ' +
    case when [c].name = @pkcol then 'IDENTITY(' +COALESCE(@ident_seed, '1')+',1)' else '' end + ' ' +
    ( case when c.is_nullable = 0 then 'NOT ' else '' end ) + 'NULL ' + 
    coalesce('DEFAULT ('+(
        REPLACE(
            REPLACE(
                LTrim(
                    RTrim(
                        REPLACE(
                            REPLACE(
                                REPLACE(
                                    REPLACE(
                                        LTrim(
                                            RTrim(
                                                REPLACE(
                                                    REPLACE(
                                                        object_definition([c].default_object_id)
                                                    ,' ','~')
                                                ,')',' ')
                                            )
                                        )
                                    ,' ','*')
                                ,'~',' ')
                            ,' ','~')
                        ,'(',' ')
                    )
                )
            ,' ','*')
        ,'~',' ')
    ) +
    case when object_definition([c].default_object_id) like '%get%date%' then '()' else '' end
    +
    ')','') + ','
 from sys.columns c
 JOIN sys.types y ON y.system_type_id = c.system_type_id
  where OBJECT_NAME(c.[object_id]) = @table_name and [y].name != 'sysname'
 order by [c].column_id


 update @sql set s=left(s,len(s)-1) where id=@@identity

-- closing bracket
insert into @sql(s) values( ')' )

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] ON')

declare @cols nvarchar(max)
SELECT @cols = STUFF(
    (
        select ',['+c.name+']'
        from sys.columns c
        JOIN sys.types y ON y.system_type_id = c.system_type_id
        where c.[object_id] = OBJECT_ID(@table_name)
        and [y].name != 'sysname'
        and [y].name != 'timestamp'
        order by [c].column_id
        FOR XML PATH ('')
     )
    , 1, 1, '')

insert into @sql(s) values( 'IF EXISTS(SELECT * FROM ['+@table_schema+'].['+@table_name+'])')
insert into @sql(s) values( 'EXEC(''INSERT INTO ['+@table_schema+'].['+@table_name+'_Temp] ('+@cols+')')
insert into @sql(s) values( 'SELECT '+@cols+' FROM ['+@table_schema+'].['+@table_name+']'')')

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] OFF')


insert into @sql(s) values( 'DROP TABLE ['+@table_schema+'].['+@table_name+']')

insert into @sql(s) values( 'EXECUTE sp_rename N''['+@table_schema+'].['+@table_name+'_Temp]'', N'''+@table_name+''', ''OBJECT''')

if ( @pkname is not null ) begin
    insert into @sql(s) values('ALTER TABLE ['+@table_schema+'].['+@table_name+'] ADD CONSTRAINT ['+@pkname+'] PRIMARY KEY CLUSTERED (')
    insert into @sql(s)
        select '  ['+COLUMN_NAME+'] ASC,' from information_schema.key_column_usage
        where constraint_name = @pkname
        GROUP BY COLUMN_NAME, ordinal_position
        order by ordinal_position

    -- remove trailing comma
    update @sql set s=left(s,len(s)-1) where id=@@identity
    insert into @sql(s) values ('  )')
end

insert into  @sql(s) values ('--Run your Statements')
insert into  @sql(s) values ('COMMIT TRANSACTION')
insert into  @sql(s) values ('END TRY')
insert into  @sql(s) values ('BEGIN CATCH')
insert into  @sql(s) values ('        ROLLBACK TRANSACTION')
insert into  @sql(s) values ('        DECLARE @Msg NVARCHAR(MAX)  ')
insert into  @sql(s) values ('        SELECT @Msg=ERROR_MESSAGE() ')
insert into  @sql(s) values ('        RAISERROR(''Error Occured: %s'', 20, 101,@msg) WITH LOG')
insert into  @sql(s) values ('END CATCH')

declare @fqry nvarchar(max)

-- result!
SELECT @fqry = (select char(10) + s from @sql order by id FOR XML PATH (''))


SELECT @table_name as [Table_Name], @fqry as [Generated_Query]
PRINT 'Table: '+@table_name
EXEC sp_executeSql @fqry

    FETCH NEXT FROM vendor_cursor 
    INTO @table_name, @table_schema
END 
CLOSE vendor_cursor;
DEALLOCATE vendor_cursor;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.