Criar tabela (estrutura) a partir da tabela existente

100

Como criar uma nova tabela, cuja estrutura deve ser a mesma de outra tabela

eu tentei

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

mas não está funcionando um erro ocorreu

Domnic
fonte
muito útil, intrigante ter uma cláusula where que é sempre falsa!
JosephDoggie

Respostas:

167

Experimentar:

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

Observe que isso não copiará índices, chaves, etc.

Se você deseja copiar toda a estrutura, você precisa gerar um Script de Criação da tabela. Você pode usar esse script para criar uma nova tabela com a mesma estrutura. Você também pode despejar os dados na nova tabela, se necessário.

Se você estiver usando o Enterprise Manager, apenas clique com o botão direito na tabela e selecione copiar para gerar um Criar Script.

Kevin Crowell
fonte
1
Kevin, apenas uma pequena mudança de formatação em sua resposta: - Selecione * Into <DestinationTableName> de <SourceTableName> Onde 1 = 2
Ashish Gupta
6
Qutbuddin, 1 = 2 impedirá a cópia de dados da tabela de origem para a tabela de destino. Experimente: - CRIAR TABELA Tabela1 (Id int, Nome varchar (200)) INSERT INTO tabela1 VALORES (1, 'A') INSERT INTO tabela1 VALORES (2, 'B') - Criará tabela2 com dados na tabela1 SELECT * INTO Table2 FROM Table1 WHERE 1 = 2 - Irá criar table2 sem dados na table1 SELECT * INTO Table2 FROM Table1 WHERE 1 = 2
Ashish Gupta
Achei que 1 = 2 seria apenas um argumento estranho e errado para evitar a cópia de dados.
Arthur Zennig
44

É o que eu uso para clonar a estrutura de uma tabela (apenas colunas) ...

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone
DanielM
fonte
1
Esta solução é mais clara do que ter a condição extra "1 = 2", eu recomendaria isso
Pinte Dani
30

Copiar apenas a estrutura (copiar todas as colunas)

Select Top 0 * into NewTable from OldTable

Copiar apenas a estrutura (copiar algumas colunas)

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

Copiar estrutura com dados

Select * into NewTable from OldTable

Se você já tem uma tabela com a mesma estrutura e deseja apenas copiar os dados, use este

Insert into NewTable Select * from OldTable
Abhishek Maurya
fonte
Trabalhou para mim no MSSQL 2008 R2
Pyrite
Ótima solução, simples e elegante. Existe um hack para fazer essa cópia de índices e chaves primárias também?
Tumaini Mosha de
16
Create table abc select * from def limit 0;

Isso definitivamente vai funcionar

GIRDHAR SINGH
fonte
Perfeito! Obrigado
Dylan B
14

PARA MYSQL:

Você pode usar:

CREATE TABLE foo LIKE bar;

Documentação aqui .

Francesco Gusmeroli
fonte
20
A questão está marcada como sql-serverpara a qual esta sintaxe não é válida, fyi.
Molomby
Não deve contar como resposta devido à relação com o MySQL não para sql-server
celerno 21/10/16
2
FYI - isso também mantém chaves primárias e índices, retidos.
garg10may
8

Provavelmente, também vale a pena mencionar que você pode fazer o seguinte:

Clique com o botão direito na tabela que deseja duplicar > Tabela de script como > Criar em > Nova janela do editor de consultas

Então, onde está diz o nome da mesa que você acabou de clicar com o botão direito no script que foi gerado, mude o nome para o nome que você deseja que sua nova mesa seja chamada e clique Execute

JsonStatham
fonte
5

tente isso .. o seguinte copia toda a estrutura da tabela existente, mas não os dados.

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

se você deseja copiar os dados, use o abaixo:

create table AT_QUOTE_CART as select * from QUOTE_CART ;
Abhi Urs
fonte
5

Eu uso o seguinte procedimento armazenado para copiar o esquema de uma tabela, incluindo PK, índices, status de partição. Não é muito rápido, mas parece funcionar. Eu recebo qualquer ideia de como acelerá-lo:

    /*
        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
Steve Faiwiszewski
fonte
1
Tornar isso mais rápido pode ser tão simples quanto declarar seus cursores como CURSOR LOCAL FAST_FORWARD. Pessoalmente, estou tentando criar um script semelhante sem usar cursores e ver como funciona.
mendosi
Olá @mendosi, sei que é antigo, mas atualmente estou procurando gerar o script CREATE com todas as coisas diversas (restrições / índices / partições / gatilhos / etc) junto com a definição de coluna. Gostaria de saber se você teve algum sucesso ao recriar isso com uma abordagem sem cursor. se sim, você se importaria de compartilhá-lo? Muito obrigado, obrigado
007
O script que escrevi copia uma ou mais tabelas e não usa um cursor. Também é grande demais para um comentário. Em vez disso, vou criar um link para o script de Hans Michiels: hansmichiels.com/2016/02/18/…
mendosi
3
SELECT * 
INTO NewTable
FROM OldTable
WHERE 1 = 2
Chris Latta
fonte
3

Não sei por que você quer fazer isso, mas tente:

SELECT *
INTO NewTable
FROM OldTable
WHERE 1 = 2

Deve funcionar.

Adrian Fâciu
fonte
Acho que copiaria também os dados? ele quer apenas a estrutura.
Ashish Gupta
@Ashis Gupta - Obrigado, esqueci o "onde" :)
Adrian Fâciu
3
Copy the table structure:-
select * into newtable from oldtable where 1=2;

Copy the table structure along with table data:-
select * into newtable from oldtable where 1=1;
NameNotFoundException
fonte
2
isso não copia restrições e chaves
Trikaldarshi
3
  1. Se você deseja copiar o mesmo banco de dados

    Select * INTO NewTableName from OldTableName
  2. Se outro banco de dados

    Select * INTO NewTableName from DatabaseName.OldTableName
cd pandey
fonte
2

Encontrei aqui o que procurava. Ajudou-me a lembrar o que usei há 3-4 anos.

Queria reutilizar a mesma sintaxe para poder criar uma tabela com dados resultantes da junção de uma tabela.

Apareceu com a consulta abaixo após algumas tentativas.

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;
user_v
fonte
0
SELECT * INTO newtable
from Oldtable
BalaRam
fonte
Use a marcação de código para maior legibilidade, também é mais útil para explicar um pouco sobre seu código.
Nima Derakhshanjan de
Obrigado por este trecho de código, que pode fornecer alguma ajuda imediata. Uma explicação adequada melhoraria muito seu valor educacional, mostrando por que essa é uma boa solução para o problema, e a tornaria mais útil para futuros leitores com perguntas semelhantes, mas não idênticas. Em particular, para olhos não treinados, parece que isso também copiaria o conteúdo de Oldtable. Como isso é evitado?
Toby Speight