Tạo bảng (cấu trúc) từ bảng hiện có


100

Cách tạo bảng mới có cấu trúc giống với một bảng khác

Tôi đã thử

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

nhưng nó không hoạt động lỗi xảy ra


rất hữu ích, hấp dẫn để có một mệnh đề where luôn sai!
JosephDoggie

Câu trả lời:


167

Thử:

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

Lưu ý rằng điều này sẽ không sao chép chỉ mục, khóa, v.v.

Nếu bạn muốn sao chép toàn bộ cấu trúc, bạn cần tạo một Tập lệnh Tạo của bảng. Bạn có thể sử dụng tập lệnh đó để tạo một bảng mới có cùng cấu trúc. Sau đó, bạn cũng có thể kết xuất dữ liệu vào bảng mới nếu cần.

Nếu bạn đang sử dụng Trình quản lý doanh nghiệp, chỉ cần nhấp chuột phải vào bảng và chọn bản sao để tạo Tập lệnh tạo.


1
Kevin, chỉ cần một sự thay đổi định dạng nhỏ trong câu trả lời của bạn: - Chọn * Into <DestinationTableName> Từ <SourceTableName> Trong trường hợp 1 = 2
Ashish Gupta

6
Qutbuddin, 1 = 2 sẽ ngăn việc sao chép dữ liệu từ nguồn sang bảng đích. Hãy thử tự mình: - TẠO BẢNG Table1 (Id int, Name varchar (200)) CHÈN VÀO GIÁ TRỊ của bảng1 (1, 'A') CHÈN VÀO bảng1 GIÁ TRỊ (2, 'B') - Sẽ tạo bảng2 với dữ liệu trong bảng1 CHỌN * vÀO table2 TỪ table1 WHERE 1 = 2 - Sẽ tạo table2 không có dữ liệu trong table1 SELECT * vÀO table2 TỪ table1 WHERE 1 = 2
Ashish Gupta

Tôi nghĩ 1 = 2 sẽ chỉ là một đối số sai kỳ lạ để tránh sao chép dữ liệu.
Arthur Zennig

44

Đây là những gì tôi sử dụng để sao chép cấu trúc bảng (chỉ cột) ...

SELECT TOP 0 *
INTO NewTable
FROM TableStructureIWishToClone

1
Giải pháp này là rõ ràng hơn vì phải điều kiện thêm "1 = 2", tôi muốn giới thiệu này
Pinte Dani

30

Chỉ sao chép cấu trúc (sao chép tất cả các cột)

Select Top 0 * into NewTable from OldTable

Chỉ sao chép cấu trúc (sao chép một số cột)

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

Sao chép cấu trúc với dữ liệu

Select * into NewTable from OldTable

Nếu bạn đã có một bảng có cùng cấu trúc và bạn chỉ muốn sao chép dữ liệu thì hãy sử dụng

Insert into NewTable Select * from OldTable

Làm việc cho tôi trong MSSQL 2008 R2
pyrit

Giải pháp tuyệt vời, đơn giản và thanh lịch. Có cách nào để tạo chỉ mục sao chép và khóa chính không?
Tumaini Mosha

16
Create table abc select * from def limit 0;

Điều này sẽ làm việc nhất định


Hoàn hảo! Cảm ơn bạn
Dylan B

14

ĐỐI VỚI MYSQL:

Bạn có thể dùng:

CREATE TABLE foo LIKE bar;

Tài liệu tại đây .


20
Câu hỏi được gắn thẻ là sql-servercú pháp này không hợp lệ, fyi.
Molomby

Không nên tính là câu trả lời do liên quan đến MySQL không sql-server
celerno

2
FYI - điều này cũng giữ lại các khóa và chỉ mục chính.
garg10may

8

Cũng có thể đáng nói là bạn có thể làm như sau:

Nhấp chuột phải vào bảng bạn muốn sao chép > Bảng tập lệnh dưới dạng > Tạo thành > Cửa sổ trình soạn thảo truy vấn mới

Sau đó, ở đâu cho biết tên của bảng mà bạn vừa nhấp chuột phải trong tập lệnh đã được tạo, hãy thay đổi tên mà bạn muốn gọi bảng mới của mình và nhấp vào Execute


5

hãy thử cái này .. cái dưới đây sao chép toàn bộ cấu trúc của bảng hiện có nhưng không sao chép dữ liệu.

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

nếu bạn muốn sao chép dữ liệu thì hãy sử dụng cái bên dưới:

create table AT_QUOTE_CART as select * from QUOTE_CART ;

5

Tôi sử dụng proc được lưu trữ sau để sao chép lược đồ của bảng, bao gồm PK, chỉ mục, trạng thái phân vùng. Nó không nhanh lắm, nhưng dường như làm được việc. Tôi hoan nghênh bất kỳ ý tưởng nào về cách tăng tốc:

    /*
        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
Làm cho điều này nhanh hơn có thể đơn giản như khai báo các con trỏ của bạn CURSOR LOCAL FAST_FORWARD. Cá nhân tôi đang cố gắng tạo một tập lệnh tương tự mà không sử dụng con trỏ và xem nó hoạt động như thế nào.
mendosi

Xin chào @mendosi Tôi biết nó đã cũ, nhưng tôi hiện đang tìm cách tạo tập lệnh CREATE với tất cả những thứ linh tinh (ràng buộc / chỉ mục / phân vùng / trình kích hoạt / v.v.) cùng với định nghĩa cột. Tôi đã tự hỏi liệu bạn có thành công khi tạo lại điều này bằng cách tiếp cận không dùng con trỏ hay không. nếu vậy, bạn có phiền chia sẻ nó không? Được đánh giá cao, cảm ơn bạn
007

Tập lệnh tôi đã viết sao chép một hoặc nhiều bảng và không sử dụng con trỏ. Nó cũng quá lớn cho một bình luận. Thay vào đó, tôi sẽ liên kết đến kịch bản của Hans Michiels: hansmichiels.com/2016/02/18/…
mendosi


3

Tôi không biết tại sao bạn muốn làm điều đó, nhưng hãy thử:

SELECT *
INTO NewTable
FROM OldTable
WHERE 1 = 2

Nó sẽ hoạt động.


Tôi nghĩ rằng điều đó cũng sẽ sao chép dữ liệu? anh ta chỉ muốn cấu trúc.
Ashish Gupta,

@Ashis Gupta - Cảm ơn, tôi đã quên "ở đâu" :)
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
điều này không sao chép những hạn chế và các phím
Trikaldarshi

3
  1. Nếu bạn muốn sao chép cùng một DataBase

    Select * INTO NewTableName from OldTableName
  2. Nếu một DataBase khác

    Select * INTO NewTableName from DatabaseName.OldTableName

2

Tìm thấy ở đây những gì tôi đang tìm kiếm. Đã giúp tôi nhớ lại những gì tôi đã sử dụng 3-4 năm trước.

Tôi muốn sử dụng lại cú pháp tương tự để có thể tạo bảng với dữ liệu là kết quả của việc nối bảng.

Đưa ra truy vấn dưới đây sau một vài lần thử.

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

Vui lòng sử dụng đánh dấu mã để dễ đọc hơn, cũng hữu ích hơn khi giải thích một chút về mã của bạn.
Nima Derakhshanjan

Cảm ơn bạn về đoạn mã này, đoạn mã có thể cung cấp một số trợ giúp ngay lập tức. Một lời giải thích phù hợp sẽ cải thiện đáng kể giá trị giáo dục của nó bằng cách chỉ ra lý do tại sao đây là một giải pháp tốt cho vấn đề và sẽ làm cho nó hữu ích hơn cho những độc giả trong tương lai với những câu hỏi tương tự, nhưng không giống hệt nhau. Đặc biệt, nó nhìn bằng con mắt chưa được đào tạo như thể điều này cũng sẽ sao chép nội dung của Oldtable. Làm thế nào mà tránh được?
Toby Speight
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.