【问题标题】:Create table (structure) from existing table从现有表创建表(结构)
【发布时间】:2011-01-31 03:13:41
【问题描述】:

如何创建与另一个表结构相同的新表

我试过了

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

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

【问题讨论】:

  • 非常有帮助,有趣的是有一个总是错误的 where 子句!
  • 这在 sqlite 中有效.. 其他无效

标签: sql-server


【解决方案1】:

试试:

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

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

如果要复制整个结构,需要生成表格的Create Script。您可以使用该脚本创建具有相同结构的新表。如果需要,您还可以将数据转储到新表中。

如果您使用的是企业管理器,只需右键单击表并选择复制即可生成创建脚本。

【讨论】:

  • Kevin,您的答案中只是一个小的格式更改:- Select * Into From Where 1 = 2
  • 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
  • 为了避免复制数据,我认为 1=2 只是一个奇怪的错误参数。
【解决方案2】:

这是我用来克隆表结构(仅列)...

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone

【讨论】:

  • 这个解决方案比额外条件“1 = 2”更清晰,我会推荐这个
【解决方案3】:

仅复制结构(复制所有列)

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 中为我工作
  • 很好的解决方案,简单而优雅。是否有技巧可以制作此副本索引和主键?
  • 是浅拷贝还是深拷贝
【解决方案4】:

对于 MYSQL:

你可以使用:

CREATE TABLE foo LIKE bar;

Documentation here.

【讨论】:

  • 问题被标记为sql-server,此语法对其无效,仅供参考。
  • 由于与 MySQL 的关系而不是 sql-server,因此不应算作答案
  • 仅供参考 - 这也保留了主键和索引。
【解决方案5】:
Create table abc select * from def limit 0;

这肯定会奏效

【讨论】:

  • 完美!谢谢
  • 请注意,该问题被标记为sql-server,这在 SQL Server 中工作。
【解决方案6】:

可能还值得一提的是,您可以执行以下操作:

右键单击要复制的表 > 将表编写为 > 创建到 > 新查询编辑器窗口

然后,在哪里说您刚刚在已生成的脚本中右键单击的表的名称,将名称更改为您希望调用新表的名称,然后单击Execute

【讨论】:

    【解决方案7】:

    我使用以下存储过程来复制表的架构,包括 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
    

    【讨论】:

    • 加快速度可能就像将光标声明为CURSOR LOCAL FAST_FORWARD 一样简单。就我个人而言,我正在尝试在不使用游标的情况下创建一个类似的脚本,看看它是如何执行的。
    • 嗨@mendosi 我知道它已经过时了,但我目前正在研究生成包含所有杂项(约束/索引/分区/触发器/等)以及列定义的 CREATE 脚本。我想知道你是否成功地用非光标方法重新创建了这个。如果是这样,你介意分享一下吗?非常感谢,谢谢
    • 我编写的脚本复制了一个或多个表并且不使用游标。它也太大了,无法评论。相反,我将链接到 Hans Michiels 脚本:hansmichiels.com/2016/02/18/…
    【解决方案8】:

    试试这个..下面的一个复制现有表的整个结构,但不复制数据。

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

    如果你想复制数据,请使用下面的:

    create table AT_QUOTE_CART as select * from QUOTE_CART ;
    

    【讨论】:

      【解决方案9】:
      1. 如果你想复制相同的数据库

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

        Select * INTO NewTableName from DatabaseName.OldTableName
        

      【讨论】:

        【解决方案10】:
        SELECT * 
        INTO NewTable
        FROM OldTable
        WHERE 1 = 2
        

        【讨论】:

          【解决方案11】:

          我不知道你为什么要这样做,但试试吧:

          SELECT *
          INTO NewTable
          FROM OldTable
          WHERE 1 = 2
          

          它应该可以工作。

          【讨论】:

          • 我认为这也会复制数据?他只想要结构。
          • @Ashis Gupta - 谢谢,我忘记了“哪里”:)
          【解决方案12】:
          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;
          

          【讨论】:

          • 这不会复制约束和键
          【解决方案13】:

          在这里找到了我想要的东西。帮助我回忆起 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;
          

          【讨论】:

            【解决方案14】:
            SELECT * INTO newtable
            from Oldtable
            

            【讨论】:

            • 请使用代码标记以提高可读性,这对于解释您的代码也更有用。
            • 感谢您提供此代码 sn-p,它可能会提供一些即时帮助。一个正确的解释would greatly improve 其教育价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有类似但不相同的问题的读者更有用。特别是,在未经训练的人看来,这似乎也会复制Oldtable 的内容。如何避免?
            【解决方案15】:

            如果你想创建一个只有从原始表中复制的结构的表,那么你可以使用以下命令来做到这一点。

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

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

            【讨论】:

            • 这是现有答案的副本。在提交新答案之前通读现有答案,并酌情添加 cmets/votes。
            • 但这与现有答案不同,我使用 create 命令执行此操作
            • 如果您查看@AbhiUrs 答案(2015 年 1 月 2 日),您的答案类似于他们答案的第一部分,尽管 where 子句略有不同。第一部分 => create table AT_QUOTE_CART as select * from QUOTE_CART where 0=1 ; 替换那些表名,我们得到:create table &lt;tablename&gt; as select * from &lt;sourcetablename&gt; where 0=1 ; 至于 where 子句,0=11&gt;2 实现相同的结果,即没有检索到数据。
            【解决方案16】:

            我需要从一个数据库复制一个表到另一个数据库。对于使用 Sequel Ace 等 GUI 的任何人,您可以右键单击表并单击“复制创建表语法”并运行该查询(您可以编辑查询,例如更改表名、删除外键、添加/删除列(如果需要))

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-02-21
              • 1970-01-01
              • 1970-01-01
              • 2021-10-03
              • 2011-04-14
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多