Создать таблицу (структуру) из существующей таблицы


101

Как создать новую таблицу, структура которой должна быть такой же, как у другой таблицы

Я попытался

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

но произошла его неработающая ошибка


очень полезно, интригующе иметь предложение where, которое всегда ложно!
— JosephDoggie

Ответы:


168

Пытаться:

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

Обратите внимание, что это не будет копировать индексы, ключи и т. Д.

Если вы хотите скопировать всю структуру, вам необходимо создать сценарий создания таблицы. Вы можете использовать этот сценарий для создания новой таблицы с той же структурой. Затем вы также можете сбросить данные в новую таблицу, если вам нужно.

Если вы используете Enterprise Manager, просто щелкните таблицу правой кнопкой мыши и выберите копию, чтобы сгенерировать сценарий создания.


1
Кевин, небольшое изменение форматирования в вашем ответе: - Выберите * В <DestinationTableName> из <SourceTableName>, где 1 = 2
— Ашиш Гупта,

6
Qutbuddin, 1 = 2 предотвратит копирование данных из исходной таблицы в целевую. Попробуйте сами: - СОЗДАЙТЕ ТАБЛИЦУ Table1 (Id int, Name varchar (200)) INSERT INTO table1 VALUES (1, 'A') INSERT INTO table1 VALUES (2, 'B') - создаст table2 с данными в table1 SELECT * INTO Table2 FROM Table1 WHERE 1 = 2 - будет создавать table2 без данных в table1 SELECT * INTO Table2 FROM Table1 WHERE 1 = 2
— Ашиш Гупта

Я думал, что 1 = 2 будет просто странным неправильным аргументом, чтобы избежать копирования данных.
— Артур Зенниг

45

Это то, что я использую для клонирования структуры таблицы (только столбцы) ...

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone

1
Это решение более понятно, чем наличие дополнительного условия «1 = 2», я бы порекомендовал это
— Пинте Дани

31

Только скопировать структуру (скопировать все столбцы)

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
— Пирит

Отличное решение, простое и элегантное. Есть ли способ сделать эти индексы копирования и первичные ключи?
— Tumaini Mosha


14

ДЛЯ MYSQL:

Ты можешь использовать:

CREATE TABLE foo LIKE bar;

Документация здесь .


21
Вопрос помечен, sql-serverдля чего этот синтаксис недействителен, fyi.
— Molomby

Не следует считать ответом из-за связи с MySQL, а не с sql-сервером
— celerno

2
FYI - это также сохраняет первичные ключи и индексы.
— garg10

8

Вероятно, также стоит упомянуть, что вы можете делать следующее:

Щелкните правой кнопкой мыши таблицу, которую вы хотите продублировать > Таблица сценариев как > Создать в > Новое окно редактора запросов

Затем, где указано имя таблицы, которую вы только что щелкнули правой кнопкой мыши в сгенерированном скрипте, измените имя на то, что вы хотите, чтобы ваша новая таблица вызывалась, и нажмите Execute


5

попробуйте это .. ниже скопируйте всю структуру существующей таблицы, но не данные.

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

если вы хотите скопировать данные, используйте следующий:

create table AT_QUOTE_CART as select * from QUOTE_CART ;

5

Я использую следующую хранимую процедуру для копирования схемы таблицы, включая 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

1
Сделать это быстрее может быть так же просто, как объявить ваши курсоры как CURSOR LOCAL FAST_FORWARD. Лично я пытаюсь создать аналогичный сценарий без использования курсоров и посмотреть, как это работает.
— mendosi

Привет, @mendosi, я знаю, что он старый, но сейчас я собираюсь создать сценарий CREATE со всеми прочими вещами (ограничения / индексы / разделы / триггеры и т. Д.) Вместе с определением столбца. Мне было интересно, удалось ли вам воссоздать это без использования курсора. если да, не могли бы вы поделиться им? Очень признателен, спасибо
— 007

Написанный мной сценарий копирует одну или несколько таблиц и не использует курсор. К тому же он слишком велик для комментария. Вместо этого я сделаю ссылку на сценарий Ханса
— Михильса

4
  1. Если вы хотите скопировать ту же базу данных

    Select * INTO NewTableName from OldTableName
  2. Если другая база данных

    Select * INTO NewTableName from DatabaseName.OldTableName


3

Я не знаю, почему вы хотите это сделать, но попробуйте:

SELECT *
INTO NewTable
FROM OldTable
WHERE 1 = 2

Он должен работать.


Думаю, что бы тоже данные копировать? ему нужна только структура.
— Ашиш Гупта,

@Ashis Gupta - Спасибо, я забыл «где» :)
— Адриан Фачу,

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;

3
это не копирует ограничения и ключи
— Trikaldarshi

2

Нашел здесь то, что искал. Помогло вспомнить то, чем я пользовался 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;

0
SELECT * INTO newtable
from Oldtable

Пожалуйста, используйте разметку кода для большей читабельности, также это более полезно, чтобы немного объяснить ваш код.
— Нима Дерахшанджан

Спасибо за этот фрагмент кода, который может сразу помочь. Правильное объяснение значительно повысило бы его образовательную ценность, показав, почему это хорошее решение проблемы, и сделало бы его более полезным для будущих читателей, задающих похожие, но не идентичные вопросы. В частности, неподготовленному глазу кажется, что при этом также скопируется содержимое Oldtable. Как этого избежать?
— Тоби Спейт

-1

Если вы хотите создать таблицу с единственной структурой, которую нужно скопировать из исходной таблицы, вы можете использовать следующую команду для этого.

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

По этому ложному условию вы можете оставить записи и скопировать структуру.


Это дубликат существующих ответов. Прочтите существующие ответы перед тем, как отправлять новый, и при необходимости добавьте комментарии / голоса.
— Кевин Хогг,

Но это не то же самое, что и существующий ответ здесь, я использовал команду create для выполнения этого действия
— Сай Дурга Камеш Кота

Если вы просмотрите ответ @AbhiUrs (2 января 2015 г.), ваш ответ аналогичен первой части их ответа, хотя и с немного другим предложением where. Первая часть => create table AT_QUOTE_CART as select * from QUOTE_CART where 0=1 ; Замените эти имена таблиц, и мы получим: create table <tablename> as select * from <sourcetablename> where 0=1 ; Что касается предложения where, 0=1достигается тот же результат, при 1>2котором данные не извлекаются.
— Кевин Хогг,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.