Crea tabella (struttura) dalla tabella esistente


100

Come creare una nuova tabella la cui struttura dovrebbe essere uguale a un'altra tabella

Provai

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

ma si è verificato un errore non funzionante


molto utile, intrigante avere una clausola where che è sempre falsa!
JosephDoggie

Risposte:


167

Provare:

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

Nota che questo non copierà indici, chiavi, ecc.

Se vuoi copiare l' intero file struttura, devi generare un Crea Script della tabella. Puoi usare quello script per creare una nuova tabella con la stessa struttura. Puoi anche scaricare i dati nella nuova tabella, se necessario.

Se utilizzi Enterprise Manager, fai clic con il pulsante destro del mouse sulla tabella e seleziona Copia per generare uno script di creazione.


1
Kevin, solo una piccola modifica di formattazione nella tua risposta: - Seleziona * In <DestinationTableName> Da <SourceTableName> Dove 1 = 2
Ashish Gupta

6
Qutbuddin, 1 = 2 impedirà la copia dei dati dalla tabella di origine a quella di destinazione. Prova tu stesso: - CREATE TABLE Table1 (Id int, Name varchar (200)) INSERT INTO table1 VALUES (1, 'A') INSERT INTO table1 VALUES (2, 'B') - Creerà table2 con i dati in table1 SELECT * INTO Table2 FROM Table1 WHERE 1 = 2 - Creerà table2 senza dati in table1 SELECT * INTO Table2 FROM Table1 WHERE 1 = 2
Ashish Gupta

Ho pensato che 1 = 2 sarebbe stato solo uno strano argomento sbagliato per evitare di copiare i dati.
Arthur Zennig

44

Questo è ciò che uso per clonare una struttura di tabella (solo colonne) ...

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone

1
Questa soluzione è più chiara rispetto alla condizione extra "1 = 2", la consiglierei
Pinte Dani

30

Copia solo struttura (copia tutte le colonne)

Select Top 0 * into NewTable from OldTable

Copia solo struttura (copia alcune colonne)

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

Copia la struttura con i dati

Select * into NewTable from OldTable

Se hai già una tabella con la stessa struttura e vuoi solo copiare i dati, usa questo

Insert into NewTable Select * from OldTable

Ha funzionato per me in MSSQL 2008 R2
Pyrite

Ottima soluzione, semplice ed elegante. Esiste un trucco per creare anche questa copia degli indici e delle chiavi primarie?
Tumaini Mosha


14

PER MYSQL:

Puoi usare:

CREATE TABLE foo LIKE bar;

Documentazione qui .


21
La domanda è contrassegnata come sql-serverper la quale questa sintassi non è valida, per esempio.
Molomby

Non dovrebbe contare come risposta a causa della relazione con MySQL e non con sql-server
celerno

2
Cordiali saluti, questo mantiene anche le chiavi e gli indici primari, mantenuti.
garg10 maggio

8

Probabilmente vale anche la pena ricordare che puoi fare quanto segue:

Fare clic con il pulsante destro del mouse sulla tabella che si desidera duplicare > Tabella script come > Crea in > Nuova finestra dell'editor di query

Quindi, dove si trova il nome della tabella su cui hai appena fatto clic con il pulsante destro del mouse nello script che è stato generato, cambia il nome in quello che vuoi che venga chiamata la tua nuova tabella e fai clic su Execute


5

prova questo .. quello sotto copia l'intera struttura della tabella esistente ma non i dati.

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

se vuoi copiare i dati, usa quello qui sotto:

create table AT_QUOTE_CART as select * from QUOTE_CART ;

5

Uso la procedura memorizzata seguente per copiare lo schema di una tabella, inclusi PK, indici, stato della partizione. Non è molto veloce, ma sembra fare il lavoro. Accolgo con favore qualsiasi idea su come accelerarlo:

    /*
        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
Renderlo più veloce potrebbe essere semplice come dichiarare i tuoi cursori come CURSOR LOCAL FAST_FORWARD. Personalmente sto tentando di creare uno script simile senza usare i cursori e vedere come funziona.
mendosi il

Ciao @mendosi, so che è vecchio, ma attualmente sto cercando di generare script CREATE con tutte le cose varie (vincoli / indici / partizioni / trigger / ecc.) Insieme alla definizione della colonna. Mi chiedevo se hai avuto successo nel ricrearlo con un approccio senza cursore. se è così, ti dispiacerebbe condividerlo? Molto apprezzato, grazie
007

Lo script che ho scritto copia una o più tabelle e non utilizza un cursore. È anche troppo grande per un commento. Invece mi collegherò alla sceneggiatura di Hans Michiels: hansmichiels.com/2016/02/18/…
mendosi

4
  1. Se vuoi copiare Same DataBase

    Select * INTO NewTableName from OldTableName
  2. Se un altro DataBase

    Select * INTO NewTableName from DatabaseName.OldTableName


3

Non so perché vuoi farlo, ma prova:

SELECT *
INTO NewTable
FROM OldTable
WHERE 1 = 2

Dovrebbe funzionare.


Penso che copierebbe anche i dati? vuole solo la struttura.
Ashish Gupta

@Ashis Gupta - Grazie, ho dimenticato il "dove" :)
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;

2
questo non copia vincoli e chiavi
Trikaldarshi

2

Ho trovato qui quello che stavo cercando. Mi ha aiutato a ricordare quello che ho usato 3-4 anni fa.

Volevo riutilizzare la stessa sintassi per poter creare una tabella con i dati risultanti dall'unione di una tabella.

È arrivato con la query sottostante dopo alcuni tentativi.

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

Usa il markup del codice per una maggiore leggibilità, anche questo è più utile per spiegare un po 'il tuo codice.
Nima Derakhshanjan,

Grazie per questo snippet di codice, che potrebbe fornire un aiuto immediato. Una spiegazione adeguata migliorerebbe notevolmente il suo valore educativo mostrando perché questa è una buona soluzione al problema e lo renderebbe più utile ai futuri lettori con domande simili, ma non identiche. In particolare, a un occhio inesperto sembra che questo copi anche il contenuto di Oldtable. Come si evita?
Toby Speight
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.