테이블의 전체 구조 복사


33

일부 방법을 사용하면 테이블 복사본을 만들 때 인덱스, PK, FK 등이 손실됩니다. 예를 들어 SQL Server에서는 다음과 같이 말할 수 있습니다.

select * into dbo.table2 from dbo.table1;

이것은 테이블의 단순한 사본입니다. 모든 인덱스 / 제약이 없습니다. 백업을 사용하지 않고 테이블 구조를 어떻게 복사 할 수 있습니까?

나는 주로 수동 으로이 작업을 수행하려고하지만 불가능한 경우 해결책을 받아 들일 것입니다.

답변:


30

물론 UI를 사용하여 테이블을 비교적 쉽게 스크립팅 할 수 있습니다.

여기에 이미지 설명을 입력하십시오

그러면 CREATE TABLE스크립트 가 출력 되며 이전 이름을 검색하여 새 이름으로 바꾸면됩니다 (그리고 새 이름을 가진 개체가 아직 존재하지 않는지 확인).

그러나 이것을 자동화하려고하면 (예 : 코드에서 테이블 작성 스크립트 생성) 좀 더 성가시다. 위의 스크립팅 옵션은 CREATE TABLE메타 데이터의 단일 위치에서 전체 DDL을 가져 오는 것이 아닙니다 . 코드에서 장면 뒤에서 마술을 많이 사용하여 최종 CREATE TABLE스크립트 를 생성합니다 (프로파일 러를 사용하여 데이터를 가져 오는 위치를 볼 수는 있지만 어떻게 어셈블하는지 알 수는 없습니다). 나는 이것에 대한 옵션을 제안했다.

http://connect.microsoft.com/SQLServer/feedback/details/273934

그러나 이것은 매우 적은 표를 얻었고 Microsoft에 의해 신속하게 격추되었습니다. 스키마 생성을 위해 타사 도구를 사용하는 것이 훨씬 더 가치가 있음을 알 수 있습니다 ( 블로그에 대해 블로그했습니다 ).

SQL Server 2012에는 2005, 2008 및 2008 R2에서 수행해야하는 작업보다 훨씬 가까이 접근 할 수있는 메타 데이터 기능이 새로 추가되어 메타 데이터의 열 정보 (예 : [n [var [char]]에 길이 사양을 추가해야하는 경우 정밀도 / 스케일을 추가해야합니다. n [var] char에 대해 max_length를 반으로 잘라야하는 경우 MAX 인 경우 -1을 MAX 등으로 변경하십시오). SQL Server 2012에서는이 부분이 조금 더 쉽습니다.

SELECT name, system_type_name, is_nullable FROM
  sys.dm_exec_describe_first_result_set('select * from sys.objects', NULL, 0)

결과 :

name                   system_type_name  is_nullable
--------------------   ----------------  -----------
name                   nvarchar(128)     0
object_id              int               0
principal_id           int               1
schema_id              int               0
parent_object_id       int               0
type                   char(2)           0
type_desc              nvarchar(60)      1
create_date            datetime          0
modify_date            datetime          0
is_ms_shipped          bit               0
is_published           bit               0
is_schema_published    bit               0

나도 이것에 대해 블로그했습니다.

아마도 이것은을 CREATE TABLE사용하는 복잡한 접근법보다 목표 진술에 훨씬 가깝지만 sys.columns여전히 할 일이 많이 있습니다. 키, 제약 조건, 텍스트 행 옵션, 파일 그룹 정보, 압축 설정, 색인 등 매우 긴 목록이므로 다시 반복 할 위험이 있으므로 타사 도구를 다시 살펴볼 것을 제안합니다. 바퀴를 재발 명하는 비유를 사용했습니다.

코드를 통해이 작업을 수행해야하지만 SQL Server 외부에서 수행 할 수 있다면 SMO / PowerShell을 고려할 수 있습니다. 이 팁Scripter.Script () 메서드를 참조하십시오 .


sys.dm_exec_describe_first_result_set은 OLEDB에서 실행될 경우 datetime2 대신 nvarchar (27)을 표시합니다.
Alsin

이것은 적대적이거나 부정적인 것이 아닙니다. 그러나 이런 종류의 일은 SQL로 20 년 후 Postgres로 이사 한 이유입니다. Postgres 솔루션은 다음과 같습니다. CREATE TABLE tbl2 (LIKE tbl1 INCLUDING ALL); -모든 색인 주석 등을 포함한 표를 복제합니다.
Damien Sawyer

@DamienSawyer 공정하게, 동일한 인덱스와 다른 모든 것을 가진 동일한 테이블을 여러 개 만드는 것은 일종의 디자인 냄새입니다. 그리고 실제로 필요할 때 도움을 줄 수있는 많은 타사 도구 (일부 무료, 일부 오픈 소스)가 있습니다.
Aaron Bertrand

물론 @AaronBertrand는 특히 유비쿼터스 3NF CRUD 스타일 스키마에서 매우 사실입니다. 때때로 우리는 데이터베이스를 덜 단단하게 사용합니다. 예를 들어, CSV와 같은 비공식 소스에서 데이터를 정리하여 프로덕션 시스템으로 마이그레이션하는 등의 데이터를 정리합니다. 비교를 위해 Excel이 훌륭한 이유 중 하나는 통합 문서가 복잡해질 수 있지만 매우 간단한식이 없기 때문입니다. 한 장의 종이는 집을 사기위한 계약과 쇼핑리스트를 작성하는 계약으로 사용될 수 있습니다.
Damien Sawyer

@DamienSawyer 그리고 기본적으로 폐기 단계 준비 테이블 인 중간 프로세스가있을 때 테이블에 존재하는 인덱스, 제약 조건, 확장 속성 등을 모두 포함 할 필요는 없다고 주장합니다. 그것을 모델화하고 있습니다. 다른 사용 사례가 존재하더라도 기본 동작에는 매우 유효한 사용 사례가 있습니다.
Aaron Bertrand

9

이 sp를 작성하여 모든 것, pk, fk, 파티션, 제약 조건이있는 스키마를 자동으로 생성했습니다 ...

중대한!! 집행 전

create type TestTableType as table (ObjectID int)

여기 SP :

    SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


    --*************************************************************************************************'
--    La procedura crea lo script di una tabella
--    Tabella   : xxxxx
--    Creata da : E.Mantovanelli
--    Data creazione : 28-06-2012
--    Data modifica: 28-06-2012
--*************************************************************************************************'

/*
    --      ID----|-----Data-----|--    User        ---------   | ----  Note
                        20-11-2013      E.Mantovanelli                  distinzione schema delle tabelle
                                                                        estrazione da db selezionato
                                                                        aggiunta estrazione partizione
*/

CREATE PROCEDURE [dbo].[util_ScriptTable] 
     @DBName SYSNAME
    ,@schema sysname
    ,@TableName SYSNAME
    ,@IncludeConstraints BIT = 1
    ,@IncludeIndexes BIT = 1
    ,@NewTableSchema sysname
    ,@NewTableName SYSNAME = NULL
    ,@UseSystemDataTypes BIT = 0
    ,@script varchar(max) output
AS 
BEGIN try
    if not exists (select * from sys.types where name = 'TestTableType')
        create type TestTableType as table (ObjectID int)--drop type TestTableType

    declare @sql nvarchar(max)

    DECLARE @MainDefinition TABLE (FieldValue VARCHAR(200))
    --DECLARE @DBName SYSNAME
    DECLARE @ClusteredPK BIT
    DECLARE @TableSchema NVARCHAR(255)

    --SET @DBName = DB_NAME(DB_ID())
    SELECT @TableName = name FROM sysobjects WHERE id = OBJECT_ID(@TableName)

    DECLARE @ShowFields TABLE (FieldID INT IDENTITY(1,1)
                                        ,DatabaseName VARCHAR(100)
                                        ,TableOwner VARCHAR(100)
                                        ,TableName VARCHAR(100)
                                        ,FieldName VARCHAR(100)
                                        ,ColumnPosition INT
                                        ,ColumnDefaultValue VARCHAR(100)
                                        ,ColumnDefaultName VARCHAR(100)
                                        ,IsNullable BIT
                                        ,DataType VARCHAR(100)
                                        ,MaxLength varchar(10)
                                        ,NumericPrecision INT
                                        ,NumericScale INT
                                        ,DomainName VARCHAR(100)
                                        ,FieldListingName VARCHAR(110)
                                        ,FieldDefinition CHAR(1)
                                        ,IdentityColumn BIT
                                        ,IdentitySeed INT
                                        ,IdentityIncrement INT
                                        ,IsCharColumn BIT 
                                        ,IsComputed varchar(255))

    DECLARE @HoldingArea TABLE(FldID SMALLINT IDENTITY(1,1)
                                        ,Flds VARCHAR(4000)
                                        ,FldValue CHAR(1) DEFAULT(0))

    DECLARE @PKObjectID TABLE(ObjectID INT)

    DECLARE @Uniques TABLE(ObjectID INT)

    DECLARE @HoldingAreaValues TABLE(FldID SMALLINT IDENTITY(1,1)
                                                ,Flds VARCHAR(4000)
                                                ,FldValue CHAR(1) DEFAULT(0))

    DECLARE @Definition TABLE(DefinitionID SMALLINT IDENTITY(1,1)
                                        ,FieldValue VARCHAR(200))


  set @sql=
  '
  use '+@DBName+'
  SELECT distinct DB_NAME()
            ,TABLE_SCHEMA
            ,TABLE_NAME
            ,''[''+COLUMN_NAME+'']'' as COLUMN_NAME
            ,CAST(ORDINAL_POSITION AS INT)
            ,COLUMN_DEFAULT
            ,dobj.name AS ColumnDefaultName
            ,CASE WHEN c.IS_NULLABLE = ''YES'' THEN 1 ELSE 0 END
            ,DATA_TYPE
            ,case CHARACTER_MAXIMUM_LENGTH when -1 then ''max'' else CAST(CHARACTER_MAXIMUM_LENGTH AS varchar) end--CAST(CHARACTER_MAXIMUM_LENGTH AS INT)
            ,CAST(NUMERIC_PRECISION AS INT)
            ,CAST(NUMERIC_SCALE AS INT)
            ,DOMAIN_NAME
            ,COLUMN_NAME + '',''
            ,'''' AS FieldDefinition
            ,CASE WHEN ic.object_id IS NULL THEN 0 ELSE 1 END AS IdentityColumn
            ,CAST(ISNULL(ic.seed_value,0) AS INT) AS IdentitySeed
            ,CAST(ISNULL(ic.increment_value,0) AS INT) AS IdentityIncrement
            ,CASE WHEN st.collation_name IS NOT NULL THEN 1 ELSE 0 END AS IsCharColumn 
            ,cc.definition 
            FROM INFORMATION_SCHEMA.COLUMNS c
            JOIN sys.columns sc ON  c.TABLE_NAME = OBJECT_NAME(sc.object_id) AND c.COLUMN_NAME = sc.Name
            LEFT JOIN sys.identity_columns ic ON c.TABLE_NAME = OBJECT_NAME(ic.object_id) AND c.COLUMN_NAME = ic.Name
            JOIN sys.types st ON COALESCE(c.DOMAIN_NAME,c.DATA_TYPE) = st.name
            LEFT OUTER JOIN sys.objects dobj ON dobj.object_id = sc.default_object_id AND dobj.type = ''D''
            left join sys.computed_columns cc on c.TABLE_NAME=OBJECT_NAME(cc.object_id) and sc.column_id=cc.column_id
    WHERE c.TABLE_NAME = @TableName and c.TABLE_SCHEMA=@schema 
    ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION
    '

  print @sql
  INSERT INTO @ShowFields( DatabaseName
                                    ,TableOwner
                                    ,TableName
                                    ,FieldName
                                    ,ColumnPosition
                                    ,ColumnDefaultValue
                                    ,ColumnDefaultName
                                    ,IsNullable
                                    ,DataType
                                    ,MaxLength
                                    ,NumericPrecision
                                    ,NumericScale
                                    ,DomainName
                                    ,FieldListingName
                                    ,FieldDefinition
                                    ,IdentityColumn
                                    ,IdentitySeed
                                    ,IdentityIncrement
                                    ,IsCharColumn
                                    ,IsComputed)

    exec sp_executesql @sql,
                       N'@TableName varchar(50),@schema varchar(50)',
                       @TableName=@TableName,@schema=@schema            
    /*
    SELECT @DBName--DB_NAME()
            ,TABLE_SCHEMA
            ,TABLE_NAME
            ,COLUMN_NAME
            ,CAST(ORDINAL_POSITION AS INT)
            ,COLUMN_DEFAULT
            ,dobj.name AS ColumnDefaultName
            ,CASE WHEN c.IS_NULLABLE = 'YES' THEN 1 ELSE 0 END
            ,DATA_TYPE
            ,CAST(CHARACTER_MAXIMUM_LENGTH AS INT)
            ,CAST(NUMERIC_PRECISION AS INT)
            ,CAST(NUMERIC_SCALE AS INT)
            ,DOMAIN_NAME
            ,COLUMN_NAME + ','
            ,'' AS FieldDefinition
            ,CASE WHEN ic.object_id IS NULL THEN 0 ELSE 1 END AS IdentityColumn
            ,CAST(ISNULL(ic.seed_value,0) AS INT) AS IdentitySeed
            ,CAST(ISNULL(ic.increment_value,0) AS INT) AS IdentityIncrement
            ,CASE WHEN st.collation_name IS NOT NULL THEN 1 ELSE 0 END AS IsCharColumn 
            FROM INFORMATION_SCHEMA.COLUMNS c
            JOIN sys.columns sc ON  c.TABLE_NAME = OBJECT_NAME(sc.object_id) AND c.COLUMN_NAME = sc.Name
            LEFT JOIN sys.identity_columns ic ON c.TABLE_NAME = OBJECT_NAME(ic.object_id) AND c.COLUMN_NAME = ic.Name
            JOIN sys.types st ON COALESCE(c.DOMAIN_NAME,c.DATA_TYPE) = st.name
            LEFT OUTER JOIN sys.objects dobj ON dobj.object_id = sc.default_object_id AND dobj.type = 'D'

    WHERE c.TABLE_NAME = @TableName
    ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION
    */
    SELECT TOP 1 @TableSchema = TableOwner FROM @ShowFields

    INSERT INTO @HoldingArea (Flds) VALUES('(')

    INSERT INTO @Definition(FieldValue)VALUES('CREATE TABLE ' + CASE WHEN @NewTableName IS NOT NULL THEN @DBName + '.' + @NewTableSchema + '.' + @NewTableName ELSE @DBName + '.' + @TableSchema + '.' + @TableName END)
    INSERT INTO @Definition(FieldValue)VALUES('(')
    INSERT INTO @Definition(FieldValue)
    SELECT   CHAR(10) + FieldName + ' ' + 
        --CASE WHEN DomainName IS NOT NULL AND @UseSystemDataTypes = 0 THEN DomainName + CASE WHEN IsNullable = 1 THEN ' NULL ' ELSE ' NOT NULL ' END ELSE UPPER(DataType) +CASE WHEN IsCharColumn = 1 THEN '(' + CAST(MaxLength AS VARCHAR(10)) + ')' ELSE '' END +CASE WHEN IdentityColumn = 1 THEN ' IDENTITY(' + CAST(IdentitySeed AS VARCHAR(5))+ ',' + CAST(IdentityIncrement AS VARCHAR(5)) + ')' ELSE '' END +CASE WHEN IsNullable = 1 THEN ' NULL ' ELSE ' NOT NULL ' END +CASE WHEN ColumnDefaultName IS NOT NULL AND @IncludeConstraints = 1 THEN 'CONSTRAINT [' + ColumnDefaultName + '] DEFAULT' + UPPER(ColumnDefaultValue) ELSE '' END END + CASE WHEN FieldID = (SELECT MAX(FieldID) FROM @ShowFields) THEN '' ELSE ',' END 

        CASE WHEN DomainName IS NOT NULL AND @UseSystemDataTypes = 0 THEN DomainName + 
            CASe WHEN IsNullable = 1 THEN ' NULL ' 
            ELSE ' NOT NULL ' 
            END 
        ELSE 
            case when IsComputed is null then
                UPPER(DataType) +
                CASE WHEN IsCharColumn = 1 THEN '(' + CAST(MaxLength AS VARCHAR(10)) + ')' 
                ELSE 
                    CASE WHEN DataType = 'numeric' THEN '(' + CAST(NumericPrecision AS VARCHAR(10))+','+ CAST(NumericScale AS VARCHAR(10)) + ')' 
                    ELSE
                        CASE WHEN DataType = 'decimal' THEN '(' + CAST(NumericPrecision AS VARCHAR(10))+','+ CAST(NumericScale AS VARCHAR(10)) + ')' 
                        ELSE '' 
                        end  
                    end 
                END +
                CASE WHEN IdentityColumn = 1 THEN ' IDENTITY(' + CAST(IdentitySeed AS VARCHAR(5))+ ',' + CAST(IdentityIncrement AS VARCHAR(5)) + ')' 
                ELSE '' 
                END +
                CASE WHEN IsNullable = 1 THEN ' NULL ' 
                ELSE ' NOT NULL ' 
                END +
                CASE WHEN ColumnDefaultName IS NOT NULL AND @IncludeConstraints = 1 THEN 'CONSTRAINT [' + replace(ColumnDefaultName,@TableName,@NewTableName) + '] DEFAULT' + UPPER(ColumnDefaultValue) 
                ELSE '' 
                END 
            else
                ' as '+IsComputed+' '
            end
        END + 
        CASE WHEN FieldID = (SELECT MAX(FieldID) FROM @ShowFields) THEN '' 
        ELSE ',' 
        END 

    FROM    @ShowFields

    IF @IncludeConstraints = 1
        BEGIN    

        set @sql=
        '
        use '+@DBName+'
        SELECT  distinct  '',CONSTRAINT ['' + replace(name,@TableName,@NewTableName) + ''] FOREIGN KEY ('' + ParentColumns + '') REFERENCES ['' + ReferencedObject + '']('' + ReferencedColumns + '')'' 
           FROM ( SELECT   ReferencedObject = OBJECT_NAME(fk.referenced_object_id), ParentObject = OBJECT_NAME(parent_object_id),fk.name
                ,   REVERSE(SUBSTRING(REVERSE((   SELECT cp.name + '',''   
                FROM   sys.foreign_key_columns fkc   
                JOIN sys.columns cp ON fkc.parent_object_id = cp.object_id AND fkc.parent_column_id = cp.column_id   
                WHERE fkc.constraint_object_id = fk.object_id   FOR XML PATH('''')   )), 2, 8000)) ParentColumns,   
                REVERSE(SUBSTRING(REVERSE((   SELECT cr.name + '',''   
                FROM   sys.foreign_key_columns fkc  
                JOIN sys.columns cr ON fkc.referenced_object_id = cr.object_id AND fkc.referenced_column_id = cr.column_id
                WHERE fkc.constraint_object_id = fk.object_id   FOR XML PATH('''')   )), 2, 8000)) ReferencedColumns   
                FROM sys.foreign_keys fk    
                    inner join sys.schemas s on fk.schema_id=s.schema_id and s.name=@schema) a    
            WHERE ParentObject = @TableName    
        '

        print @sql

        INSERT INTO @Definition(FieldValue)
        exec sp_executesql @sql,
                   N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50)',
                       @TableName=@TableName,@NewTableName=@NewTableName,@schema=@schema
            /*
           SELECT    ',CONSTRAINT [' + name + '] FOREIGN KEY (' + ParentColumns + ') REFERENCES [' + ReferencedObject + '](' + ReferencedColumns + ')'  
           FROM ( SELECT   ReferencedObject = OBJECT_NAME(fk.referenced_object_id), ParentObject = OBJECT_NAME(parent_object_id),fk.name
                ,   REVERSE(SUBSTRING(REVERSE((   SELECT cp.name + ','   
                FROM   sys.foreign_key_columns fkc   
                JOIN sys.columns cp ON fkc.parent_object_id = cp.object_id AND fkc.parent_column_id = cp.column_id   
                WHERE fkc.constraint_object_id = fk.object_id   FOR XML PATH('')   )), 2, 8000)) ParentColumns,   
                REVERSE(SUBSTRING(REVERSE((   SELECT cr.name + ','   
                FROM   sys.foreign_key_columns fkc  
                JOIN sys.columns cr ON fkc.referenced_object_id = cr.object_id AND fkc.referenced_column_id = cr.column_id
                WHERE fkc.constraint_object_id = fk.object_id   FOR XML PATH('')   )), 2, 8000)) ReferencedColumns   
                FROM sys.foreign_keys fk    ) a    
            WHERE ParentObject = @TableName    
            */

            set @sql=
            '
            use '+@DBName+'
            SELECT distinct '',CONSTRAINT ['' + replace(c.name,@TableName,@NewTableName) + ''] CHECK '' + definition 
            FROM sys.check_constraints c join sys.schemas s on c.schema_id=s.schema_id and s.name=@schema    
            WHERE OBJECT_NAME(parent_object_id) = @TableName
            '

            print @sql
            INSERT INTO @Definition(FieldValue) 
            exec sp_executesql @sql,
                               N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50)',
                       @TableName=@TableName,@NewTableName=@NewTableName,@schema=@schema
            /*
            SELECT ',CONSTRAINT [' + name + '] CHECK ' + definition FROM sys.check_constraints    
            WHERE OBJECT_NAME(parent_object_id) = @TableName
            */

            set @sql=
            '
            use '+@DBName+'
            SELECT DISTINCT  PKObject = cco.object_id 
            FROM    sys.key_constraints cco    
            JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id    
            JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id
            join sys.schemas s on cco.schema_id=s.schema_id and s.name=@schema
            WHERE    OBJECT_NAME(parent_object_id) = @TableName    AND  i.type = 1 AND    is_primary_key = 1
            '
            print @sql
            INSERT INTO @PKObjectID(ObjectID) 
            exec sp_executesql @sql,
                               N'@TableName varchar(50),@schema varchar(50)',
                               @TableName=@TableName,@schema=@schema
            /*
            SELECT DISTINCT  PKObject = cco.object_id 
            FROM    sys.key_constraints cco    
            JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id    
            JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id
            WHERE    OBJECT_NAME(parent_object_id) = @TableName    AND  i.type = 1 AND    is_primary_key = 1
            */

            set @sql=
            '
            use '+@DBName+'
            SELECT DISTINCT    PKObject = cco.object_id
            FROM    sys.key_constraints cco   
            JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id  
            JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id
            join sys.schemas s on cco.schema_id=s.schema_id and s.name=@schema
            WHERE    OBJECT_NAME(parent_object_id) = @TableName AND  i.type = 2 AND    is_primary_key = 0 AND    is_unique_constraint = 1
            '
            print @sql
            INSERT INTO @Uniques(ObjectID)
            exec sp_executesql @sql,
                               N'@TableName varchar(50),@schema varchar(50)',
                               @TableName=@TableName,@schema=@schema
            /*
            SELECT DISTINCT    PKObject = cco.object_id
            FROM    sys.key_constraints cco   
            JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id  
            JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id
            WHERE    OBJECT_NAME(parent_object_id) = @TableName AND  i.type = 2 AND    is_primary_key = 0 AND    is_unique_constraint = 1
            */

            SET @ClusteredPK = CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE 0 END

            declare @t TestTableType
            insert @t select * from @PKObjectID
            declare @u TestTableType
            insert @u select * from @Uniques

            set @sql=
            '
            use '+@DBName+'
            SELECT distinct '',CONSTRAINT '' + replace(cco.name,@TableName,@NewTableName) + CASE type WHEN ''PK'' THEN '' PRIMARY KEY '' + CASE WHEN pk.ObjectID IS NULL THEN '' NONCLUSTERED '' ELSE '' CLUSTERED '' END  WHEN ''UQ'' THEN '' UNIQUE '' END + CASE WHEN u.ObjectID IS NOT NULL THEN '' NONCLUSTERED '' ELSE '''' END 
            + ''(''+REVERSE(SUBSTRING(REVERSE(( SELECT   c.name +  + CASE WHEN cc.is_descending_key = 1 THEN '' DESC'' ELSE '' ASC'' END + '',''    
            FROM   sys.key_constraints ccok   
            LEFT JOIN sys.index_columns cc ON ccok.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id
            LEFT JOIN sys.columns c ON cc.object_id = c.object_id AND cc.column_id = c.column_id 
            LEFT JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id  
            WHERE i.object_id = ccok.parent_object_id AND   ccok.object_id = cco.object_id    
            order by key_ordinal FOR XML PATH(''''))), 2, 8000)) + '')''
            FROM sys.key_constraints cco 
            inner join sys.schemas s on cco.schema_id=s.schema_id and s.name=@schema
            LEFT JOIN @U u ON cco.object_id = u.objectID
            LEFT JOIN @t pk ON cco.object_id = pk.ObjectID    
            WHERE    OBJECT_NAME(cco.parent_object_id) = @TableName 

            '

            print @sql
            INSERT INTO @Definition(FieldValue)
            exec sp_executesql @sql,
                               N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50),@t TestTableType readonly,@u TestTableType readonly',
                               @TableName=@TableName,@NewTableName=@NewTableName,@schema=@schema,@t=@t,@u=@u

            /*
            SELECT ',CONSTRAINT ' + name + CASE type WHEN 'PK' THEN ' PRIMARY KEY ' + CASE WHEN pk.ObjectID IS NULL THEN ' NONCLUSTERED ' ELSE ' CLUSTERED ' END  WHEN 'UQ' THEN ' UNIQUE ' END + CASE WHEN u.ObjectID IS NOT NULL THEN ' NONCLUSTERED ' ELSE '' END 
            + '(' +REVERSE(SUBSTRING(REVERSE(( SELECT   c.name +  + CASE WHEN cc.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END + ','    
            FROM   sys.key_constraints ccok   
            LEFT JOIN sys.index_columns cc ON ccok.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id
           LEFT JOIN sys.columns c ON cc.object_id = c.object_id AND cc.column_id = c.column_id 
           LEFT JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id  
           WHERE i.object_id = ccok.parent_object_id AND   ccok.object_id = cco.object_id    FOR XML PATH(''))), 2, 8000)) + ')'
           FROM sys.key_constraints cco 
           LEFT JOIN @PKObjectID pk ON cco.object_id = pk.ObjectID    
           LEFT JOIN @Uniques u ON cco.object_id = u.objectID
           WHERE    OBJECT_NAME(cco.parent_object_id) = @TableName 
           */
        END

        INSERT INTO @Definition(FieldValue) VALUES(')')

        set @sql=
        '
        use '+@DBName+'
        select '' on '' + d.name + ''([''+c.name+''])''
        from sys.tables t join sys.indexes i on(i.object_id = t.object_id and i.index_id < 2)
                          join sys.index_columns ic on(ic.partition_ordinal > 0 and ic.index_id = i.index_id and ic.object_id = t.object_id)
                          join sys.columns c on(c.object_id = ic.object_id and c.column_id = ic.column_id)
                          join sys.schemas s on t.schema_id=s.schema_id
                          join sys.data_spaces d on i.data_space_id=d.data_space_id
        where t.name=@TableName and s.name=@schema
        order by key_ordinal
        '

        print 'x'
        print @sql
        INSERT INTO @Definition(FieldValue) 
        exec sp_executesql @sql,
                           N'@TableName varchar(50),@schema varchar(50)',
                           @TableName=@TableName,@schema=@schema

        IF @IncludeIndexes = 1
        BEGIN
            set @sql=
            '
            use '+@DBName+'
            SELECT distinct '' CREATE '' + i.type_desc + '' INDEX ['' + replace(i.name COLLATE SQL_Latin1_General_CP1_CI_AS,@TableName,@NewTableName) + ''] ON '+@DBName+'.'+@NewTableSchema+'.'+@NewTableName+' ('' 
            +   REVERSE(SUBSTRING(REVERSE((   SELECT name + CASE WHEN sc.is_descending_key = 1 THEN '' DESC'' ELSE '' ASC'' END + '',''   
            FROM  sys.index_columns sc  
            JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id   
            WHERE  t.name=@TableName AND  sc.object_id = i.object_id AND  sc.index_id = i.index_id   
                                         and is_included_column=0
            ORDER BY key_ordinal ASC   FOR XML PATH('''')    )), 2, 8000)) + '')''+
            ISNULL( '' include (''+REVERSE(SUBSTRING(REVERSE((   SELECT name + '',''   
            FROM  sys.index_columns sc  
            JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id   
            WHERE  t.name=@TableName AND  sc.object_id = i.object_id AND  sc.index_id = i.index_id   
                                         and is_included_column=1
            ORDER BY key_ordinal ASC   FOR XML PATH('''')    )), 2, 8000))+'')'' ,'''')+''''    
            FROM sys.indexes i join sys.tables t on i.object_id=t.object_id
                               join sys.schemas s on t.schema_id=s.schema_id   
            AND CASE WHEN @ClusteredPK = 1 AND is_primary_key = 1 AND i.type = 1 THEN 0 ELSE 1 END = 1   AND is_unique_constraint = 0   AND is_primary_key = 0 
                where t.name=@TableName and s.name=@schema
            '

            print @sql
            INSERT INTO @Definition(FieldValue)    
            exec sp_executesql @sql,
                               N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50), @ClusteredPK bit',
                               @TableName=@TableName,@NewTableName=@NewTableName,@schema=@schema,@ClusteredPK=@ClusteredPK

        END 

            /*

                SELECT   'CREATE ' + type_desc + ' INDEX [' + [name] COLLATE SQL_Latin1_General_CP1_CI_AS + '] ON [' +  OBJECT_NAME(object_id) + '] (' +   REVERSE(SUBSTRING(REVERSE((   SELECT name + CASE WHEN sc.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END + ','   
                FROM  sys.index_columns sc  
                JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id   
                WHERE  OBJECT_NAME(sc.object_id) = @TableName AND  sc.object_id = i.object_id AND  sc.index_id = i.index_id   
                ORDER BY index_column_id ASC   FOR XML PATH('')    )), 2, 8000)) + ')'    
                FROM sys.indexes i    
                WHERE   OBJECT_NAME(object_id) = @TableName
                AND CASE WHEN @ClusteredPK = 1 AND is_primary_key = 1 AND type = 1 THEN 0 ELSE 1 END = 1   AND is_unique_constraint = 0   AND is_primary_key = 0 

            */

            INSERT INTO @MainDefinition(FieldValue)   
            SELECT FieldValue FROM @Definition    
            ORDER BY DefinitionID ASC 

            ----------------------------------

            declare @q  varchar(max)

            set @q=(select replace((SELECT FieldValue FROM @MainDefinition FOR XML PATH('')),'</FieldValue>',''))

            set @script=(select REPLACE(@q,'<FieldValue>',''))
            --drop type TestTableType
END try
-- ##############################################################################################################################################################################
BEGIN CATCH        
    BEGIN
        -- INIZIO  Procedura in errore =========================================================================================================================================================
            PRINT '***********************************************************************************************************************************************************' 
            PRINT 'ErrorNumber               : ' + CAST(ERROR_NUMBER() AS NVARCHAR(MAX))
            PRINT 'ErrorSeverity             : ' + CAST(ERROR_SEVERITY() AS NVARCHAR(MAX)) 
            PRINT 'ErrorState                : ' + CAST(ERROR_STATE() AS NVARCHAR(MAX)) 
            PRINT 'ErrorLine                 : ' + CAST(ERROR_LINE() AS NVARCHAR(MAX)) 
            PRINT 'ErrorMessage              : ' + CAST(ERROR_MESSAGE() AS NVARCHAR(MAX))
            PRINT '***********************************************************************************************************************************************************' 
        -- FINE  Procedura in errore =========================================================================================================================================================
    END 
        set @script=''
    return -1
END CATCH   
-- ##############################################################################################################################################################################   

그것을 실행하려면 :

declare @s varchar(max)
exec [util_ScriptTable]   'db','schema_source','table_source',1,1,'schema_dest','tab_dest',0,@s output
select @s

작동하지 않습니다!
itzik Paz

스크립트를 수정했습니다 : 고정 TEXT 열 지원 및 테이블 생성 및 데이터 복사 기능이 추가되었습니다. 데이터는 복사했지만 스키마는 아닌 'SELECT * INTO NewTable FROM OldTable'대신 사용할 수 있습니다. gist.github.com/MNF/eb905c7ec215670a3abc62f9c2cf9d7b
MiFreidgeim SO-stop be evil

4

이것은 착암기를 사용하여 벽에 못을 넣을 수도 있지만 질문의 폭이 넓기 때문에 언급 할 수있는 유효한 옵션이라고 생각합니다.

SQL Server 2012 SP4 +, 2014 SP2 + 또는 2016 SP1 + DBCC CLONEDATABASE를 사용하는 경우 데이터베이스 전용 데이터의 스키마 전용 복사본을 만드는 데 활용할 수 있습니다. 이는 여러 테이블의 포괄적 인 스키마 복사본을 생성하는 데 이상적이며 일련의 테이블을 반복하는 프로세스를 "자동화"할 필요성을 완화 할 수 있지만 모든 테이블 복사본이 새로운 읽기 전용 데이터베이스 내에 생성 될 것임을 경고합니다. .

이 표는 것이다 외래 키, 기본 키, 인덱스 및 제약 조건을 포함한다. 또한 통계 및 쿼리 데이터를 저장 (사용자가 지정하지 않는 한 포함 NO_STATISTICS하고 NO_QUERYSTORE).

문법은

DBCC CLONEDATABASE (source_database_name, target_database_name)[WITH [NO_STATISTICS][,NO_QUERYSTORE]] 

이 브렌트 Ozar가 가지고있는,주의해야 할 몇 가지 다른주의 사항이 또한 큰 포스트 에,하지만 그것은 모두 정말 아래로 비등하는 방법과 당신에 관한 테이블의 복사본을 만들 이유 여부 미묘의는 거래 차단기는 .


3

SQL Server Management Studio에서 "스크립트 생성"명령을 사용하여 인덱스, 트리거, 외래 키 등 테이블을 생성 할 수있는 스크립트를 얻을 수 있습니다.

SSMS에서

  • 테이블이있는 데이터베이스를 마우스 오른쪽 단추로 클릭하십시오.
  • 작업-> 스크립트 생성을 선택하십시오.
  • "특정 데이터베이스 오브젝트 선택"을 선택하십시오.
  • "테이블"목록을 펼치고 스크립트하려는 테이블 옆에있는 확인란을 선택하십시오.
  • "다음"을 클릭하여 마법사의 다음 페이지로 이동하십시오.
  • 저장 옵션을 원하는대로 설정 한 다음 "고급"버튼을 클릭하십시오
  • 원하는대로 고급 옵션을 설정하십시오. 특히, "테이블 /보기 옵션"에서 기본적으로 인덱스, 트리거 및 전체 텍스트 인덱스는 스크립팅 되지 않습니다 . 원하는 경우 "False"에서 "True"로 전환하십시오.
  • 완료되면 "확인"을 클릭하여 고급 옵션을 저장하고 "다음"을 클릭하여 선택 사항을 검토하십시오. 스크립트를 실제로 생성하려면 "다음"을 다시 클릭하십시오.

그런 다음 대상 데이터베이스에 필요한 내용 만 포함하도록 편집 할 수 있습니다.


0

이 스레드에서 E.Mantovanelli의 버전을 기반으로 한 버전이 있습니다. 이는 고유 인덱스가 결과 스크립트에 키워드 UNIQUE를 포함하지 않는 문제를 수정합니다. 또한 비 클러스터형 인덱스없이 테이블을 만들거나 비 클러스터형 인덱스 만 스크립팅 할 수 있도록 매개 변수를 추가합니다. 이것을 사용하여 스테이지 테이블을 작성하고 비 클러스터형 인덱스를 추가 한 다음 테이블 스위치를 수행하여로드가 더 빠르게 실행되고 인덱스가 조각화되지 않도록합니다.

SET ANSI_NULLS ON;
GO

SET QUOTED_IDENTIFIER ON;
GO

--*************************************************************************************************'
--    La procedura crea lo script di una tabella
--    Tabella   : xxxxx
--    Creata da : E.Mantovanelli
--    Data creazione : 28-06-2012
--    Data modifica: 28-06-2012
--*************************************************************************************************'

/*
    --      ID----|-----Data-----|--    User        ---------   | ----  Note
                        20-11-2013      E.Mantovanelli                  distinzione schema delle tabelle
                                                                        estrazione da db selezionato
                                                                        aggiunta estrazione partizione
*/
--*************************************************************************************************'
--    Creates a copy of a table with optionally all indexes and constraints depending on parameters
--    Updated by : Brent Willis
--    Date Updated : 09-11-2019
--    Changes: Added the ability to create a table with clustered index and constraints only or to 
--             CREATE just the non-clustered indexes. This is helpful so a table can be created, 
--             loaded then non-clusted indexes added so it can them be swapped into a partitioned 
--             table with freshly created indexes to lower fragmentation. 
--
--             Also fixed an issue when a unique index was defined the index resulting table was not unique. 
--*************************************************************************************************'

ALTER PROCEDURE dbo.util_ScriptTable
    @DBName                sysname
  , @schema                sysname
  , @TableName             sysname
  , @includeTable          Bit     = 1
  , @IncludeConstraints    Bit     = 1
  , @IncludeClusteredIndex Bit     = 1
  , @IncludeIndexes        Bit     = 1
  , @NewTableSchema        sysname
  , @NewTableName          sysname = NULL
  , @UseSystemDataTypes    Bit     = 0
  , @script                Varchar(MAX) OUTPUT
AS
    BEGIN TRY
        IF NOT EXISTS (SELECT * FROM sys.types WHERE name = 'TestTableType')
            CREATE TYPE TestTableType AS TABLE (ObjectID Int); --drop type TestTableType

        DECLARE @sql NVarchar(MAX);

        DECLARE @MainDefinition Table (FieldValue Varchar(200));

        --DECLARE @DBName SYSNAME
        DECLARE @ClusteredPK Bit;
        DECLARE @TableSchema NVarchar(255);

        --SET @DBName = DB_NAME(DB_ID())
        SELECT @TableName = name FROM sys.sysobjects WHERE id = Object_Id(@TableName);

        DECLARE @ShowFields Table (FieldID            Int IDENTITY(1, 1)
                                 , DatabaseName       Varchar(100)
                                 , TableOwner         Varchar(100)
                                 , TableName          Varchar(100)
                                 , FieldName          Varchar(100)
                                 , ColumnPosition     Int
                                 , ColumnDefaultValue Varchar(100)
                                 , ColumnDefaultName  Varchar(100)
                                 , IsNullable         Bit
                                 , DataType           Varchar(100)
                                 , MaxLength          Varchar(10)
                                 , NumericPrecision   Int
                                 , NumericScale       Int
                                 , DomainName         Varchar(100)
                                 , FieldListingName   Varchar(110)
                                 , FieldDefinition    Char(1)
                                 , IdentityColumn     Bit
                                 , IdentitySeed       Int
                                 , IdentityIncrement  Int
                                 , IsCharColumn       Bit
                                 , IsComputed         Varchar(255));

        DECLARE @HoldingArea Table (FldID SmallInt IDENTITY(1, 1), Flds Varchar(4000), FldValue Char(1) DEFAULT (0));

        DECLARE @PKObjectID Table (ObjectID Int);

        DECLARE @Uniques Table (ObjectID Int);

        DECLARE @Definition Table (DefinitionID SmallInt IDENTITY(1, 1), FieldValue Varchar(2000));

        SET @sql = N'
  use ' + @DBName + N'
  SELECT distinct DB_NAME()
            ,TABLE_SCHEMA
            ,TABLE_NAME
            ,''[''+COLUMN_NAME+'']'' as COLUMN_NAME
            ,CAST(ORDINAL_POSITION AS INT)
            ,COLUMN_DEFAULT
            ,dobj.name AS ColumnDefaultName
            ,CASE WHEN c.IS_NULLABLE = ''YES'' THEN 1 ELSE 0 END
            ,DATA_TYPE
            ,case CHARACTER_MAXIMUM_LENGTH when -1 then ''max'' else CAST(CHARACTER_MAXIMUM_LENGTH AS varchar) end--CAST(CHARACTER_MAXIMUM_LENGTH AS INT)
            ,CAST(NUMERIC_PRECISION AS INT)
            ,CAST(NUMERIC_SCALE AS INT)
            ,DOMAIN_NAME
            ,COLUMN_NAME + '',''
            ,'''' AS FieldDefinition
            ,CASE WHEN ic.object_id IS NULL THEN 0 ELSE 1 END AS IdentityColumn
            ,CAST(ISNULL(ic.seed_value,0) AS INT) AS IdentitySeed
            ,CAST(ISNULL(ic.increment_value,0) AS INT) AS IdentityIncrement
            ,CASE WHEN st.collation_name IS NOT NULL THEN 1 ELSE 0 END AS IsCharColumn 
            ,cc.definition 
            FROM INFORMATION_SCHEMA.COLUMNS c
            JOIN sys.columns sc ON  c.TABLE_NAME = OBJECT_NAME(sc.object_id) AND c.COLUMN_NAME = sc.Name
            LEFT JOIN sys.identity_columns ic ON c.TABLE_NAME = OBJECT_NAME(ic.object_id) AND c.COLUMN_NAME = ic.Name
            JOIN sys.types st ON COALESCE(c.DOMAIN_NAME,c.DATA_TYPE) = st.name
            LEFT OUTER JOIN sys.objects dobj ON dobj.object_id = sc.default_object_id AND dobj.type = ''D''
            left join sys.computed_columns cc on c.TABLE_NAME=OBJECT_NAME(cc.object_id) and sc.column_id=cc.column_id
    WHERE c.TABLE_NAME = @TableName and c.TABLE_SCHEMA=@schema 
    ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION
    '   ;

        --PRINT @sql;
        INSERT INTO @ShowFields (DatabaseName
                               , TableOwner
                               , TableName
                               , FieldName
                               , ColumnPosition
                               , ColumnDefaultValue
                               , ColumnDefaultName
                               , IsNullable
                               , DataType
                               , MaxLength
                               , NumericPrecision
                               , NumericScale
                               , DomainName
                               , FieldListingName
                               , FieldDefinition
                               , IdentityColumn
                               , IdentitySeed
                               , IdentityIncrement
                               , IsCharColumn
                               , IsComputed)
        EXEC sys.sp_executesql @sql
                             , N'@TableName varchar(50),@schema varchar(50)'
                             , @TableName = @TableName
                             , @schema = @schema;

        SELECT TOP 1 @TableSchema = TableOwner FROM @ShowFields;

        INSERT INTO @HoldingArea (Flds) VALUES ('(');

        IF @includeTable = 1
            BEGIN
                INSERT INTO @Definition (FieldValue)
                VALUES
                (   'CREATE TABLE ' + CASE
                                          WHEN @NewTableName IS NOT NULL THEN
                                              @DBName + '.' + @NewTableSchema + '.' + @NewTableName
                                          ELSE
                                              @DBName + '.' + @TableSchema + '.' + @TableName
                                      END);

                INSERT INTO @Definition (FieldValue) VALUES ('(');

                INSERT INTO @Definition (FieldValue)
                SELECT Char(10) + FieldName + ' '
                       + CASE
                             WHEN DomainName IS NOT NULL AND @UseSystemDataTypes = 0 THEN
                                 DomainName + CASE WHEN IsNullable = 1 THEN ' NULL ' ELSE ' NOT NULL ' END
                             ELSE
                                 CASE
                                     WHEN IsComputed IS NULL THEN
                                         Upper(DataType)
                                         + CASE
                                               WHEN IsCharColumn = 1 THEN
                                                   '(' + Cast(MaxLength AS Varchar(10)) + ')'
                                               ELSE
                                                   CASE
                                                       WHEN DataType = 'numeric' THEN
                                                           '(' + Cast(NumericPrecision AS Varchar(10)) + ','
                                                           + Cast(NumericScale AS Varchar(10)) + ')'
                                                       ELSE
                                                           CASE
                                                               WHEN DataType = 'decimal' THEN
                                                                   '(' + Cast(NumericPrecision AS Varchar(10)) + ','
                                                                   + Cast(NumericScale AS Varchar(10)) + ')'
                                                               ELSE
                                                                   ''
                                                           END
                                                   END
                                           END
                                         + CASE
                                               WHEN IdentityColumn = 1 THEN
                                                   ' IDENTITY(' + Cast(IdentitySeed AS Varchar(5)) + ','
                                                   + Cast(IdentityIncrement AS Varchar(5)) + ')'
                                               ELSE
                                                   ''
                                           END + CASE WHEN IsNullable = 1 THEN ' NULL ' ELSE ' NOT NULL ' END
                                         + CASE
                                               WHEN ColumnDefaultName IS NOT NULL AND @IncludeConstraints = 1 THEN
                                                   'CONSTRAINT ['
                                                   + Replace(ColumnDefaultName, @TableName, @NewTableName)
                                                   + '] DEFAULT' + Upper(ColumnDefaultValue)
                                               ELSE
                                                   ''
                                           END
                                     ELSE
                                         ' as ' + IsComputed + ' '
                                 END
                         END + CASE
                                   WHEN FieldID = (SELECT Max(FieldID)FROM @ShowFields) THEN
                                       ''
                                   ELSE
                                       ','
                               END
                FROM @ShowFields;

                --------------------------------------------------
                IF @IncludeConstraints = 1
                    BEGIN
                        SET @sql = N'
        use ' +         @DBName + N'
        SELECT  distinct  '',CONSTRAINT ['' + replace(name,@TableName,@NewTableName) + ''] FOREIGN KEY ('' + ParentColumns + '') REFERENCES ['' + ReferencedObject + '']('' + ReferencedColumns + '')'' 
           FROM ( SELECT   ReferencedObject = OBJECT_NAME(fk.referenced_object_id), ParentObject = OBJECT_NAME(parent_object_id),fk.name
                ,   REVERSE(SUBSTRING(REVERSE((   SELECT cp.name + '',''   
                FROM   sys.foreign_key_columns fkc   
                JOIN sys.columns cp ON fkc.parent_object_id = cp.object_id AND fkc.parent_column_id = cp.column_id   
                WHERE fkc.constraint_object_id = fk.object_id   FOR XML PATH('''')   )), 2, 8000)) ParentColumns,   
                REVERSE(SUBSTRING(REVERSE((   SELECT cr.name + '',''   
                FROM   sys.foreign_key_columns fkc  
                JOIN sys.columns cr ON fkc.referenced_object_id = cr.object_id AND fkc.referenced_column_id = cr.column_id
                WHERE fkc.constraint_object_id = fk.object_id   FOR XML PATH('''')   )), 2, 8000)) ReferencedColumns   
                FROM sys.foreign_keys fk    
                    inner join sys.schemas s on fk.schema_id=s.schema_id and s.name=@schema) a    
            WHERE ParentObject = @TableName    
        '               ;

                        --PRINT @sql;
                        INSERT INTO @Definition (FieldValue)
                        EXEC sys.sp_executesql @sql
                                             , N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50)'
                                             , @TableName = @TableName
                                             , @NewTableName = @NewTableName
                                             , @schema = @schema;

                        SET @sql = N'
            use ' +     @DBName + N'
            SELECT distinct '',CONSTRAINT ['' + replace(c.name,@TableName,@NewTableName) + ''] CHECK '' + definition 
            FROM sys.check_constraints c join sys.schemas s on c.schema_id=s.schema_id and s.name=@schema    
            WHERE OBJECT_NAME(parent_object_id) = @TableName
            '           ;

                        --PRINT @sql;
                        INSERT INTO @Definition (FieldValue)
                        EXEC sys.sp_executesql @sql
                                             , N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50)'
                                             , @TableName = @TableName
                                             , @NewTableName = @NewTableName
                                             , @schema = @schema;

                        SET @sql = N'
            use ' +     @DBName + N'
            SELECT DISTINCT  PKObject = cco.object_id 
            FROM    sys.key_constraints cco    
            JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id    
            JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id
            join sys.schemas s on cco.schema_id=s.schema_id and s.name=@schema
            WHERE    OBJECT_NAME(parent_object_id) = @TableName    AND  i.type = 1 AND    is_primary_key = 1
            '           ;

                        --PRINT @sql;
                        INSERT INTO @PKObjectID (ObjectID)
                        EXEC sys.sp_executesql @sql
                                             , N'@TableName varchar(50),@schema varchar(50)'
                                             , @TableName = @TableName
                                             , @schema = @schema;

                        SET @sql = N'
            use ' +     @DBName + N'
            SELECT DISTINCT    PKObject = cco.object_id
            FROM    sys.key_constraints cco   
            JOIN sys.index_columns cc ON cco.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id  
            JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id
            join sys.schemas s on cco.schema_id=s.schema_id and s.name=@schema
            WHERE    OBJECT_NAME(parent_object_id) = @TableName AND  i.type = 2 AND    is_primary_key = 0 AND    is_unique_constraint = 1
            '           ;

                        --PRINT @sql;
                        INSERT INTO @Uniques (ObjectID)
                        EXEC sys.sp_executesql @sql
                                             , N'@TableName varchar(50),@schema varchar(50)'
                                             , @TableName = @TableName
                                             , @schema = @schema;

                        SET @ClusteredPK = CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE 0 END;

                        DECLARE @t TestTableType;

                        INSERT @t SELECT * FROM @PKObjectID;

                        DECLARE @u TestTableType;

                        INSERT @u SELECT * FROM @Uniques;

                        SET @sql = N'
            use ' +     @DBName + N'
            SELECT distinct '',CONSTRAINT '' + replace(cco.name,@TableName,@NewTableName) + CASE type WHEN ''PK'' THEN '' PRIMARY KEY '' + CASE WHEN pk.ObjectID IS NULL THEN '' NONCLUSTERED '' ELSE '' CLUSTERED '' END  WHEN ''UQ'' THEN '' UNIQUE '' END + CASE WHEN u.ObjectID IS NOT NULL THEN '' NONCLUSTERED '' ELSE '''' END 
            + ''(''+REVERSE(SUBSTRING(REVERSE(( SELECT   c.name +  + CASE WHEN cc.is_descending_key = 1 THEN '' DESC'' ELSE '' ASC'' END + '',''    
            FROM   sys.key_constraints ccok   
            LEFT JOIN sys.index_columns cc ON ccok.parent_object_id = cc.object_id AND cco.unique_index_id = cc.index_id
            LEFT JOIN sys.columns c ON cc.object_id = c.object_id AND cc.column_id = c.column_id 
            LEFT JOIN sys.indexes i ON cc.object_id = i.object_id AND cc.index_id = i.index_id  
            WHERE i.object_id = ccok.parent_object_id AND   ccok.object_id = cco.object_id    
            order by key_ordinal FOR XML PATH(''''))), 2, 8000)) + '')''
            FROM sys.key_constraints cco 
            inner join sys.schemas s on cco.schema_id=s.schema_id and s.name=@schema
            LEFT JOIN @U u ON cco.object_id = u.objectID
            LEFT JOIN @t pk ON cco.object_id = pk.ObjectID    
            WHERE    OBJECT_NAME(cco.parent_object_id) = @TableName 

            '           ;

                        --PRINT @sql;
                        INSERT INTO @Definition (FieldValue)
                        EXEC sys.sp_executesql @sql
                                             , N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50),@t TestTableType readonly,@u TestTableType readonly'
                                             , @TableName = @TableName
                                             , @NewTableName = @NewTableName
                                             , @schema = @schema
                                             , @t = @t
                                             , @u = @u;
                    END;

                INSERT INTO @Definition (FieldValue) VALUES (')');
            END;

        SET @sql = N'
        use ' + @DBName
                   + N'
        select '' on '' + d.name + ''([''+c.name+''])''
        from sys.tables t join sys.indexes i on(i.object_id = t.object_id and i.index_id < 2)
                          join sys.index_columns ic on(ic.partition_ordinal > 0 and ic.index_id = i.index_id and ic.object_id = t.object_id)
                          join sys.columns c on(c.object_id = ic.object_id and c.column_id = ic.column_id)
                          join sys.schemas s on t.schema_id=s.schema_id
                          join sys.data_spaces d on i.data_space_id=d.data_space_id
        where t.name=@TableName and s.name=@schema
        order by key_ordinal
        ';

        PRINT 'x';

        --PRINT @sql;
        INSERT INTO @Definition (FieldValue)
        EXEC sys.sp_executesql @sql
                             , N'@TableName varchar(50),@schema varchar(50)'
                             , @TableName = @TableName
                             , @schema = @schema;

        IF @IncludeClusteredIndex = 1
            BEGIN
                SET @sql = N'
            use ' + @DBName
                           + N'
            SELECT distinct '' CREATE '' + CASE WHEN i.is_unique = 1 THEN ''UNIQUE '' ELSE '''' end + i.type_desc + '' INDEX ['' + replace(i.name COLLATE SQL_Latin1_General_CP1_CI_AS,@TableName,@NewTableName) + ''] ON '
                           + @DBName + N'.' + @NewTableSchema + N'.' + @NewTableName
                           + N' ('' 
            +   REVERSE(SUBSTRING(REVERSE((   SELECT name + CASE WHEN sc.is_descending_key = 1 THEN '' DESC'' ELSE '' ASC'' END + '',''   
            FROM  sys.index_columns sc  
            JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id   
            WHERE  t.name=@TableName AND  sc.object_id = i.object_id AND  sc.index_id = i.index_id   
                                         and is_included_column=0
            ORDER BY key_ordinal ASC   FOR XML PATH('''')    )), 2, 8000)) + '')''+
            ISNULL( '' include (''+REVERSE(SUBSTRING(REVERSE((   SELECT name + '',''   
            FROM  sys.index_columns sc  
            JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id   
            WHERE  t.name=@TableName AND  sc.object_id = i.object_id AND  sc.index_id = i.index_id   
                                         and is_included_column=1 
            ORDER BY key_ordinal ASC   FOR XML PATH('''')    )), 2, 8000))+'')'' ,'''')+''''    
            FROM sys.indexes i join sys.tables t on i.object_id=t.object_id
                               join sys.schemas s on t.schema_id=s.schema_id   
            AND CASE WHEN @ClusteredPK = 1 AND is_primary_key = 1 AND i.type = 1 THEN 0 ELSE 1 END = 1   AND is_unique_constraint = 0   AND is_primary_key = 0 
                where t.name=@TableName and s.name=@schema and i.type_desc = ''CLUSTERED''
            '   ;

                --PRINT @sql;
                INSERT INTO @Definition (FieldValue)
                EXEC sys.sp_executesql @sql
                                     , N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50), @ClusteredPK bit'
                                     , @TableName = @TableName
                                     , @NewTableName = @NewTableName
                                     , @schema = @schema
                                     , @ClusteredPK = @ClusteredPK;
            END;

        IF @IncludeIndexes = 1
            BEGIN
                SET @sql = N'
            use ' + @DBName
                           + N'
            SELECT distinct '' CREATE '' + CASE WHEN i.is_unique = 1 THEN ''UNIQUE '' ELSE '''' end + i.type_desc + '' INDEX ['' + replace(i.name COLLATE SQL_Latin1_General_CP1_CI_AS,@TableName,@NewTableName) + ''] ON '
                           + @DBName + N'.' + @NewTableSchema + N'.' + @NewTableName
                           + N' ('' 
            +   REVERSE(SUBSTRING(REVERSE((   SELECT name + CASE WHEN sc.is_descending_key = 1 THEN '' DESC'' ELSE '' ASC'' END + '',''   
            FROM  sys.index_columns sc  
            JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id   
            WHERE  t.name=@TableName AND  sc.object_id = i.object_id AND  sc.index_id = i.index_id   
                                         and is_included_column=0
            ORDER BY key_ordinal ASC   FOR XML PATH('''')    )), 2, 8000)) + '')''+
            ISNULL( '' include (''+REVERSE(SUBSTRING(REVERSE((   SELECT name + '',''   
            FROM  sys.index_columns sc  
            JOIN sys.columns c ON sc.object_id = c.object_id AND sc.column_id = c.column_id   
            WHERE  t.name=@TableName AND  sc.object_id = i.object_id AND  sc.index_id = i.index_id   
                                         and is_included_column=1 
            ORDER BY key_ordinal ASC   FOR XML PATH('''')    )), 2, 8000))+'')'' ,'''')+''''    
            FROM sys.indexes i join sys.tables t on i.object_id=t.object_id
                               join sys.schemas s on t.schema_id=s.schema_id   
            AND CASE WHEN @ClusteredPK = 1 AND is_primary_key = 1 AND i.type = 1 THEN 0 ELSE 1 END = 1   AND is_unique_constraint = 0   AND is_primary_key = 0 
                where t.name=@TableName and s.name=@schema and i.type_desc <> ''CLUSTERED''
            '   ;

                PRINT @sql;

                INSERT INTO @Definition (FieldValue)
                EXEC sys.sp_executesql @sql
                                     , N'@TableName varchar(50),@NewTableName varchar(50),@schema varchar(50), @ClusteredPK bit'
                                     , @TableName = @TableName
                                     , @NewTableName = @NewTableName
                                     , @schema = @schema
                                     , @ClusteredPK = @ClusteredPK;
            END;

        --SELECT * FROM @Definition;
        INSERT INTO @MainDefinition (FieldValue)
        SELECT FieldValue FROM @Definition ORDER BY DefinitionID ASC;

        --SELECT * FROM @MainDefinition;

        ----------------------------------
        DECLARE @q Varchar(MAX);

        SET @q = (SELECT Replace((SELECT FieldValue FROM @MainDefinition FOR XML PATH('')), '</FieldValue>', ''));
        SET @script = (SELECT Replace(@q, '<FieldValue>', ''));
    END TRY
    -- ##############################################################################################################################################################################
    BEGIN CATCH
        BEGIN
            -- INIZIO  Procedura in errore =========================================================================================================================================================
            PRINT '***********************************************************************************************************************************************************';
            PRINT 'ErrorNumber               : ' + Cast(Error_Number() AS NVarchar(MAX));
            PRINT 'ErrorSeverity             : ' + Cast(Error_Severity() AS NVarchar(MAX));
            PRINT 'ErrorState                : ' + Cast(Error_State() AS NVarchar(MAX));
            PRINT 'ErrorLine                 : ' + Cast(Error_Line() AS NVarchar(MAX));
            PRINT 'ErrorMessage              : ' + Cast(Error_Message() AS NVarchar(MAX));
            PRINT '***********************************************************************************************************************************************************';
        -- FINE  Procedura in errore =========================================================================================================================================================
        END;

        SET @script = '';

        RETURN -1;
    END CATCH;
-- ##############################################################################################################################################################################   

-1

이 스크립트를 사용하여 외래 키는 있지만 인덱스는없는 테이블 구조를 복사 할 수 있습니다. 이 스크립트는 사용자 정의 유형 및 계산 열을 정상적으로 처리합니다.

--\
---) Author: Hans Michiels
---) Script to copy a sql server table structure with foreign keys but without indexes.
---) This script handles user defined types and computed columns gracefully.
--/
/*
(c) Copyright 2016 - hansmichiels.com

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

--\
---) VARIABLES DECLARATIONS
--/
DECLARE @CrLf NVARCHAR(2) 
DECLARE @Indent NVARCHAR(2) 
DECLARE @nsql NVARCHAR(MAX)
DECLARE @SimulationMode CHAR(1) 
DECLARE @SourceSchemaAndTable NVARCHAR(260) 
DECLARE @TargetSchemaAndTable NVARCHAR(260) 
DECLARE @FkNameSuffix NVARCHAR(128)
DECLARE @TableOptions NVARCHAR(500)

--\
---) CONFIGURATION: set the source and target schema/tablename here, and some other settings.
--/
SELECT 
    @SimulationMode = 'Y' -- Use Y if you only want the SQL statement in the output window without it being executed.
  , @SourceSchemaAndTable = '[Production].[Product]'
  , @TargetSchemaAndTable = '[stg].[Product]'
  , @TableOptions = ' WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]'
  , @FkNameSuffix = '_' + REPLACE(CAST(NEWID() AS VARCHAR(40)), '-', '') -- A Guid is added to the foreign key name to make it unique.
  , @CrLf = CHAR(13) + CHAR(10)
  , @Indent = SPACE(2)
  -- For 'min' script use this (in case sql is near 4000 characters):
  -- , @CrLf  = ' '
  -- , @Indent = ''

--\
---) BUILD SQL FOR CLONING TABLE
--/
SELECT @nsql
    = ISNULL(@nsql, '')
    + CASE col_sequence WHEN 1 THEN
      @CrLf + 'IF OBJECT_ID(N''' + @TargetSchemaAndTable + ''', ''U'') IS NOT NULL DROP TABLE ' + @TargetSchemaAndTable + ';'
    + @CrLf + 'CREATE TABLE ' + @TargetSchemaAndTable + @CrLf + @Indent + '( ' ELSE @CrLf + @Indent + ', ' END
    + [definition]
FROM (
      SELECT ROW_NUMBER() OVER (PARTITION BY tb.object_id ORDER BY tb.object_id, col.column_id) AS col_sequence
        , QUOTENAME(col.name) + ' '
        + COALESCE(
            'AS ' + cmp.definition + CASE ISNULL(cmp.is_persisted, 0) WHEN 1 THEN ' PERSISTED ' ELSE '' END,
            CASE
              WHEN col.system_type_id != col.user_type_id THEN QUOTENAME(usr_tp.schema_name) + '.' + QUOTENAME(usr_tp.name)
              ELSE
                QUOTENAME(sys_tp.name) +
                CASE
                  WHEN sys_tp.name IN ('char', 'varchar', 'binary', 'varbinary') THEN '(' + CONVERT(VARCHAR, CASE col.max_length WHEN -1 THEN 'max' ELSE CAST(col.max_length AS varchar(10)) END) + ')'
                  WHEN sys_tp.name IN ('nchar', 'nvarchar') THEN '(' + CONVERT(VARCHAR, CASE col.max_length WHEN -1 THEN 'max' ELSE CAST(col.max_length/2 AS varchar(10)) END) + ')'
                  WHEN sys_tp.name IN ('decimal', 'numeric') THEN '(' + CAST(col.precision AS VARCHAR) + ',' + CAST(col.scale AS VARCHAR) +  ')'
                  WHEN sys_tp.name IN ('datetime2') THEN '(' + CAST(col.scale AS VARCHAR) +  ')'
                  ELSE ''
                END          
            END
            )       
        + CASE col.is_nullable
            WHEN 0 THEN ' NOT'
            ELSE ''
          END + ' NULL' AS [definition]
        FROM sys.tables tb
        JOIN sys.schemas sch
          ON sch.schema_id = tb.schema_id
        JOIN sys.columns col
          ON col.object_id = tb.object_id
        JOIN sys.types sys_tp
          ON col.system_type_id = sys_tp.system_type_id
        AND col.system_type_id = sys_tp.user_type_id
        LEFT JOIN
            (
            SELECT tp.*, sch.name AS [schema_name]
            FROM sys.types tp
            JOIN sys.schemas sch
            ON tp.schema_id = sch.schema_id
            ) usr_tp
          ON col.system_type_id = usr_tp.system_type_id
        AND col.user_type_id = usr_tp.user_type_id
        LEFT JOIN sys.computed_columns cmp
          ON cmp.object_id = tb.object_id
        AND cmp.column_id = col.column_id
      WHERE tb.object_id = OBJECT_ID(@SourceSchemaAndTable, 'U')
      ) subqry
;
SELECT @nsql
    = ISNULL(@nsql, '')
    + CASE col_sequence
        WHEN 1 THEN @CrLf + ', PRIMARY KEY ' + CASE is_clustered_index WHEN 1 THEN 'CLUSTERED' ELSE 'NONCLUSTERED' END
            + @CrLf + @Indent + '( '
        ELSE @CrLf + @Indent + ', '
      END
    + QUOTENAME(pk_cols.column_name)
    + CASE is_descending_key
        WHEN 1 THEN ' DESC'
        ELSE ' ASC'
      END
FROM (
      SELECT TOP 2147483647 sch.name as schema_name, tb.name as table_name, col.name as column_name
                , ROW_NUMBER() OVER (PARTITION BY tb.object_id ORDER BY tb.object_id, col.column_id) AS col_sequence
                , ic.is_descending_key
                , CASE WHEN idx.index_id = 1 THEN 1 ELSE 0 END AS [is_clustered_index]
        FROM sys.tables tb
        JOIN sys.schemas sch
          ON sch.schema_id = tb.schema_id
        JOIN sys.indexes idx
          ON idx.is_primary_key = 1
        AND idx.object_id = tb.object_id
        JOIN sys.index_columns ic
          ON is_included_column = 0  
        AND ic.object_id = tb.object_id
        AND ic.index_id = idx.index_id
        JOIN sys.columns col
          ON col.column_id = ic.column_id
        AND col.object_id = tb.object_id
      WHERE tb.object_id = OBJECT_ID(@SourceSchemaAndTable, 'U')
      ORDER BY col.column_id
      ) pk_cols

SELECT @nsql = @nsql + @CrLf + @indent + ') ' + @TableOptions

IF @SimulationMode = 'Y' 
BEGIN
  PRINT '-- Simulation mode: script is not executed.'
END
PRINT @nsql;
IF @SimulationMode != 'Y' 
BEGIN
  EXEC(@nsql);
END

--\
---) Copy foreign key constraints
---) A guid is added to the foreign key name to make it unique within the database.
--/
SET @nsql = N'';
SELECT @nsql += N'
ALTER TABLE '
      + @TargetSchemaAndTable
      + ' ADD CONSTRAINT [' + LEFT(fk.name + @FkNameSuffix, 128) +  '] '
      + ' FOREIGN KEY (' + STUFF((SELECT ',' + QUOTENAME(col.name)
      -- get all the columns in the constraint table
      FROM sys.columns AS col
      JOIN sys.foreign_key_columns AS fkc
        ON fkc.parent_column_id = col.column_id
        AND fkc.parent_object_id = col.[object_id]
      WHERE fkc.constraint_object_id = fk.[object_id]
      ORDER BY fkc.constraint_column_id
      FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'')
      + ') REFERENCES ' + QUOTENAME(rs.name) + '.' + QUOTENAME(rtb.name)
      + '('
      + STUFF((SELECT ',' + QUOTENAME(col.name)
      -- get all the referenced columns
      FROM sys.columns AS col
      JOIN sys.foreign_key_columns AS fkc
        ON fkc.referenced_column_id = col.column_id
        AND fkc.referenced_object_id = col.[object_id]
      WHERE fkc.constraint_object_id = fk.object_id
      ORDER BY fkc.constraint_column_id
      FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'') + ');'
FROM sys.foreign_keys AS fk
JOIN sys.tables AS rtb -- referenced table
    ON fk.referenced_object_id = rtb.[object_id]
JOIN sys.schemas AS rs
    ON rtb.[schema_id] = rs.[schema_id]
JOIN sys.tables AS ctb -- constraint table
    ON fk.parent_object_id = ctb.[object_id]
WHERE rtb.is_ms_shipped = 0 AND ctb.is_ms_shipped = 0
  AND ctb.object_id = OBJECT_ID(@SourceSchemaAndTable, 'U');

IF @SimulationMode = 'Y' 
BEGIN
  PRINT '-- Simulation mode: script is not executed.'
END
PRINT @nsql;
IF @SimulationMode != 'Y' 
BEGIN
  EXEC(@nsql);
END

관심이 있다면 내 블로그에서도 찾을 수 있습니다 : http://www.hansmichiels.com/2016/02/18/how-to-copy-a-database-table-structure-t-sql-scripting-series -s01e01 /


-2
Select *
into [new table name]
from [table to be copied name]
where 0=1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.