2010-03-24 15 views
58

esistente Come creare nuova tabella che struttura dovrebbe essere uguale a un altro tavoloCrea una tabella (struttura) dalla tabella

ho provato

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

ma il suo errore non funziona verificato

+0

molto utile, interessante per avere una clausola WHERE che è sempre false! – JosephDoggie

risposta

106

Prova:

Si noti che questo non copierà indici, chiavi, ecc.

Se si desidera copiare l'intera struttura , è necessario generare uno script di creazione della tabella. Puoi usare quello script per creare una nuova tabella con la stessa struttura. È anche possibile scaricare i dati nella nuova tabella, se necessario.

Se si utilizza Enterprise Manager, fare clic con il pulsante destro del mouse sulla tabella e selezionare Copia per generare uno script di creazione.

+0

Kevin, basta una piccola modifica di formattazione nella risposta: - Seleziona * In Da Dove 1 = 2 –

+0

@Ashish Risolto, grazie. –

+7

perché aggiungere dove clausola qui 1 = 2 ??? – BreakHead

2
SELECT * 
INTO NewTable 
FROM OldTable 
WHERE 1 = 2 
3

Non so perché si vuole farlo, ma provo:

SELECT * 
INTO NewTable 
FROM OldTable 
WHERE 1 = 2 

Dovrebbe funzionare.

+0

Penso che copi anche i dati? lui vuole solo la struttura. –

+0

@Ashis Gupta - Grazie, ho dimenticato il "dove" :) –

1

Trovato qui quello che stavo cercando. Mi ha aiutato a ricordare ciò che ho usato 3-4 anni fa.

Ho voluto riutilizzare la stessa sintassi per poter creare una tabella con i dati risultanti dal join di una tabella.

Arriva con una query di seguito 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; 
16

Questo è quello che io uso per clonare una struttura di tabella (solo colonne) ...

SELECT TOP 0 * 
INTO NewTable 
FROM TableStructureIWishToClone 
9
Create table abc select * from def limit 0; 

questo lavoro preciso

8

La sua probabilmente anche la pena ricordare che si può effettuare le seguenti operazioni:

Fare clic con il pulsante destro del mouse sul tavolo che si desidera duplicare > Script Tabella Come > Crea Per > Nuova query finestra Editor

Poi, in cui si dice il nome della tabella che si giusto cliccato nello script che è stato generato, modificare il nome di ciò che più desiderate la nuova tabella di essere chiamato e cliccare Execute

2
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 i vincoli e le chiavi – Trikaldarshi

3

provare questo .. il sotto una 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 si desidera copiare i dati quindi utilizzare il sotto di un:

create table AT_QUOTE_CART as select * from QUOTE_CART ; 
5

È possibile utilizzare:

CREATE TABLE foo LIKE bar; 

Documentation here.

+13

La domanda è contrassegnata come 'sql-server' per cui questa sintassi non è valida, fyi. – Molomby

+0

Non dovrebbe contare come risposta dovuta alla relazione con MySQL non a sql-server – celerno

14

Copia struttura solo (copiare tutte le colonne)

Select Top 0 * into NewTable from OldTable 
solo

Copia struttura (copiare alcune colonne)

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

struttura di copia con i dati

Select * into NewTable from OldTable 

Se si dispone già di un tavolo con la stessa struttura e vuoi solo copiare i dati, quindi usa questo

Insert into NewTable Select * from OldTable 
+0

Ha funzionato per me in MSSQL 2008 R2 – Pyrite

+0

Ottima soluzione, semplice ed elegante. C'è un trucco per fare questo copia indici e chiavi primarie pure? –

2
  1. Se si desidera copiare stesso database

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

    Select * INTO NewTableName from DatabaseName.OldTableName 
    
3

Io uso il seguente stored procedure per copiare lo schema di un tavolo, tra cui PK, indici, stato della partizione. Non è molto veloce, ma sembra fare il lavoro. I I accogliere tutte le idee 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 [email protected] +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) [email protected]    
    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 
+0

Rendere questo più veloce potrebbe essere semplice come dichiarare i cursori come "CURSOR LOCAL FAST_FORWARD". Personalmente sto tentando di creare uno script simile senza usare i cursori e vedere come si comporta. – mendosi

-1
SELECT * INTO newtable 
from Oldtable 
+0

Utilizzare la marcatura del codice per una maggiore leggibilità, anche questo è più utile per spiegare un po 'del codice. –

+0

Grazie per questo snippet di codice, che potrebbe fornire un aiuto immediato. Una spiegazione adeguata [migliorerebbe notevolmente] (// meta.stackexchange.com/q/114762) il suo valore educativo mostrando * perché * questa è una buona soluzione al problema e renderebbe più utile ai futuri lettori con simili, ma non identiche, domande. In particolare, guarda all'occhio non allenato come se questo copierebbe anche il contenuto di Oldtable. Come viene evitato? –

Problemi correlati