Mevcut tablodan tablo (yapı) oluştur


103

Hangi yapının başka bir tablo ile aynı olması gereken yeni tablo nasıl oluşturulur

denedim

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

ama çalışmıyor hatası oluştu


her zaman yanlış olan bir where cümlesine sahip olmak çok yardımcı, ilgi çekici!
JosephDoggie

Yanıtlar:


171

Deneyin:

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

Bunun dizinleri, anahtarları vb. Kopyalamayacağını unutmayın.

Tüm yapıyı kopyalamak istiyorsanız , tablonun bir Komut Dosyası Oluşturmanız gerekir. Aynı yapıya sahip yeni bir tablo oluşturmak için bu komut dosyasını kullanabilirsiniz. Daha sonra, gerekirse verileri yeni tabloya aktarabilirsiniz.

Enterprise Manager kullanıyorsanız, sadece tabloya sağ tıklayın ve bir Create Script oluşturmak için kopyayı seçin.


1
Kevin, cevabınızda sadece küçük bir biçim değişikliği: - <DestinationTableName> içine <SourceTableName> 'den seçin Burada 1 = 2
Ashish Gupta

6
Qutbuddin, 1 = 2, verilerin kaynaktan hedef tabloya kopyalanmasını önleyecektir. Kendinizi deneyin: - CREATE TABLE Table1 (Id int, Name varchar (200)) INSERT INTO table1 VALUES (1, 'A') INSERT INTO table1 VALUES (2, 'B') - tablo1'deki verilerle tablo2 oluşturacak SEÇ * Tablo1 1 = 2 NEREDEN Tablo2’ye Tablo1’deki veriler olmadan tablo2 oluşturacak SEÇİN * Tablo2’den Tablo1’den 1 = 2
Ashish Gupta

Verilerin kopyalanmasını önlemek için 1 = 2'nin sadece garip bir yanlış argüman olacağını düşündüm.
Arthur Zennig

45

Bir tablo yapısını klonlamak için kullandığım şey budur (yalnızca sütunlar) ...

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone

1
Bu çözüm, "1 = 2" ekstra koşuluna sahip olmaktan daha net, bunu tavsiye ederim
Pinte Dani

32

Yalnızca yapıyı kopyala (tüm sütunları kopyala)

Select Top 0 * into NewTable from OldTable

Yalnızca yapıyı kopyala (bazı sütunları kopyala)

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

Yapıyı verilerle kopyala

Select * into NewTable from OldTable

Zaten aynı yapıya sahip bir tablonuz varsa ve yalnızca verileri kopyalamak istiyorsanız, bunu kullanın

Insert into NewTable Select * from OldTable

Benim için MSSQL 2008 R2'de çalıştı
Pirit

1
Harika çözüm, basit ve zarif. Bu kopya dizinlerini ve birincil anahtarları da yapmak için bir hack var mı?
Tumaini Mosha

16
Create table abc select * from def limit 0;

Bu işi kesinleştirecek


Mükemmel! Teşekkürler
Dylan B

Sorusu ile etiketlenmiş olduğu Bildirimi sql-serverve bu yok değil SQL Server çalışır.
Alexandre


8

Muhtemelen aşağıdakileri de yapabileceğinizden bahsetmeye değer:

Çoğaltmak istediğiniz tabloya sağ tıklayın > Farklı Komut Dosyası Tablosu > Oluştur > Yeni Sorgu Düzenleyici Penceresi

Ardından, oluşturulan komut dosyasında sağ tıkladığınız tablonun adı nerede yazıyorsa, adı yeni tablonuzun çağrılmasını istediğiniz şekilde değiştirin ve tıklayın Execute


5

bunu deneyin .. aşağıdaki tablo mevcut tablonun tüm yapısını kopyalar, ancak verileri kopyalamayın.

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

Verileri kopyalamak istiyorsanız, aşağıdakini kullanın:

create table AT_QUOTE_CART as select * from QUOTE_CART ;

5

PK, dizinler, bölüm durumu dahil olmak üzere bir tablonun şemasını kopyalamak için aşağıdaki depolanmış proc'u kullanıyorum. Çok hızlı değil ama işi yapıyor gibi görünüyor. Nasıl hızlandırılacağına dair her türlü fikre açığım:

    /*
        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
Bunu hızlandırmak, imleçlerinizi bildirmek kadar basit olabilir CURSOR LOCAL FAST_FORWARD. Şahsen, imleç kullanmadan benzer bir komut dosyası oluşturmaya ve bunun nasıl bir performans gösterdiğini görmeye çalışıyorum.
mendosi

Merhaba @mendosi Eski olduğunu biliyorum, ancak şu anda sütun tanımıyla birlikte tüm çeşitli şeylerle (kısıtlamalar / dizinler / bölümler / tetikleyiciler / vb.) CREATE komut dosyası oluşturmaya çalışıyorum. Bunu imleçsiz bir yaklaşımla yeniden oluşturmada başarılı olup olmadığınızı merak ediyordum. öyleyse, paylaşır mısın? Çok minnettarız, teşekkürler
007

Yazdığım komut dosyası bir veya daha fazla tabloyu kopyalıyor ve imleç kullanmıyor. Ayrıca bir yorum için çok büyük. Bunun yerine Hans Michiels senaryosuna bağlantı vereceğim: hansmichiels.com/2016/02/18/…
mendosi

4
  1. Aynı DataBase'i kopyalamak istiyorsanız

    Select * INTO NewTableName from OldTableName
    
  2. Başka bir Veri Tabanı ise

    Select * INTO NewTableName from DatabaseName.OldTableName
    


3

Bunu neden yapmak istediğini bilmiyorum ama dene:

SELECT *
INTO NewTable
FROM OldTable
WHERE 1 = 2

İşe yaramalı.


Sanırım bu da verileri kopyalayacak mı? o sadece yapıyı istiyor.
Ashish Gupta

@Ashis Gupta - Teşekkürler, "nerede" yi unuttum :)
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;

3
bu kısıtlamaları ve anahtarları kopyalamaz
Trikaldarshiii

2

Burada aradığımı buldum. 3-4 yıl önce ne kullandığımı hatırlamama yardımcı oldu.

Bir tablonun birleştirilmesinden kaynaklanan verilerle tablo oluşturabilmek için aynı sözdizimini yeniden kullanmak istedim.

Birkaç denemeden sonra aşağıdaki sorgu ile geldi.

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

Daha fazla okunabilirlik için lütfen kod işaretlemeyi kullanın, ayrıca kodunuz hakkında biraz açıklama yapmak daha yararlıdır.
Nima Derakhshanjan

Hemen yardımcı olabilecek bu kod parçacığı için teşekkür ederiz. Uygun bir açıklama , bunun neden soruna iyi bir çözüm olduğunu göstererek eğitimsel değerini büyük ölçüde artıracak ve benzer, ancak aynı olmayan sorulara sahip gelecekteki okuyucular için daha yararlı hale getirecektir. Özellikle, eğitimsiz göze sanki bu aynı zamanda içeriğini de kopyalayacakmış gibi bakıyor Oldtable. Bundan nasıl kaçınılır?
Toby Speight

-1

Orijinal tablodan kopyalanacak tek yapıya sahip bir tablo oluşturmak istiyorsanız, bunu yapmak için aşağıdaki komutu kullanabilirsiniz.

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

Bu yanlış koşulla kayıtları bırakabilir ve yapıyı kopyalayabilirsiniz.


Bu, mevcut yanıtların bir kopyasıdır. Yenisini göndermeden önce mevcut cevapları okuyun ve uygunsa yorum / oy ekleyin.
Kevin Hogg

Ama buradaki mevcut cevapla aynı değil, bu eylemi yapmak için create komutunu kullandım
Sai Durga Kamesh Kota

@AbhiUrs cevabını (02-Ocak-2015) gözden geçirirseniz, cevabınız biraz farklı bir where cümlesiyle de olsa, cevaplarının ilk kısmına benzer. Birinci bölüm => create table AT_QUOTE_CART as select * from QUOTE_CART where 0=1 ; Bu tablo adlarını değiştirin ve şunu elde ederiz: create table <tablename> as select * from <sourcetablename> where 0=1 ; where cümlesine gelince , hiçbir veri alınmayanla 0=1aynı sonucu elde eder 1>2.
Kevin Hogg
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.