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

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

    There is a Powershell script buried in the msdb forums that will script all the tables and related objects:

    # Script all tables in a database
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") 
        | out-null
    
    $s = new-object ('Microsoft.SqlServer.Management.Smo.Server') '<Servername>'
    $db = $s.Databases['<Database>']
    
    $scrp = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') ($s)
    $scrp.Options.AppendToFile = $True
    $scrp.Options.ClusteredIndexes = $True
    $scrp.Options.DriAll = $True
    $scrp.Options.ScriptDrops = $False
    $scrp.Options.IncludeHeaders = $False
    $scrp.Options.ToFileOnly = $True
    $scrp.Options.Indexes = $True
    $scrp.Options.WithDependencies = $True
    $scrp.Options.FileName = 'C:\Temp\<Database>.SQL'
    
    foreach($item in $db.Tables) { $tablearray+=@($item) }
    $scrp.Script($tablearray)
    
    Write-Host "Scripting complete"
    
    0 讨论(0)
  • 2020-11-22 11:41

    Something I've noticed - in the INFORMATION_SCHEMA.COLUMNS view, CHARACTER_MAXIMUM_LENGTH gives a size of 2147483647 (2^31-1) for field types such as image and text. ntext is 2^30-1 (being double-byte unicode and all).

    This size is included in the output from this query, but it is invalid for these data types in a CREATE statement (they should not have a maximum size value at all). So unless the results from this are manually corrected, the CREATE script won't work given these data types.

    I imagine it's possible to fix the script to account for this, but that's beyond my SQL capabilities.

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

    One more variant with foreign keys support and in one statement:

     SELECT
            obj.name
            ,'CREATE TABLE [' + 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 object_name(id) = obj.name
                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 information_schema.columns.column_default IS NOT NULL THEN ' DEFAULT ' + information_schema.columns.column_default ELSE '' END
                + ','
            FROM
                INFORMATION_SCHEMA.COLUMNS
            WHERE table_name = obj.name
            ORDER BY ordinal_position
            FOR XML PATH('')
        ) cols (list)
        CROSS APPLY(
            SELECT
                CHAR(10) + 'ALTER TABLE ' + obj.name + '_noident_temp 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
                            '  REFERENCES [' + kcu1.constraint_schema + '].' + '[' + kcu2.table_name + ']' + '(' + kcu2.column_name + '), '
                        FROM information_schema.referential_constraints as rc
                            JOIN information_schema.key_column_usage as kcu1 ON (kcu1.constraint_catalog = rc.constraint_catalog AND kcu1.constraint_schema = rc.constraint_schema AND kcu1.constraint_name = rc.constraint_name)
                            JOIN information_schema.key_column_usage as kcu2 ON (kcu2.constraint_catalog = rc.unique_constraint_catalog AND kcu2.constraint_schema = rc.unique_constraint_schema AND kcu2.constraint_name = rc.unique_constraint_name AND kcu2.ordinal_position = KCU1.ordinal_position)
                        WHERE
                            kcu1.constraint_catalog = tc.constraint_catalog AND kcu1.constraint_schema = tc.constraint_schema AND kcu1.constraint_name = tc.constraint_name
                    ) r (list)
                WHERE tc.table_name = obj.name
                FOR XML PATH('')
            ) a (alt)
        ) refs (list)
        WHERE
            xtype = 'U'
        AND name NOT IN ('dtproperties')
        AND obj.name = 'your_table_name'
    

    You could try in is sqlfiddle: http://sqlfiddle.com/#!6/e3b66/3/0

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

    Credit due to @Blorgbeard for sharing his script. I'll certainly bookmark it in case I need it.

    Yes, you can "right click" on the table and script the CREATE TABLE script, but:

    • The a script will contain loads of cruft (interested in the extended properties anyone?)
    • If you have 200+ tables in your schema, it's going to take you half a day to script the lot by hand.

    With this script converted into a stored procedure, and combined with a wrapper script you would have a nice automated way to dump your table design into source control etc.

    The rest of your DB code (SP's, FK indexes, Triggers etc) would be under source control anyway ;)

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

    If you are using management studio and have the query analyzer window open you can drag the table name to the query analyzer window and ... bingo! you get the table script. I've not tried this in SQL2008

    0 讨论(0)
  • 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
    
    0 讨论(0)
提交回复
热议问题