从现有表创建表(结构)


101

如何创建新表,其结构应与另一个表相同

我试过了

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

但发生了无法正常工作的错误


非常有帮助,有趣的是总是有一个false的where子句!
JosephDoggie

Answers:


168

尝试:

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

请注意,这不会复制索引,键等。

如果要复制整个结构,则需要生成表的“创建脚本”。您可以使用该脚本创建具有相同结构的新表。然后,您也可以根据需要将数据转储到新表中。

如果使用的是企业管理器,只需右键单击该表,然后选择“副本”以生成“创建脚本”。


1
凯文(Kevin),您的答案只有一个小的格式更改:-选择*进入<目标表名称(DestinationTableName)>从<源表名称(SourceTableName)出发,其中1 = 2
Ashish Gupta 2010年

6
Qutbuddin,1 = 2将阻止数据从源表复制到目标表。尝试一下:-创建表Table1(Id int,名称varchar(200))将表1插入值1('A')将表1插入值1(2,'B')-将用表1中的数据创建表2 SELECT *从表1的WHITE 1 = 2中进入表2-将在表1中创建无数据的表2 SELECT *从表1的WHERE 1 = 2中进入表2
Ashish Gupta 2010年

我认为1 = 2只是一个奇怪的错误参数,以避免复制数据。
亚瑟·曾尼格

45

这就是我用来克隆表结构(仅列)的方法。

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone

1
此解决方案比具有额外条件“ 1 = 2”更清晰,我建议您这样做
Pinte Dani

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中为我工作
Pyrite

伟大的解决方案,简单而优雅。是否有办法使该副本同时具有索引和主键?
Tumaini Mosha



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

我使用以下存储的proc复制表的架构,包括PK,索引,分区状态。它不是很快,但是似乎可以完成任务。II欢迎任何有关如何加快速度的想法:

    /*
        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'4-4-6

@mendosi,您好,我知道它已经很旧了,但是我目前正在考虑使用所有杂项(约束/索引/分区/触发器/等)以及列定义来生成CREATE脚本。我想知道您是否以非游标方法成功创建了此文件。如果是这样,您愿意分享吗?非常感谢,谢谢
007

我编写的脚本复制了一个或多个表,并且不使用游标。也太大了,无法发表评论。相反,我将链接到汉斯· 米歇尔斯
mendosi

4
  1. 如果要复制相同数据库

    Select * INTO NewTableName from OldTableName
  2. 如果是另一个数据库

    Select * INTO NewTableName from DatabaseName.OldTableName



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 2014年

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
Toby Speight

-1

如果要创建具有唯一结构的表,该结构要从原始表复制,则可以使用以下命令来执行此操作。

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

通过这种错误条件,您可以保留记录并复制结构。


这是现有答案的重复。在提交新答案之前,请通读现有答案,并在适当时添加评论/投票。
凯文·霍格

但这与现有答案不同,我
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未检索到数据的结果相同。
凯文·霍格
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.