In SQL Server, how do I generate a CREATE TABLE statement for a given table?

前端 未结 16 2195
离开以前
离开以前 2020-11-22 11:34

I\'ve spent a good amount of time coming up with solution to this problem, so in the spirit of this post, I\'m posting it here, since I think it might be useful to others. <

相关标签:
16条回答
  • 2020-11-22 11:48

    I've modified the version above to run for all tables and support new SQL 2005 data types. It also retains the primary key names. Works only on SQL 2005 (using cross apply).

    
    select  'create table [' + so.name + '] (' + o.list + ')' + CASE WHEN tc.Constraint_Name IS NULL THEN '' ELSE 'ALTER TABLE ' + so.Name + ' ADD CONSTRAINT ' + tc.Constraint_Name  + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')' END
    from    sysobjects so
    cross apply
        (SELECT 
            '  ['+column_name+'] ' + 
            data_type + case data_type
                when 'sql_variant' then ''
                when 'text' then ''
                when 'ntext' then ''
                when 'xml' then ''
                when 'decimal' then '(' + cast(numeric_precision as varchar) + ', ' + cast(numeric_scale as varchar) + ')'
                else coalesce('('+case when character_maximum_length = -1 then 'MAX' else cast(character_maximum_length as varchar) end +')','') end + ' ' +
            case when exists ( 
            select id from syscolumns
            where object_name(id)=so.name
            and name=column_name
            and columnproperty(id,name,'IsIdentity') = 1 
            ) then
            'IDENTITY(' + 
            cast(ident_seed(so.name) as varchar) + ',' + 
            cast(ident_incr(so.name) as varchar) + ')'
            else ''
            end + ' ' +
             (case when UPPER(IS_NULLABLE) = 'NO' then 'NOT ' else '' end ) + 'NULL ' + 
              case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT ELSE '' END + ', ' 
    
         from information_schema.columns where table_name = so.name
         order by ordinal_position
        FOR XML PATH('')) o (list)
    left join
        information_schema.table_constraints tc
    on  tc.Table_name       = so.Name
    AND tc.Constraint_Type  = 'PRIMARY KEY'
    cross apply
        (select '[' + Column_Name + '], '
         FROM   information_schema.key_column_usage kcu
         WHERE  kcu.Constraint_Name = tc.Constraint_Name
         ORDER BY
            ORDINAL_POSITION
         FOR XML PATH('')) j (list)
    where   xtype = 'U'
    AND name    NOT IN ('dtproperties')
    
    

    Update: Added handling of the XML data type

    Update 2: Fixed cases when 1) there is multiple tables with the same name but with different schemas, 2) there is multiple tables having PK constraint with the same name

    0 讨论(0)
  • 2020-11-22 11:48

    I modified the accepted answer and now it can get the command including primary key and foreign key in a certain schema.

    declare @table varchar(100)
    declare @schema varchar(100)
    set @table = 'Persons' -- set table name here
    set @schema = 'OT' -- set SCHEMA name here
    declare @sql table(s varchar(1000), id int identity)
    
    -- create statement
    insert into  @sql(s) values ('create table ' + @table + ' (')
    
    -- column list
    insert into @sql(s)
    select 
        '  '+column_name+' ' + 
        data_type + coalesce('('+cast(character_maximum_length as varchar)+')','') + ' ' +
        case when exists ( 
            select id from syscolumns
            where object_name(id)=@table
            and name=column_name
            and columnproperty(id,name,'IsIdentity') = 1 
        ) then
            'IDENTITY(' + 
            cast(ident_seed(@table) as varchar) + ',' + 
            cast(ident_incr(@table) as varchar) + ')'
        else ''
        end + ' ' +
        ( case when IS_NULLABLE = 'No' then 'NOT ' else '' end ) + 'NULL ' + 
        coalesce('DEFAULT '+COLUMN_DEFAULT,'') + ','
    
     from information_schema.columns where table_name = @table and table_schema = @schema
     order by ordinal_position
    
    -- primary key
    declare @pkname varchar(100)
    select @pkname = constraint_name from information_schema.table_constraints
    where table_name = @table and constraint_type='PRIMARY KEY'
    
    if ( @pkname is not null ) begin
        insert into @sql(s) values('  PRIMARY KEY (')
        insert into @sql(s)
            select '   '+COLUMN_NAME+',' from information_schema.key_column_usage
            where constraint_name = @pkname
            order by ordinal_position
        -- remove trailing comma
        update @sql set s=left(s,len(s)-1) where id=@@identity
        insert into @sql(s) values ('  )')
    end
    else begin
        -- remove trailing comma
        update @sql set s=left(s,len(s)-1) where id=@@identity
    end
    
    
    -- foreign key
    declare @fkname varchar(100)
    select @fkname = constraint_name from information_schema.table_constraints
    where table_name = @table and constraint_type='FOREIGN KEY'
    
    if ( @fkname is not null ) begin
        insert into @sql(s) values(',')
        insert into @sql(s) values('  FOREIGN KEY (')
        insert into @sql(s)
            select '   '+COLUMN_NAME+',' from information_schema.key_column_usage
            where constraint_name = @fkname
            order by ordinal_position
        -- remove trailing comma
        update @sql set s=left(s,len(s)-1) where id=@@identity
        insert into @sql(s) values ('  ) REFERENCES ')
        insert into @sql(s) 
            SELECT  
                OBJECT_NAME(fk.referenced_object_id)
            FROM 
                sys.foreign_keys fk
            INNER JOIN 
                sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id
            INNER JOIN
                sys.columns c1 ON fkc.parent_column_id = c1.column_id AND fkc.parent_object_id = c1.object_id
            INNER JOIN
                sys.columns c2 ON fkc.referenced_column_id = c2.column_id AND fkc.referenced_object_id = c2.object_id
            where fk.name = @fkname
        insert into @sql(s) 
            SELECT  
                '('+c2.name+')'
            FROM 
                sys.foreign_keys fk
            INNER JOIN 
                sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id
            INNER JOIN
                sys.columns c1 ON fkc.parent_column_id = c1.column_id AND fkc.parent_object_id = c1.object_id
            INNER JOIN
                sys.columns c2 ON fkc.referenced_column_id = c2.column_id AND fkc.referenced_object_id = c2.object_id
            where fk.name = @fkname
    end
    
    -- closing bracket
    insert into @sql(s) values( ')' )
    
    -- result!
    select s from @sql order by id
    
    0 讨论(0)
  • 2020-11-22 11:49

    I'm going to improve the answer by supporting partitioned tables:

    find partition scheme and partition key using below scritps:

    declare @partition_scheme varchar(100) = (
    select distinct ps.Name AS PartitionScheme
    from sys.indexes i  
    join sys.partitions p ON i.object_id=p.object_id AND i.index_id=p.index_id  
    join sys.partition_schemes ps on ps.data_space_id = i.data_space_id  
    where i.object_id = object_id('your table name')
    )
    print @partition_scheme
    
    declare @partition_column varchar(100) = (
    select c.name 
    from  sys.tables          t
    join  sys.indexes         i 
          on(i.object_id = t.object_id 
      and i.index_id < 2)
    join  sys.index_columns  ic 
      on(ic.partition_ordinal > 0 
      and ic.index_id = i.index_id and ic.object_id = t.object_id)
    join  sys.columns         c 
      on(c.object_id = ic.object_id 
      and c.column_id = ic.column_id)
    where t.object_id  = object_id('your table name')
    )
    print @partition_column
    

    then change the generation query by adding below line at the right place:

    + IIF(@partition_scheme is null, '', 'ON [' + @partition_scheme + ']([' + @partition_column + '])')
    
    0 讨论(0)
  • 2020-11-22 11:54

    Here's the script that I came up with. It handles Identity columns, default values, and primary keys. It does not handle foreign keys, indexes, triggers, or any other clever stuff. It works on SQLServer 2000, 2005 and 2008.

    declare @schema varchar(100), @table varchar(100)
    set @schema = 'dbo' -- set schema name here
    set @table = 'MyTable' -- set table name here
    declare @sql table(s varchar(1000), id int identity)
    
    -- create statement
    insert into  @sql(s) values ('create table [' + @table + '] (')
    
    -- column list
    insert into @sql(s)
    select 
        '  ['+column_name+'] ' + 
        data_type + coalesce('('+cast(character_maximum_length as varchar)+')','') + ' ' +
        case when exists ( 
            select id from syscolumns
            where object_name(id)=@table
            and name=column_name
            and columnproperty(id,name,'IsIdentity') = 1 
        ) then
            'IDENTITY(' + 
            cast(ident_seed(@table) as varchar) + ',' + 
            cast(ident_incr(@table) as varchar) + ')'
        else ''
        end + ' ' +
        ( case when IS_NULLABLE = 'No' then 'NOT ' else '' end ) + 'NULL ' + 
        coalesce('DEFAULT '+COLUMN_DEFAULT,'') + ','
    
     from INFORMATION_SCHEMA.COLUMNS where table_name = @table AND table_schema = @schema
     order by ordinal_position
    
    -- primary key
    declare @pkname varchar(100)
    select @pkname = constraint_name from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    where table_name = @table and constraint_type='PRIMARY KEY'
    
    if ( @pkname is not null ) begin
        insert into @sql(s) values('  PRIMARY KEY (')
        insert into @sql(s)
            select '   ['+COLUMN_NAME+'],' from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
            where constraint_name = @pkname
            order by ordinal_position
        -- remove trailing comma
        update @sql set s=left(s,len(s)-1) where id=@@identity
        insert into @sql(s) values ('  )')
    end
    else begin
        -- remove trailing comma
        update @sql set s=left(s,len(s)-1) where id=@@identity
    end
    
    -- closing bracket
    insert into @sql(s) values( ')' )
    
    -- result!
    select s from @sql order by id
    
    0 讨论(0)
  • 2020-11-22 11:54

    Show create table in classic asp (handles constraints, primary keys, copying the table structure and/or data ...)

    Sql server Show create table Mysql-style "Show create table" and "show create database" commands from Microsoft sql server. The script is written is Microsoft asp-language and is quite easy to port to another language.*

    0 讨论(0)
  • 2020-11-22 11:55

    I include definitions for computed columns

        select 'CREATE TABLE [' + so.name + '] (' + o.list + ')' + CASE WHEN tc.Constraint_Name IS NULL THEN '' ELSE 'ALTER TABLE ' + so.Name + ' ADD CONSTRAINT ' + tc.Constraint_Name  + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')' END, name
    from    sysobjects so
    cross apply
        (SELECT
    
    case when comps.definition is not null then '  ['+column_name+'] AS ' + comps.definition 
    else
            '  ['+column_name+'] ' + data_type + 
            case
            when data_type like '%text' or data_type in ('image', 'sql_variant' ,'xml')
                then ''
            when data_type in ('float')
                then '(' + cast(coalesce(numeric_precision, 18) as varchar(11)) + ')'
            when data_type in ('datetime2', 'datetimeoffset', 'time')
                then '(' + cast(coalesce(datetime_precision, 7) as varchar(11)) + ')'
            when data_type in ('decimal', 'numeric')
                then '(' + cast(coalesce(numeric_precision, 18) as varchar(11)) + ',' + cast(coalesce(numeric_scale, 0) as varchar(11)) + ')'
            when (data_type like '%binary' or data_type like '%char') and character_maximum_length = -1
                then '(max)'
            when character_maximum_length is not null
                then '(' + cast(character_maximum_length as varchar(11)) + ')'
            else ''
            end + ' ' +
            case when exists ( 
            select id from syscolumns
            where object_name(id)=so.name
            and name=column_name
            and columnproperty(id,name,'IsIdentity') = 1 
            ) then
            'IDENTITY(' + 
            cast(ident_seed(so.name) as varchar) + ',' + 
            cast(ident_incr(so.name) as varchar) + ')'
            else ''
            end + ' ' +
             (case when information_schema.columns.IS_NULLABLE = 'No' then 'NOT ' else '' end ) + 'NULL ' + 
              case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT ELSE '' END 
    end + ', ' 
    
         from information_schema.columns 
         left join sys.computed_columns comps 
         on OBJECT_ID(information_schema.columns.TABLE_NAME)=comps.object_id and information_schema.columns.COLUMN_NAME=comps.name
    
         where table_name = so.name
         order by ordinal_position
        FOR XML PATH('')) o (list)
    left join
        information_schema.table_constraints tc
    on  tc.Table_name       = so.Name
    AND tc.Constraint_Type  = 'PRIMARY KEY'
    cross apply
        (select '[' + Column_Name + '], '
         FROM   information_schema.key_column_usage kcu
         WHERE  kcu.Constraint_Name = tc.Constraint_Name
         ORDER BY
            ORDINAL_POSITION
         FOR XML PATH('')) j (list)
    where   xtype = 'U'
    AND name    NOT IN ('dtproperties')
    
    0 讨论(0)
提交回复
热议问题