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

前端 未结 16 2471
离开以前
离开以前 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:47

    A query based on Hubbitus answer.

    • includes schema names
    • fixes foreign keys with more than one field
    • includes CASCADE UPDATE & DELETE
    • includes a conditioned DROP TABLE
    SELECT 
      Schema_Name = SCHEMA_NAME(obj.uid)
    , Table_Name = name
    , Drop_Table = 'IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES  WHERE TABLE_SCHEMA = ''' + SCHEMA_NAME(obj.uid) + '''  AND  TABLE_NAME = ''' + obj.name + '''))
    DROP TABLE [' + SCHEMA_NAME(obj.uid) + '].[' + obj.name + '] '
    , Create_Table ='
    CREATE TABLE [' + SCHEMA_NAME(obj.uid) + '].[' + obj.name + '] (' + LEFT(cols.list, LEN(cols.list) - 1 ) + ')' + ISNULL(' ' + refs.list, '')
        FROM sysobjects obj
        CROSS APPLY (
            SELECT 
                CHAR(10)
                + ' [' + 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 ( -- Identity skip
                                    select id from syscolumns
                                    where id = obj.id
                                    and name = column_name
                                    and columnproperty(id, name, 'IsIdentity') = 1 
                                    ) then
                            'IDENTITY(' + 
                                cast(ident_seed(obj.name) as varchar) + ',' + 
                                cast(ident_incr(obj.name) as varchar) + ')'
                else ''
                end + ' '
                + CASE WHEN IS_NULLABLE = 'No' THEN 'NOT ' ELSE '' END
                + 'NULL'
                + CASE WHEN IC.column_default IS NOT NULL THEN ' DEFAULT ' + IC.column_default ELSE '' END
                + ','
            FROM INFORMATION_SCHEMA.COLUMNS IC
            WHERE IC.table_name   = obj.name
              AND IC.TABLE_SCHEMA = SCHEMA_NAME(obj.uid)
            ORDER BY ordinal_position
            FOR XML PATH('')
        ) cols (list)
        CROSS APPLY(
            SELECT
                CHAR(10) + 'ALTER TABLE [' + SCHEMA_NAME(obj.uid) + '].[' + obj.name + '] ADD ' + LEFT(alt, LEN(alt)-1)
            FROM(
                SELECT
                    CHAR(10)
                    + ' CONSTRAINT ' + tc.constraint_name
                    + ' ' + tc.constraint_type + ' (' + LEFT(c.list, LEN(c.list)-1) + ')'
                    + COALESCE(CHAR(10) + r.list, ', ')
                FROM information_schema.table_constraints tc
                    CROSS APPLY(
                        SELECT   '[' + kcu.column_name + '], '
                        FROM     information_schema.key_column_usage kcu
                        WHERE    kcu.constraint_name = tc.constraint_name
                        ORDER BY kcu.ordinal_position
                        FOR XML PATH('')
                    ) c (list)
                    OUTER APPLY(
                        -- // http://stackoverflow.com/questions/3907879/sql-server-howto-get-foreign-key-reference-from-information-schema
                        SELECT LEFT(f.list, LEN(f.list)-1) + ')' + IIF(rc.DELETE_RULE = 'NO ACTION', '', ' ON DELETE ' + rc.DELETE_RULE) + IIF(rc.UPDATE_RULE = 'NO ACTION', '', ' ON UPDATE ' + rc.UPDATE_RULE) + ', '
                        FROM information_schema.referential_constraints rc
                        CROSS APPLY(
                            SELECT IIF(kcu.ordinal_position = 1, ' REFERENCES [' + kcu.table_schema + '].[' + kcu.table_name + '] (', '') 
                                    + '[' + kcu.column_name + '], '
                            FROM information_schema.key_column_usage kcu 
                            WHERE kcu.constraint_catalog = rc.unique_constraint_catalog AND kcu.constraint_schema = rc.unique_constraint_schema AND kcu.constraint_name = rc.unique_constraint_name
                            ORDER BY kcu.ordinal_position
                            FOR XML PATH('')
                        ) f (list)
                        WHERE rc.constraint_catalog = tc.constraint_catalog 
                          AND rc.constraint_schema  = tc.constraint_schema 
                          AND rc.constraint_name    = tc.constraint_name
                    ) r (list)
                WHERE tc.table_name = obj.name
                FOR XML PATH('')
            ) a (alt)
        ) refs (list)
        WHERE xtype = 'U'
    

    To combine drop table (if exists) with create use like this:

    SELECT Drop_Table + CHAR(10) + Create_Table FROM SysCreateTables
    

提交回复
热议问题