Crear tabla (estructura) a partir de una tabla existente

100

Cómo crear una nueva tabla cuya estructura debería ser la misma que otra tabla

Lo intenté

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

pero se produjo un error que no funciona

Domnic
fuente
¡Es muy útil, intrigante tener una cláusula where que siempre es falsa!
JosephDoggie

Respuestas:

167

Tratar:

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

Tenga en cuenta que esto no copiará índices, claves, etc.

Si desea copiar la estructura completa , debe generar un Script de creación de la tabla. Puede usar ese script para crear una nueva tabla con la misma estructura. Luego, también puede volcar los datos en la nueva tabla si es necesario.

Si está utilizando Enterprise Manager, simplemente haga clic con el botón derecho en la tabla y seleccione copiar para generar un Script de creación.

Kevin Crowell
fuente
1
Kevin, solo un pequeño cambio de formato en su respuesta: - Seleccione * En <DestinationTableName> de <SourceTableName> donde 1 = 2
Ashish Gupta
6
Qutbuddin, 1 = 2 evitará la copia de datos de la tabla de origen a la de destino. Pruébelo: - CREAR TABLA Table1 (Id int, Nombre varchar (200)) INSERT INTO table1 VALUES (1, 'A') INSERT INTO table1 VALUES (2, 'B') - Creará table2 con datos en table1 SELECT * INTO Table2 FROM Table1 DONDE 1 = 2 - Creará table2 sin datos en table1 SELECCIONAR * INTO Table2 FROM Table1 DONDE 1 = 2
Ashish Gupta
Pensé que 1 = 2 sería simplemente un argumento incorrecto extraño para evitar copiar datos.
Arthur Zennig
44

Esto es lo que uso para clonar una estructura de tabla (solo columnas) ...

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone
DanielM
fuente
1
Esta solución es más clara que tener la condición adicional "1 = 2", lo recomendaría
Pinte Dani
30

Copiar solo la estructura (copiar todas las columnas)

Select Top 0 * into NewTable from OldTable

Copiar solo la estructura (copiar algunas columnas)

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

Copiar estructura con datos

Select * into NewTable from OldTable

Si ya tiene una tabla con la misma estructura y solo desea copiar datos, use esto

Insert into NewTable Select * from OldTable
Abhishek Maurya
fuente
Trabajó para mí en MSSQL 2008 R2
Pyrite
Gran solución, simple y elegante. ¿Hay algún truco para hacer que esta copia de índices y claves primarias también?
Tumaini Mosha
16
Create table abc select * from def limit 0;

Esto definitivamente funcionará

GIRDHAR SINGH
fuente
¡Perfecto! Gracias
Dylan B
14

PARA MYSQL:

Puedes usar:

CREATE TABLE foo LIKE bar;

Documentación aquí .

Francesco Gusmeroli
fuente
20
La pregunta está etiquetada como sql-serverpara la que esta sintaxis no es válida, para su información.
Molomby
No debería contar como respuesta debido a la relación con MySQL, no con el servidor SQL
celerno
2
Para su información, esto también mantiene las claves e índices primarios retenidos.
garg10may
8

Probablemente también valga la pena mencionar que puede hacer lo siguiente:

Haga clic con el botón derecho en la tabla que desea duplicar > Tabla de secuencia de comandos como > Crear en > Nueva ventana del editor de consultas

Luego, donde dice el nombre de la tabla en la que simplemente hizo clic derecho en el script que se ha generado, cambie el nombre a lo que quiera que se llame a su nueva tabla y haga clic Execute

JsonStatham
fuente
5

intente esto .. el siguiente copia la estructura completa de la tabla existente pero no los datos.

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

si desea copiar los datos, utilice el siguiente:

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

Utilizo el siguiente proceso almacenado para copiar el esquema de una tabla, incluidos PK, índices y estado de la partición. No es muy rápido, pero parece funcionar. Doy la bienvenida a cualquier idea sobre cómo acelerarlo:

    /*
        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
fuente
1
Hacer esto más rápido podría ser tan simple como declarar los cursores como CURSOR LOCAL FAST_FORWARD. Personalmente, estoy intentando crear un script similar sin usar cursores y ver cómo funciona.
mendosi
Hola @mendosi, sé que es antiguo, pero actualmente estoy buscando generar un script CREATE con todas las cosas misceláneas (restricciones / índices / particiones / activadores / etc.) junto con la definición de columna. Me preguntaba si tuvo éxito al recrear esto con un enfoque sin cursor. si es así, ¿te importaría compartirlo? Muy apreciado, gracias
007
El script que escribí copia una o más tablas y no usa un cursor. También es demasiado grande para un comentario. En su lugar, lo vincularé al guión de Hans Michiels: hansmichiels.com/2016/02/18/…
mendosi
3
SELECT * 
INTO NewTable
FROM OldTable
WHERE 1 = 2
Chris Latta
fuente
3

No sé por qué quieres hacer eso, pero intenta:

SELECT *
INTO NewTable
FROM OldTable
WHERE 1 = 2

Deberia de funcionar.

Adrian Fâciu
fuente
¿Creo que también copiaría los datos? solo quiere la estructura.
Ashish Gupta
@Ashis Gupta - Gracias, olvidé el "dónde" :)
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
fuente
2
esto no copia restricciones y claves
Trikaldarshi
3
  1. Si desea copiar la misma base de datos

    Select * INTO NewTableName from OldTableName
  2. Si otra base de datos

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

Encontré aquí lo que estaba buscando. Me ayudó a recordar lo que usé hace 3 o 4 años.

Quería reutilizar la misma sintaxis para poder crear una tabla con datos resultantes de la combinación de una tabla.

Surgió con la siguiente consulta después de algunos intentos.

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
fuente
0
SELECT * INTO newtable
from Oldtable
BalaRam
fuente
Utilice el marcado de código para una mayor legibilidad, que también es más útil para explicar un poco sobre su código.
Nima Derakhshanjan
Gracias por este fragmento de código, que puede proporcionar ayuda inmediata. Una explicación adecuada mejoraría enormemente su valor educativo al mostrar por qué es una buena solución al problema y lo haría más útil para futuros lectores con preguntas similares, pero no idénticas. En particular, para el ojo inexperto parece que esto también copiaría el contenido de Oldtable. ¿Cómo se evita eso?
Toby Speight