สร้างตาราง (โครงสร้าง) จากตารางที่มีอยู่


103

วิธีสร้างตารางใหม่ซึ่งโครงสร้างควรจะเหมือนกับตารางอื่น

ฉันเหนื่อย

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

แต่เกิดข้อผิดพลาดไม่ทำงาน


มีประโยชน์มากน่าสนใจที่จะมีประโยค where ที่เป็นเท็จเสมอ!
JosephDoggie

คำตอบ:


171

ลอง:

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

โปรดทราบว่าสิ่งนี้จะไม่คัดลอกดัชนีคีย์และอื่น ๆ

หากคุณต้องการคัดลอกโครงสร้างทั้งหมดคุณต้องสร้าง Create Script ของตาราง คุณสามารถใช้สคริปต์นั้นเพื่อสร้างตารางใหม่ที่มีโครงสร้างเดียวกัน จากนั้นคุณสามารถถ่ายโอนข้อมูลลงในตารางใหม่ได้หากต้องการ

หากคุณใช้ Enterprise Manager เพียงคลิกขวาที่ตารางแล้วเลือกคัดลอกเพื่อสร้าง Create Script


1
เควินการเปลี่ยนรูปแบบเพียงเล็กน้อยในคำตอบของคุณ: - เลือก * เป็น <DestinationTableName> จาก <SourceTableName> โดยที่ 1 = 2
Ashish Gupta

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 * เข้าสู่ Table2 จาก Table1 WHERE 1 = 2 - จะสร้าง table2 โดยไม่มีข้อมูลใน table1 SELECT * INTO Table2 จาก Table1 WHERE 1 = 2
Ashish Gupta

ฉันคิดว่า 1 = 2 เป็นเพียงการโต้แย้งที่ผิดแปลก ๆ เพื่อหลีกเลี่ยงการคัดลอกข้อมูล
Arthur Zennig

45

นี่คือสิ่งที่ฉันใช้ในการโคลนโครงสร้างตาราง (คอลัมน์เท่านั้น) ...

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone

1
วิธีแก้ปัญหานี้ชัดเจนกว่าการมีเงื่อนไขพิเศษ "1 = 2" ฉันขอแนะนำสิ่งนี้
Pinte Dani

32

คัดลอกโครงสร้างเท่านั้น (คัดลอกคอลัมน์ทั้งหมด)

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
Pyrite

1
ทางออกที่ดีเรียบง่ายและสง่างาม มีการแฮ็กเพื่อสร้างดัชนีการคัดลอกและคีย์หลักด้วยหรือไม่
Tumaini Mosha

16
Create table abc select * from def limit 0;

สิ่งนี้จะได้ผลแน่นอน


สมบูรณ์แบบ! ขอบคุณ
Dylan B

สังเกตว่าคำถามถูกแท็กsql-serverและไม่สามารถใช้งานได้ใน SQL Server
Alexandre

14

สำหรับ MYSQL:

คุณสามารถใช้ได้:

CREATE TABLE foo LIKE bar;

เอกสารที่นี่


21
คำถามถูกแท็กว่าsql-serverไวยากรณ์นี้ไม่ถูกต้อง fyi
Molomby

ไม่ควรนับเป็นคำตอบเนื่องจากความสัมพันธ์กับ MySQL ไม่ใช่ sql-server
celerno

2
FYI - ยังเก็บคีย์หลักและดัชนีไว้ด้วย
garg10

8

อาจเป็นเรื่องที่ควรค่าแก่การกล่าวถึงว่าคุณสามารถทำสิ่งต่อไปนี้:

คลิกขวาที่ตารางที่คุณต้องการทำซ้ำ> Script Table As > Create To > New Query Editor Window

จากนั้นชื่อตารางที่คุณเพิ่งคลิกขวาในสคริปต์ที่สร้างขึ้นนั้นอยู่ที่ไหนให้เปลี่ยนชื่อเป็นสิ่งที่คุณต้องการให้เรียกตารางใหม่ของคุณแล้วคลิก 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

ฉันใช้ proc ที่เก็บไว้ต่อไปนี้เพื่อคัดลอกสคีมาของตารางรวมถึง PK ดัชนีสถานะพาร์ติชัน มันไม่เร็วมาก แต่ดูเหมือนจะทำงาน II ยินดีต้อนรับทุกแนวคิดในการเร่งความเร็ว:

    /*
        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

สคริปต์ที่ฉันเขียนจะคัดลอกตารางอย่างน้อยหนึ่งตารางและไม่ใช้เคอร์เซอร์ นอกจากนี้ยังใหญ่เกินไปสำหรับความคิดเห็น แต่ฉันจะเชื่อมโยงไปยัง Hans Michiels script: hansmichiels.com/2016/02/18/…
mendosi

4
  1. หากคุณต้องการคัดลอกฐานข้อมูลเดียวกัน

    Select * INTO NewTableName from OldTableName
    
  2. ถ้า DataBase อื่น

    Select * INTO NewTableName from DatabaseName.OldTableName
    


3

ฉันไม่รู้ว่าทำไมคุณถึงอยากทำแบบนั้น แต่ลอง:

SELECT *
INTO NewTable
FROM OldTable
WHERE 1 = 2

มันควรจะทำงาน


ฉันคิดว่าจะคัดลอกข้อมูลด้วยหรือไม่? เขาต้องการเพียงโครงสร้าง
Ashish Gupta

@Ashis Gupta - ขอบคุณฉันลืม "ที่ไหน" :)
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
สิ่งนี้ไม่ได้คัดลอกข้อ จำกัด และคีย์
Trikaldarshiii

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

โปรดใช้โค้ดมาร์กอัปเพื่อให้อ่านง่ายขึ้นซึ่งจะมีประโยชน์มากกว่าในการอธิบายเล็กน้อยเกี่ยวกับโค้ดของคุณ
Nima Derakhshanjan

ขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือได้ทันที คำอธิบายที่เหมาะสมจะช่วยเพิ่มคุณค่าทางการศึกษาได้อย่างมากโดยแสดงให้เห็นว่าเหตุใดจึงเป็นวิธีแก้ปัญหาที่ดีและจะทำให้มีประโยชน์มากขึ้นสำหรับผู้อ่านในอนาคตที่มีคำถามที่คล้ายกัน แต่ไม่เหมือนกัน Oldtableโดยเฉพาะอย่างยิ่งมันดูได้ด้วยตาได้รับการฝึกฝนเป็นว่านี้ก็จะคัดลอกเนื้อหาของ หลีกเลี่ยงได้อย่างไร?
Toby Speight

-1

หากคุณต้องการสร้างตารางที่มีโครงสร้างเดียวที่จะคัดลอกจากตารางเดิมคุณสามารถใช้คำสั่งต่อไปนี้เพื่อดำเนินการดังกล่าว

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

ด้วยเงื่อนไขเท็จนี้คุณสามารถออกจากระเบียนและคัดลอกโครงสร้างได้


คำตอบนี้ซ้ำกับคำตอบที่มีอยู่ อ่านคำตอบที่มีอยู่ก่อนส่งคำตอบใหม่และเพิ่มความคิดเห็น / โหวตตามความเหมาะสม
Kevin Hogg

แต่มันไม่เหมือนกับคำตอบที่มีอยู่ที่นี่ฉันใช้คำสั่งสร้างเพื่อดำเนินการนี้
Sai Durga Kamesh Kota

หากคุณตรวจสอบคำตอบของ @AbhiUrs (02- ม.ค. 2558) คำตอบของคุณจะคล้ายกับส่วนแรกของคำตอบแม้ว่าจะมีข้อแตกต่างกันเล็กน้อย ส่วนแรก => 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ที่ไม่มีการดึงข้อมูล
Kevin Hogg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.