기존 테이블에서 테이블 (구조) 생성


101

다른 테이블과 구조가 동일해야하는 새 테이블을 만드는 방법

나는 시도했다

CREATE TABLE dom AS SELECT * FROM dom1 WHERE 1=2

하지만 작동하지 않는 오류가 발생했습니다.


항상 거짓 인 where 절을 사용하는 것은 매우 유용하고 흥미 롭습니다!
JosephDoggie 2017-08-09

답변:


168

시험:

Select * Into <DestinationTableName> From <SourceTableName> Where 1 = 2

이것은 인덱스, 키 등을 복사하지 않습니다.

전체 구조 를 복사 하려면 테이블의 Create Script를 생성해야합니다. 해당 스크립트를 사용하여 동일한 구조로 새 테이블을 만들 수 있습니다. 그런 다음 필요한 경우 데이터를 새 테이블에 덤프 할 수도 있습니다.

Enterprise Manager를 사용하는 경우 테이블을 마우스 오른쪽 단추로 클릭하고 복사를 선택하여 스크립트 작성을 생성하십시오.


1
Kevin, 답변의 작은 서식 변경 :-Select * Into <DestinationTableName> From <SourceTableName> Where 1 = 2
Ashish Gupta

6
Qutbuddin, 1 = 2는 소스에서 대상 테이블로의 데이터 복사를 방지합니다. -CREATE TABLE Table1 (Id int, Name varchar (200)) INSERT INTO table1 VALUES (1, 'A') INSERT INTO table1 VALUES (2, 'B')-table1의 데이터로 table2를 생성합니다 SELECT * INTO Table2 FROM Table1 WHERE 1 = 2-table1에 데이터없이 table2 생성 SELECT * INTO Table2 FROM Table1 WHERE 1 = 2
Ashish Gupta

나는 1 = 2가 데이터 복사를 피하기 위해 이상한 잘못된 주장이라고 생각했습니다.
Arthur Zennig

45

이것은 테이블 구조를 복제하는 데 사용하는 것입니다 (열만 해당) ...

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone

1
이 솔루션은 별도의 조건 "1 = 2"를하는 것보다 명확,이 추천 할 것입니다
Pinte 다니

31

구조 만 복사 (모든 열 복사)

Select Top 0 * into NewTable from OldTable

구조 만 복사 (일부 열 복사)

Select Top 0 Col1,Col2,Col3,Col4,Col5 into NewTable from OldTable

데이터로 구조 복사

Select * into NewTable from OldTable

이미 동일한 구조의 테이블이 있고 데이터 만 복사하려는 경우 다음을 사용하십시오.

Insert into NewTable Select * from OldTable

MSSQL 2008 R2에서 나를 위해 일한
황철석

간단하고 우아한 훌륭한 솔루션. 이 복사본 인덱스와 기본 키를 만드는 해킹이 있습니까?
Tumaini Mosha

16
Create table abc select * from def limit 0;

이것은 확실한 작업이 될 것입니다.


완전한! 감사합니다
Dylan B


8

다음을 수행 할 수 있다는 점도 언급 할 가치가 있습니다.

복제 할 테이블을 마우스 오른쪽 버튼으로 클릭 > 스크립트 테이블 형식 > 생성 대상 > 새 쿼리 편집기 창

그런 다음 생성 된 스크립트에서 방금 마우스 오른쪽 버튼으로 클릭 한 테이블의 이름이 어디에 표시되는지, 새 테이블을 호출 할 이름으로 변경하고 Execute


5

이것을 시도하십시오 .. 아래 하나는 기존 테이블의 전체 구조를 복사하지만 데이터는 복사하지 않습니다.

create table AT_QUOTE_CART as select * from QUOTE_CART where 0=1 ;

데이터를 복사하려면 아래 항목을 사용하십시오.

create table AT_QUOTE_CART as select * from QUOTE_CART ;

5

PK, 인덱스, 파티션 상태를 포함하여 테이블의 스키마를 복사하기 위해 다음 저장 프로 시저를 사용합니다. 매우 신속하지는 않지만 작업을 수행하는 것 같습니다. 속도를 높이는 방법에 대한 아이디어를 환영합니다.

    /*
        Clones a table's schema from an existing table (without data)
        if target table exists, it will be dropped first.
        The following schema elements are cloned:
            * Structure
            * Primary key
            * Indexes
            * Constraints
    DOES NOT copy:
        * Triggers
        * File groups

    ASSUMPTION: constraints are uniquely named with the table name, so that we dont end up with duplicate constraint names
*/
CREATE PROCEDURE [dbo].[spCloneTableStructure]

@SourceTable            nvarchar(255),
@DestinationTable       nvarchar(255),
@PartionField           nvarchar(255),
@SourceSchema           nvarchar(255) = 'dbo',  
@DestinationSchema      nvarchar(255) = 'dbo',    
@RecreateIfExists       bit = 1

AS
BEGIN

DECLARE @msg  nvarchar(200), @PartionScript nvarchar(255), @sql NVARCHAR(MAX)

    IF EXISTS(Select s.name As SchemaName, t.name As TableName
                        From sys.tables t
                        Inner Join sys.schemas s On t.schema_id = s.schema_id
                        Inner Join sys.partitions p on p.object_id = t.object_id
                        Where p.index_id In (0, 1) and t.name = @SourceTable
                        Group By s.name, t.name
                        Having Count(*) > 1)

        SET @PartionScript = ' ON [PS_PartitionByCompanyId]([' + @PartionField + '])'
    else
        SET @PartionScript = ''

SET NOCOUNT ON;
BEGIN TRY   
    SET @msg ='  CloneTable  ' + @DestinationTable + ' - Step 1, Drop table if exists. Timestamp: '  + CONVERT(NVARCHAR(50),GETDATE(),108)
     RAISERROR( @msg,0,1) WITH NOWAIT
    --drop the table
    if EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = @DestinationTable)
    BEGIN
        if @RecreateIfExists = 1
            BEGIN
                exec('DROP TABLE [' + @DestinationSchema + '].[' + @DestinationTable + ']')
            END
        ELSE
            RETURN
    END

    SET @msg ='  CloneTable  ' + @DestinationTable + ' - Step 2, Create table. Timestamp: '  + CONVERT(NVARCHAR(50),GETDATE(),108)
    RAISERROR( @msg,0,1) WITH NOWAIT
    --create the table
    exec('SELECT TOP (0) * INTO [' + @DestinationTable + '] FROM [' + @SourceTable + ']')       

    --create primary key
    SET @msg ='  CloneTable  ' + @DestinationTable + ' - Step 3, Create primary key. Timestamp: '  + CONVERT(NVARCHAR(50),GETDATE(),108)
    RAISERROR( @msg,0,1) WITH NOWAIT
    DECLARE @PKSchema nvarchar(255), @PKName nvarchar(255),@count   INT
    SELECT TOP 1 @PKSchema = CONSTRAINT_SCHEMA, @PKName = CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = @SourceSchema AND TABLE_NAME = @SourceTable AND CONSTRAINT_TYPE = 'PRIMARY KEY'
    IF NOT @PKSchema IS NULL AND NOT @PKName IS NULL
    BEGIN
        DECLARE @PKColumns nvarchar(MAX)
        SET @PKColumns = ''

        SELECT @PKColumns = @PKColumns + '[' + COLUMN_NAME + '],'
            FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
            where TABLE_NAME = @SourceTable and TABLE_SCHEMA = @SourceSchema AND CONSTRAINT_SCHEMA = @PKSchema AND CONSTRAINT_NAME= @PKName
            ORDER BY ORDINAL_POSITION

        SET @PKColumns = LEFT(@PKColumns, LEN(@PKColumns) - 1)

        exec('ALTER TABLE [' + @DestinationSchema + '].[' + @DestinationTable + '] ADD  CONSTRAINT [PK_' + @DestinationTable + '] PRIMARY KEY CLUSTERED (' + @PKColumns + ')' + @PartionScript);
    END

    --create other indexes
    SET @msg ='  CloneTable  ' + @DestinationTable + ' - Step 4, Create Indexes. Timestamp: '  + CONVERT(NVARCHAR(50),GETDATE(),108)
    RAISERROR( @msg,0,1) WITH NOWAIT
    DECLARE @IndexId int, @IndexName nvarchar(255), @IsUnique bit, @IsUniqueConstraint bit, @FilterDefinition nvarchar(max), @type int

    set @count=0
    DECLARE indexcursor CURSOR FOR
    SELECT index_id, name, is_unique, is_unique_constraint, filter_definition, type FROM sys.indexes WHERE is_primary_key = 0 and object_id = object_id('[' + @SourceSchema + '].[' + @SourceTable + ']')
    OPEN indexcursor;
    FETCH NEXT FROM indexcursor INTO @IndexId, @IndexName, @IsUnique, @IsUniqueConstraint, @FilterDefinition, @type
    WHILE @@FETCH_STATUS = 0
       BEGIN
            set @count =@count +1
            DECLARE @Unique nvarchar(255)
            SET @Unique = CASE WHEN @IsUnique = 1 THEN ' UNIQUE ' ELSE '' END

            DECLARE @KeyColumns nvarchar(max), @IncludedColumns nvarchar(max)
            SET @KeyColumns = ''
            SET @IncludedColumns = ''

            select @KeyColumns = @KeyColumns + '[' + c.name + '] ' + CASE WHEN is_descending_key = 1 THEN 'DESC' ELSE 'ASC' END + ',' from sys.index_columns ic
            inner join sys.columns c ON c.object_id = ic.object_id and c.column_id = ic.column_id
            where index_id = @IndexId and ic.object_id = object_id('[' + @SourceSchema + '].[' + @SourceTable + ']') and key_ordinal > 0
            order by index_column_id

            select @IncludedColumns = @IncludedColumns + '[' + c.name + '],' from sys.index_columns ic
            inner join sys.columns c ON c.object_id = ic.object_id and c.column_id = ic.column_id
            where index_id = @IndexId and ic.object_id = object_id('[' + @SourceSchema + '].[' + @SourceTable + ']') and key_ordinal = 0
            order by index_column_id

            IF LEN(@KeyColumns) > 0
                SET @KeyColumns = LEFT(@KeyColumns, LEN(@KeyColumns) - 1)

            IF LEN(@IncludedColumns) > 0
            BEGIN
                SET @IncludedColumns = ' INCLUDE (' + LEFT(@IncludedColumns, LEN(@IncludedColumns) - 1) + ')'
            END

            IF @FilterDefinition IS NULL
                SET @FilterDefinition = ''
            ELSE
                SET @FilterDefinition = 'WHERE ' + @FilterDefinition + ' '

            SET @msg ='  CloneTable  ' + @DestinationTable + ' - Step 4.' + CONVERT(NVARCHAR(5),@count) + ', Create Index ' + @IndexName + '. Timestamp: '  + CONVERT(NVARCHAR(50),GETDATE(),108)
            RAISERROR( @msg,0,1) WITH NOWAIT

            if @type = 2
                SET @sql = 'CREATE ' + @Unique + ' NONCLUSTERED INDEX [' + @IndexName + '] ON [' + @DestinationSchema + '].[' + @DestinationTable + '] (' + @KeyColumns + ')' + @IncludedColumns + @FilterDefinition  + @PartionScript
            ELSE
                BEGIN
                    SET @sql = 'CREATE ' + @Unique + ' CLUSTERED INDEX [' + @IndexName + '] ON [' + @DestinationSchema + '].[' + @DestinationTable + '] (' + @KeyColumns + ')' + @IncludedColumns + @FilterDefinition + @PartionScript
                END
            EXEC (@sql)
            FETCH NEXT FROM indexcursor INTO @IndexId, @IndexName, @IsUnique, @IsUniqueConstraint, @FilterDefinition, @type
       END
    CLOSE indexcursor
    DEALLOCATE indexcursor

    --create constraints
    SET @msg ='  CloneTable  ' + @DestinationTable + ' - Step 5, Create constraints. Timestamp: '  + CONVERT(NVARCHAR(50),GETDATE(),108)
    RAISERROR( @msg,0,1) WITH NOWAIT
    DECLARE @ConstraintName nvarchar(max), @CheckClause nvarchar(max), @ColumnName NVARCHAR(255)
    DECLARE const_cursor CURSOR FOR
        SELECT
            REPLACE(dc.name, @SourceTable, @DestinationTable),[definition], c.name
        FROM sys.default_constraints dc
            INNER JOIN sys.columns c ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id
        WHERE OBJECT_NAME(parent_object_id) =@SourceTable               
    OPEN const_cursor
    FETCH NEXT FROM const_cursor INTO @ConstraintName, @CheckClause, @ColumnName
    WHILE @@FETCH_STATUS = 0
       BEGIN
            exec('ALTER TABLE [' + @DestinationTable + '] ADD CONSTRAINT [' + @ConstraintName + '] DEFAULT ' + @CheckClause + ' FOR ' + @ColumnName)
            FETCH NEXT FROM const_cursor INTO @ConstraintName, @CheckClause, @ColumnName
       END;
    CLOSE const_cursor
    DEALLOCATE const_cursor                 


END TRY
    BEGIN CATCH
        IF (SELECT CURSOR_STATUS('global','indexcursor')) >= -1
        BEGIN
         DEALLOCATE indexcursor
        END

        IF (SELECT CURSOR_STATUS('global','const_cursor')) >= -1
        BEGIN
         DEALLOCATE const_cursor
        END


        PRINT 'Error Message: ' + ERROR_MESSAGE(); 
    END CATCH

END

GO

1
이것을 더 빠르게 만드는 것은 커서를 선언하는 것처럼 간단 할 수 있습니다 CURSOR LOCAL FAST_FORWARD. 개인적으로 커서를 사용하지 않고 비슷한 스크립트를 만들고 어떻게 작동하는지 확인하려고합니다.
mendosi

안녕하세요 @mendosi 저는 그것이 오래되었다는 것을 알고 있지만 현재 열 정의와 함께 모든 기타 사항 (제약 조건 / 인덱스 / 파티션 / 트리거 / 등)을 사용하여 CREATE 스크립트를 생성하는 방법을 찾고 있습니다. 커서가 아닌 접근 방식으로 이것을 재현하는 데 성공했는지 궁금합니다. 그렇다면 공유해 주시겠습니까? 대단히 감사합니다. 감사합니다
007

내가 작성한 스크립트는 하나 이상의 테이블을 복사하고 커서를 사용하지 않습니다. 댓글도 너무 큽니다. 대신 Hans Michiels 스크립트에 연결하겠습니다. hansmichiels.com/2016/02/18/…
mendosi

4
  1. 동일한 데이터베이스를 복사하려는 경우

    Select * INTO NewTableName from OldTableName
  2. 다른 데이터베이스 인 경우

    Select * INTO NewTableName from DatabaseName.OldTableName


3

왜 그렇게 하려는지 모르겠지만 시도해보십시오.

SELECT *
INTO NewTable
FROM OldTable
WHERE 1 = 2

작동합니다.


나는 그것도 데이터를 복사 할 것이라고 생각합니까? 그는 구조만을 원합니다.
Ashish Gupta

@Ashis 굽타 - 덕분에, 나는 "": 잊었습니다
아드리안 Fâciu

3
Copy the table structure:-
select * into newtable from oldtable where 1=2;

Copy the table structure along with table data:-
select * into newtable from oldtable where 1=1;

3
이 제약과 키를 복사하지 않습니다
Trikaldarshi

2

내가 찾던 것을 여기서 찾았습니다. 내가 3-4 년 전에 사용한 것을 기억하는 데 도움이되었습니다.

테이블 조인으로 인한 데이터로 테이블을 생성 할 수 있도록 동일한 구문을 재사용하고 싶었습니다.

몇 번의 시도 후에 아래 쿼리가 나타났습니다.

SELECT a.*
INTO   DetailsArchive
FROM   (SELECT d.*
        FROM   details AS d
               INNER JOIN
               port AS p
               ON p.importid = d.importid
        WHERE  p.status = 2) AS a;

0
SELECT * INTO newtable
from Oldtable

가독성을 높이려면 코드 마크 업을 사용하십시오. 또한 코드에 대해 약간 설명하는 데 더 유용합니다.
Nima Derakhshanjan

즉각적인 도움을 줄 수있는이 코드 스 니펫에 감사드립니다. 적절한 설명 이것이 문제에 대한 좋은 해결책 인 이유 를 보여줌으로써 교육적 가치를 크게 향상시키고 유사하지만 동일하지는 않은 질문을 가진 미래의 독자에게 더 유용하게 만들 것입니다. 특히 훈련되지 않은 눈에는 Oldtable. 어떻게 피할 수 있습니까?
토비 Speight

-1

원본 테이블에서 복사 할 유일한 구조로 테이블을 생성하려는 경우 다음 명령을 사용하여 수행 할 수 있습니다.

create table <tablename> as select * from <sourcetablename> where 1>2;

이 거짓 조건으로 기록을 남기고 구조를 복사 할 수 있습니다.


이것은 기존 답변의 중복입니다. 새 답변을 제출하기 전에 기존 답변을 읽고 적절한 경우 의견 / 투표를 추가하십시오.
Kevin Hogg

하지만이 작업을 수행하기 위해 create 명령을 사용했습니다.
Sai Durga Kamesh Kota

@AbhiUrs 답변 (2015 년 1 월 2 일)을 검토하면 답변은 where 절이 약간 다르지만 답변의 첫 부분과 비슷합니다. 첫 번째 부분 => create table AT_QUOTE_CART as select * from QUOTE_CART where 0=1 ; 해당 테이블 이름을 바꾸면 다음과 같은 결과가 나타납니다 create table <tablename> as select * from <sourcetablename> where 0=1 ; . where 절의 경우 검색된 데이터가없는 0=1것과 동일한 결과를 얻습니다 1>2.
Kevin Hogg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.