使用Query为现有表生成SQL创建脚本

cwe*_*ton 59 sql t-sql sql-server

我需要能够为SQL Server 2008中的现有表获取CREATE脚本.我假设我可以通过以某种方式查询sys.tables来执行此操作,但是这不会返回给我CREATE脚本数据.

Dev*_*art 128

这可能对你有所帮助.此脚本为任何表生成索引,FK,PK和公共结构.

例如 -

DDL:

CREATE TABLE [dbo].[WorkOut](
    [WorkOutID] [bigint] IDENTITY(1,1) NOT NULL,
    [TimeSheetDate] [datetime] NOT NULL,
    [DateOut] [datetime] NOT NULL,
    [EmployeeID] [int] NOT NULL,
    [IsMainWorkPlace] [bit] NOT NULL,
    [DepartmentUID] [uniqueidentifier] NOT NULL,
    [WorkPlaceUID] [uniqueidentifier] NULL,
    [TeamUID] [uniqueidentifier] NULL,
    [WorkShiftCD] [nvarchar](10) NULL,
    [WorkHours] [real] NULL,
    [AbsenceCode] [varchar](25) NULL,
    [PaymentType] [char](2) NULL,
    [CategoryID] [int] NULL,
    [Year]  AS (datepart(year,[TimeSheetDate])),
 CONSTRAINT [PK_WorkOut] PRIMARY KEY CLUSTERED 
(
    [WorkOutID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

ALTER TABLE [dbo].[WorkOut] ADD  
CONSTRAINT [DF__WorkOut__IsMainW__2C1E8537]  DEFAULT ((1)) FOR [IsMainWorkPlace]

ALTER TABLE [dbo].[WorkOut]  WITH CHECK ADD  CONSTRAINT [FK_WorkOut_Employee_EmployeeID] FOREIGN KEY([EmployeeID])
REFERENCES [dbo].[Employee] ([EmployeeID])

ALTER TABLE [dbo].[WorkOut] CHECK CONSTRAINT [FK_WorkOut_Employee_EmployeeID]
Run Code Online (Sandbox Code Playgroud)

查询:

DECLARE @table_name SYSNAME
SELECT @table_name = 'dbo.WorkOut'

DECLARE 
      @object_name SYSNAME
    , @object_id INT

SELECT 
      @object_name = '[' + s.name + '].[' + o.name + ']'
    , @object_id = o.[object_id]
FROM sys.objects o WITH (NOWAIT)
JOIN sys.schemas s WITH (NOWAIT) ON o.[schema_id] = s.[schema_id]
WHERE s.name + '.' + o.name = @table_name
    AND o.[type] = 'U'
    AND o.is_ms_shipped = 0

DECLARE @SQL NVARCHAR(MAX) = ''

;WITH index_column AS 
(
    SELECT 
          ic.[object_id]
        , ic.index_id
        , ic.is_descending_key
        , ic.is_included_column
        , c.name
    FROM sys.index_columns ic WITH (NOWAIT)
    JOIN sys.columns c WITH (NOWAIT) ON ic.[object_id] = c.[object_id] AND ic.column_id = c.column_id
    WHERE ic.[object_id] = @object_id
),
fk_columns AS 
(
     SELECT 
          k.constraint_object_id
        , cname = c.name
        , rcname = rc.name
    FROM sys.foreign_key_columns k WITH (NOWAIT)
    JOIN sys.columns rc WITH (NOWAIT) ON rc.[object_id] = k.referenced_object_id AND rc.column_id = k.referenced_column_id 
    JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id AND c.column_id = k.parent_column_id
    WHERE k.parent_object_id = @object_id
)
SELECT @SQL = 'CREATE TABLE ' + @object_name + CHAR(13) + '(' + CHAR(13) + STUFF((
    SELECT CHAR(9) + ', [' + c.name + '] ' + 
        CASE WHEN c.is_computed = 1
            THEN 'AS ' + cc.[definition] 
            ELSE UPPER(tp.name) + 
                CASE WHEN tp.name IN ('varchar', 'char', 'varbinary', 'binary', 'text')
                       THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(5)) END + ')'
                     WHEN tp.name IN ('nvarchar', 'nchar', 'ntext')
                       THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length / 2 AS VARCHAR(5)) END + ')'
                     WHEN tp.name IN ('datetime2', 'time2', 'datetimeoffset') 
                       THEN '(' + CAST(c.scale AS VARCHAR(5)) + ')'
                     WHEN tp.name = 'decimal' 
                       THEN '(' + CAST(c.[precision] AS VARCHAR(5)) + ',' + CAST(c.scale AS VARCHAR(5)) + ')'
                    ELSE ''
                END +
                CASE WHEN c.collation_name IS NOT NULL THEN ' COLLATE ' + c.collation_name ELSE '' END +
                CASE WHEN c.is_nullable = 1 THEN ' NULL' ELSE ' NOT NULL' END +
                CASE WHEN dc.[definition] IS NOT NULL THEN ' DEFAULT' + dc.[definition] ELSE '' END + 
                CASE WHEN ic.is_identity = 1 THEN ' IDENTITY(' + CAST(ISNULL(ic.seed_value, '0') AS CHAR(1)) + ',' + CAST(ISNULL(ic.increment_value, '1') AS CHAR(1)) + ')' ELSE '' END 
        END + CHAR(13)
    FROM sys.columns c WITH (NOWAIT)
    JOIN sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id
    LEFT JOIN sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id] AND c.column_id = cc.column_id
    LEFT JOIN sys.default_constraints dc WITH (NOWAIT) ON c.default_object_id != 0 AND c.[object_id] = dc.parent_object_id AND c.column_id = dc.parent_column_id
    LEFT JOIN sys.identity_columns ic WITH (NOWAIT) ON c.is_identity = 1 AND c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
    WHERE c.[object_id] = @object_id
    ORDER BY c.column_id
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, CHAR(9) + ' ')
    + ISNULL((SELECT CHAR(9) + ', CONSTRAINT [' + k.name + '] PRIMARY KEY (' + 
                    (SELECT STUFF((
                         SELECT ', [' + c.name + '] ' + CASE WHEN ic.is_descending_key = 1 THEN 'DESC' ELSE 'ASC' END
                         FROM sys.index_columns ic WITH (NOWAIT)
                         JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
                         WHERE ic.is_included_column = 0
                             AND ic.[object_id] = k.parent_object_id 
                             AND ic.index_id = k.unique_index_id     
                         FOR XML PATH(N''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, ''))
            + ')' + CHAR(13)
            FROM sys.key_constraints k WITH (NOWAIT)
            WHERE k.parent_object_id = @object_id 
                AND k.[type] = 'PK'), '') + ')'  + CHAR(13)
    + ISNULL((SELECT (
        SELECT CHAR(13) +
             'ALTER TABLE ' + @object_name + ' WITH' 
            + CASE WHEN fk.is_not_trusted = 1 
                THEN ' NOCHECK' 
                ELSE ' CHECK' 
              END + 
              ' ADD CONSTRAINT [' + fk.name  + '] FOREIGN KEY(' 
              + STUFF((
                SELECT ', [' + k.cname + ']'
                FROM fk_columns k
                WHERE k.constraint_object_id = fk.[object_id]
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
               + ')' +
              ' REFERENCES [' + SCHEMA_NAME(ro.[schema_id]) + '].[' + ro.name + '] ('
              + STUFF((
                SELECT ', [' + k.rcname + ']'
                FROM fk_columns k
                WHERE k.constraint_object_id = fk.[object_id]
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
               + ')'
            + CASE 
                WHEN fk.delete_referential_action = 1 THEN ' ON DELETE CASCADE' 
                WHEN fk.delete_referential_action = 2 THEN ' ON DELETE SET NULL'
                WHEN fk.delete_referential_action = 3 THEN ' ON DELETE SET DEFAULT' 
                ELSE '' 
              END
            + CASE 
                WHEN fk.update_referential_action = 1 THEN ' ON UPDATE CASCADE'
                WHEN fk.update_referential_action = 2 THEN ' ON UPDATE SET NULL'
                WHEN fk.update_referential_action = 3 THEN ' ON UPDATE SET DEFAULT'  
                ELSE '' 
              END 
            + CHAR(13) + 'ALTER TABLE ' + @object_name + ' CHECK CONSTRAINT [' + fk.name  + ']' + CHAR(13)
        FROM sys.foreign_keys fk WITH (NOWAIT)
        JOIN sys.objects ro WITH (NOWAIT) ON ro.[object_id] = fk.referenced_object_id
        WHERE fk.parent_object_id = @object_id
        FOR XML PATH(N''), TYPE).value('.', 'NVARCHAR(MAX)')), '')
    + ISNULL(((SELECT
         CHAR(13) + 'CREATE' + CASE WHEN i.is_unique = 1 THEN ' UNIQUE' ELSE '' END 
                + ' NONCLUSTERED INDEX [' + i.name + '] ON ' + @object_name + ' (' +
                STUFF((
                SELECT ', [' + c.name + ']' + CASE WHEN c.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END
                FROM index_column c
                WHERE c.is_included_column = 0
                    AND c.index_id = i.index_id
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ')'  
                + ISNULL(CHAR(13) + 'INCLUDE (' + 
                    STUFF((
                    SELECT ', [' + c.name + ']'
                    FROM index_column c
                    WHERE c.is_included_column = 1
                        AND c.index_id = i.index_id
                    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ')', '')  + CHAR(13)
        FROM sys.indexes i WITH (NOWAIT)
        WHERE i.[object_id] = @object_id
            AND i.is_primary_key = 0
            AND i.[type] = 2
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
    ), '')

PRINT @SQL
--EXEC sys.sp_executesql @SQL
Run Code Online (Sandbox Code Playgroud)

输出:

CREATE TABLE [dbo].[WorkOut]
(
      [WorkOutID] BIGINT NOT NULL IDENTITY(1,1)
    , [TimeSheetDate] DATETIME NOT NULL
    , [DateOut] DATETIME NOT NULL
    , [EmployeeID] INT NOT NULL
    , [IsMainWorkPlace] BIT NOT NULL DEFAULT((1))
    , [DepartmentUID] UNIQUEIDENTIFIER NOT NULL
    , [WorkPlaceUID] UNIQUEIDENTIFIER NULL
    , [TeamUID] UNIQUEIDENTIFIER NULL
    , [WorkShiftCD] NVARCHAR(10) COLLATE Cyrillic_General_CI_AS NULL
    , [WorkHours] REAL NULL
    , [AbsenceCode] VARCHAR(25) COLLATE Cyrillic_General_CI_AS NULL
    , [PaymentType] CHAR(2) COLLATE Cyrillic_General_CI_AS NULL
    , [CategoryID] INT NULL
    , [Year] AS (datepart(year,[TimeSheetDate]))
    , CONSTRAINT [PK_WorkOut] PRIMARY KEY ([WorkOutID] ASC)
)

ALTER TABLE [dbo].[WorkOut] WITH CHECK ADD CONSTRAINT [FK_WorkOut_Employee_EmployeeID] FOREIGN KEY([EmployeeID]) REFERENCES [dbo].[Employee] ([EmployeeID])
ALTER TABLE [dbo].[WorkOut] CHECK CONSTRAINT [FK_WorkOut_Employee_EmployeeID]

CREATE NONCLUSTERED INDEX [IX_WorkOut_WorkShiftCD_AbsenceCode] ON [dbo].[WorkOut] ([WorkShiftCD] ASC, [AbsenceCode] ASC)
INCLUDE ([WorkOutID], [WorkHours])
Run Code Online (Sandbox Code Playgroud)

另请查看这篇文章 -

如何为现有表生成CREATE TABLE脚本:第1部分

  • 没问题:)我明天会添加对计算列的支持. (4认同)
  • 请参阅更新的答案(添加对计算列的支持,修复列的顺序并加快查询速度). (4认同)
  • 你应该使用 `quotename()` 而不是 `'[' + thing + ']'` (3认同)
  • @NeelamSharma:如果种子值或增量值超过 char(1),则在处理标识列时,脚本会存在错误,如果您以负数或大于个位数播种/增量,则会出现这种情况。对我有用的是在 SELECT 的最后一个 CASE 语句中用 varchar 替换 CHAR(1) (2认同)

Ste*_*ton 16

是指您希望创建生成CREATE脚本的TSQL脚本,还是使用SQL SERVER Management Studio中的管理工具生成Create脚本?

如果是后者,则只需右键单击一个表,然后选择脚本表为 - >创建到 - >新查询窗口.

如果要编写整个数据库脚本,请右键单击数据库并选择"任务" - >"生成脚本...",然后按照向导进行操作

否则就是从各种系统表中选择各种有趣的东西.

  • 我实际上正在寻找一种以语法方式获取这些内容的方法,因为这将从 .NET 应用程序运行以生成主脚本文件。 (2认同)

ild*_*nny 7

首先,我喜欢 devart 编写的脚本,我想使用它,但我发现了一些限制,所以我决定改进它:

  • 我修复了将脚本限制为 4000 个字符的错误(仍然有可能某些疯狂的表仍然超出限制)
  • 我修复了表使用非聚集主键时的错误/限制
  • 我用 quotename 替换了 '['
  • 我添加了默认约束的名称
  • 我改变了逻辑来识别源表
  • 我添加了删除并重新创建表及其 FK 的可能性
  • 我添加了生成特定属性的可能性
  • 我添加了对表压缩的支持
  • 我添加了为任意数量的表生成脚本的可能性
  • 我修复了打印结果时 4000 varchar() 的限制
  • 我将 '' 替换为 N''
  • 我添加了在执行期间生成消息的选项,因为我的最终脚本(带有插入)可能需要很长时间,以至于我想知道它在做什么
  • 我添加了“插入”的生成

我没有时间正确测试它,我只在 SQL Server 2012/4 上测试了它

下一个版本将改变 FK 的生成,因为它们需要在末尾添加。否则他们可能会失败。

任何评论将不胜感激。

set transaction isolation level read uncommitted;
SET NOCOUNT ON;
SET STATISTICS TIME OFF;
SET STATISTICS IO OFF;

-- http://stackoverflow.com/questions/12639948/sql-nvarchar-and-varchar-limits
--NB: Crazy table can still have truncation at 4000 because of unexpected number of indexes or other very long list of columns/defaults etc
-- triggers are not supported
-- xml indexes are not supported

DECLARE @Tables table(id int identity(1,1), [name] sysname);
insert into @Tables([name])
values
   ('<yourSchema>.<youTableName>')
  ,('<yourSchema2>.<youTableName2>')
;
DECLARE @object_id                          int;
DECLARE @SourceDatabase nvarchar(max) = N'SourceTest'; --this is used only by the insert 
DECLARE @TargetDatabase nvarchar(max) = N'DescTest';   --this is used only by the insert and USE <DBName>

--- options ---
DECLARE @UseTransaction                     bit = 0; 
DECLARE @GenerateUseDatabase                bit = 0;
DECLARE @GenerateFKs                        bit = 1;
DECLARE @GenerateIdentity                   bit = 1;
DECLARE @GenerateCollation                  bit = 0;
DECLARE @GenerateCreateTable                bit = 1;
DECLARE @GenerateIndexes                    bit = 1;
DECLARE @GenerateConstraints                bit = 1;
DECLARE @GenerateKeyConstraints             bit = 1;
DECLARE @GenerateConstraintNameOfDefaults   bit = 1;
DECLARE @GenerateDropIfItExists             bit = 1;
DECLARE @GenerateDropFKIfItExists           bit = 0;
DECLARE @GenerateDelete                     bit = 0;
DECLARE @GenerateInsertInto                 bit = 0;
DECLARE @GenerateIdentityInsert             int = 0; --0 ignore set,but add column; 1 generate; 2 ignore set and column
DECLARE @GenerateSetNoCount                 int = 2; --0 ignore set,1=set on, 2=set off 
DECLARE @GenerateMessages                   bit = 1; --print with no wait
DECLARE @GenerateDataCompressionOptions     bit = 1; --TODO: generates the compression option only of the table, not the indexes
                                                    --NB: the compression options reflects the design value.
                                                    --The actual compression of a the page is saved here
                                                    --SELECT * from sys.dm_db_database_page_allocations(DB_ID(), @object_ID, 0, 1, 'DETAILED')

-----------------------------------------------------------------------------
------------------------------------------------------------------------------
--- Let's play
DECLARE @DataTypeSpacer                     int = 45; --this is just to improve the formatting of the script ...
DECLARE @name                               sysname;
DECLARE @SQL                                NVARCHAR(MAX) = N''

DECLARE db_cursor CURSOR FOR SELECT [name] from @Tables
OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @name  

WHILE @@FETCH_STATUS = 0  
BEGIN  
    SET @object_id = object_ID(@name)
    goto CreateScript;
backFromCreateScript:
    FETCH NEXT FROM db_cursor INTO @name 
END 
CLOSE db_cursor  
DEALLOCATE db_cursor 
return;

CreateScript:

DECLARE @CR NVARCHAR(max) = NCHAR(13);
DECLARE @TB NVARCHAR(max) = NCHAR(9);
DECLARE @CurrentIndent nvarchar(max) = ''

;WITH index_column AS 
(
    SELECT 
        ic.[object_id]
        , ic.index_id
        , ic.is_descending_key
        , ic.is_included_column
        , c.name
    FROM sys.index_columns ic WITH (NOWAIT)
    JOIN sys.columns c WITH (NOWAIT) ON ic.[object_id] = c.[object_id] AND ic.column_id = c.column_id
    WHERE ic.[object_id] = @object_id
),
fk_columns AS 
(
    SELECT 
        k.constraint_object_id
        , cname = c.name
        , rcname = rc.name
    FROM sys.foreign_key_columns k WITH (NOWAIT)
    JOIN sys.columns rc WITH (NOWAIT) ON rc.[object_id] = k.referenced_object_id AND rc.column_id = k.referenced_column_id 
    JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id AND c.column_id = k.parent_column_id
    WHERE k.parent_object_id = @object_id and @GenerateFKs = 1
)
SELECT @SQL = 

    --------------------  USE DATABASE   --------------------------------------------------------------------------------------------------
        CAST(
            CASE WHEN @GenerateUseDatabase = 1
            THEN N'USE ' + @TargetDatabase + N';' + @CR
            ELSE N'' END 
        as nvarchar(max))
        +
    --------------------  SET NOCOUNT   --------------------------------------------------------------------------------------------------
        CAST(
            CASE @GenerateSetNoCount 
            WHEN 1 THEN N'SET NOCOUNT ON;' + @CR
            WHEN 2 THEN N'SET NOCOUNT OFF;' + @CR
            ELSE N'' END 
        as nvarchar(max))
        +
    --------------------  USE TRANSACTION  --------------------------------------------------------------------------------------------------
        CAST(
            CASE WHEN @UseTransaction = 1
            THEN 
                N'SET XACT_ABORT ON' + @CR
                + N'BEGIN TRY' + @CR
                + N'BEGIN TRAN' + @CR
            ELSE N'' END 
        as nvarchar(max))
        +
    --------------------  DROP SYNONYM   --------------------------------------------------------------------------------------------------
        CASE WHEN @GenerateDropIfItExists = 1
        THEN 
            CAST(
                    N'IF OBJECT_ID(''' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N''',''SN'') IS NOT NULL DROP SYNONYM ' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N';' + @CR 
            as nvarchar(max))
        ELSE 
            CAST(
                    N'' 
            as nvarchar(max))
        END 
        +
    --------------------  DROP IS Exists --------------------------------------------------------------------------------------------------
        CASE WHEN @GenerateDropIfItExists = 1
        THEN 
            --Drop table if exists
            CAST(
                N'IF OBJECT_ID(''' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N''',''U'') IS NOT NULL DROP TABLE ' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N';' + @CR 
            as nvarchar(max))
            + @CR
        ELSE N'' END 
        +
    --------------------  DROP IS Exists --------------------------------------------------------------------------------------------------
        CAST((CASE WHEN @GenerateMessages = 1 and @GenerateDropFKIfItExists = 1 THEN 
            N'RAISERROR(''DROP CONSTRAINTS OF %s'',10,1, ''' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N''') WITH NOWAIT;' + @CR            
        ELSE N'' END) as nvarchar(max)) 
        +
        CASE WHEN @GenerateDropFKIfItExists = 1
        THEN 
            --Drop foreign keys
            ISNULL(((
                SELECT 
                    CAST(
                        N'ALTER TABLE ' + quotename(s.name) + N'.' + quotename(t.name) + N' DROP CONSTRAINT ' + RTRIM(f.name) + N';' + @CR
                    as nvarchar(max))
                FROM sys.tables t
                INNER JOIN sys.foreign_keys f ON f.parent_object_id = t.object_id
                INNER JOIN sys.schemas      s ON s.schema_id = f.schema_id
                WHERE f.referenced_object_id = @object_id
                FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'))
            ,N'') + @CR
        ELSE N'' END 
    +
    --------------------- CREATE TABLE -----------------------------------------------------------------------------------------------------------------
    CAST((CASE WHEN @GenerateMessages = 1 THEN 
        N'RAISERROR(''CREATE TABLE %s'',10,1, ''' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N''') WITH NOWAIT;' + @CR           
    ELSE N'' END) as nvarchar(max)) 
    +
    CASE WHEN @GenerateCreateTable = 1 THEN 
        CAST(
            N'CREATE TABLE ' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + @CR + N'(' + @CR + STUFF((
            SELECT 
                CAST(
                    @TB + N',' + quotename(c.name) + N' ' + ISNULL(replicate(' ',@DataTypeSpacer - len(quotename(c.name))),'')  --isnull(replicate) then len(quotename(c.name)) > @DataTypeSpacer
                    +  
                    CASE WHEN c.is_computed = 1
                        THEN N' AS ' + cc.[definition] 
                        ELSE UPPER(tp.name) + 
                            CASE WHEN tp.name IN (N'varchar', N'char', N'varbinary', N'binary', N'text')
                                    THEN N'(' + CASE WHEN c.max_length = -1 THEN N'MAX' ELSE CAST(c.max_length AS NVARCHAR(5)) END + N')'
                                    WHEN tp.name IN (N'nvarchar', N'nchar', N'ntext')
                                    THEN N'(' + CASE WHEN c.max_length = -1 THEN N'MAX' ELSE CAST(c.max_length / 2 AS NVARCHAR(5)) END + N')'
                                    WHEN tp.name IN (N'datetime2', N'time2', N'datetimeoffset') 
                                    THEN N'(' + CAST(c.scale AS NVARCHAR(5)) + N')'
                                    WHEN tp.name = N'decimal' 
                                    THEN N'(' + CAST(c.[precision] AS NVARCHAR(5)) + N',' + CAST(c.scale AS NVARCHAR(5)) + N')'
                                ELSE N''
                            END +
                            CASE WHEN c.collation_name IS NOT NULL and @GenerateCollation = 1 THEN N' COLLATE ' + c.collation_name ELSE N'' END +
                            CASE WHEN c.is_nullable = 1 THEN N' NULL' ELSE N' NOT NULL' END +
                            CASE WHEN dc.[definition] IS NOT NULL THEN CASE WHEN @GenerateConstraintNameOfDefaults = 1 THEN N' CONSTRAINT ' + quotename(dc.name) ELSE N'' END + N' DEFAULT' + dc.[definition] ELSE N'' END + 
                            CASE WHEN ic.is_identity = 1 and @GenerateIdentity = 1 THEN N' IDENTITY(' + CAST(ISNULL(ic.seed_value, N'0') AS NCHAR(1)) + N',' + CAST(ISNULL(ic.increment_value, N'1') AS NCHAR(1)) + N')' ELSE N'' END 
                    END + @CR
                AS nvarchar(Max))
            FROM sys.columns c WITH (NOWAIT)
                INNER JOIN sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id
                LEFT JOIN sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id] AND c.column_id = cc.column_id
                LEFT JOIN sys.default_constraints dc WITH (NOWAIT) ON c.default_object_id != 0 AND c.[object_id] = dc.parent_object_id AND c.column_id = dc.parent_column_id
                LEFT JOIN sys.identity_columns ic WITH (NOWAIT) ON c.is_identity = 1 AND c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
            WHERE c.[object_id] = @object_id
            ORDER BY c.column_id
            FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, @TB + N' ')
    as nvarchar(max))
    ELSE 
        CAST('' as nvarchar(max)) 
    end 
    + 
    ---------------------- Key Constraints ----------------------------------------------------------------
    CAST(
        case when @GenerateKeyConstraints <> 1 THEN N'' ELSE 
            ISNULL((SELECT @TB + N', CONSTRAINT ' + quotename(k.name) + N' PRIMARY KEY ' + ISNULL(kidx.type_desc, N'') + N'(' + 
                        (SELECT STUFF((
                            SELECT N', ' + quotename(c.name) + N' ' + CASE WHEN ic.is_descending_key = 1 THEN N'DESC' ELSE N'ASC' END
                            FROM sys.index_columns ic WITH (NOWAIT)
                            JOIN sys.columns c WITH (NOWAIT) ON c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id
                            WHERE ic.is_included_column = 0
                                AND ic.[object_id] = k.parent_object_id 
                                AND ic.index_id = k.unique_index_id     
                            FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N''))
                + N')' + @CR
                FROM sys.key_constraints k WITH (NOWAIT) LEFT JOIN sys.indexes kidx ON
                    k.parent_object_id = kidx.object_id and k.unique_index_id = kidx.index_id
                WHERE k.parent_object_id = @object_id 
                    AND k.[type] = N'PK'), N'') + N')'  + @CR
        END 
    as nvarchar(max))
    +
    CAST(
    CASE 
        WHEN 
            @GenerateDataCompressionOptions = 1 
            AND 
            (SELECT top 1 data_compression_desc from sys.partitions where object_ID = @object_id and index_id = 1) <> N'NONE'
        THEN 
            N'WITH (DATA_COMPRESSION=' + (SELECT top 1 data_compression_desc from sys.partitions where object_ID = @object_id and index_id = 1) + N')' + @CR
        ELSE
            N'' + @CR
    END as nvarchar(max))
    + 
    --------------------- FOREIGN KEYS -----------------------------------------------------------------------------------------------------------------
    CAST((CASE WHEN @GenerateMessages = 1 and @GenerateDropFKIfItExists = 1 THEN 
        N'RAISERROR(''CREATING FK OF  %s'',10,1, ''' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N''') WITH NOWAIT;' + @CR            
    ELSE N'' END) as nvarchar(max)) 
    +
    CAST(
        ISNULL((SELECT (
            SELECT @CR +
            N'ALTER TABLE ' + + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + + N' WITH' 
            + CASE WHEN fk.is_not_trusted = 1 
                THEN N' NOCHECK' 
                ELSE N' CHECK' 
            END + 
            N' ADD CONSTRAINT ' + quotename(fk.name)  + N' FOREIGN KEY(' 
            + STUFF((
                SELECT N', ' + quotename(k.cname) + N''
                FROM fk_columns k
                WHERE k.constraint_object_id = fk.[object_id]
                FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'')
            + N')' +
            N' REFERENCES ' + quotename(SCHEMA_NAME(ro.[schema_id])) + N'.' + quotename(ro.name) + N' ('
            + STUFF((
                SELECT N', ' + quotename(k.rcname) + N''
                FROM fk_columns k
                WHERE k.constraint_object_id = fk.[object_id]
                FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'')
            + N')'
            + CASE 
                WHEN fk.delete_referential_action = 1 THEN N' ON DELETE CASCADE' 
                WHEN fk.delete_referential_action = 2 THEN N' ON DELETE SET NULL'
                WHEN fk.delete_referential_action = 3 THEN N' ON DELETE SET DEFAULT' 
                ELSE N'' 
            END
            + CASE 
                WHEN fk.update_referential_action = 1 THEN N' ON UPDATE CASCADE'
                WHEN fk.update_referential_action = 2 THEN N' ON UPDATE SET NULL'
                WHEN fk.update_referential_action = 3 THEN N' ON UPDATE SET DEFAULT'  
                ELSE N'' 
            END 
            + @CR + N'ALTER TABLE ' + + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + + N' CHECK CONSTRAINT ' + quotename(fk.name)  + N'' + @CR
        FROM sys.foreign_keys fk WITH (NOWAIT)
        JOIN sys.objects ro WITH (NOWAIT) ON ro.[object_id] = fk.referenced_object_id
        WHERE fk.parent_object_id = @object_id
        FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)')), N'')
    as nvarchar(max))
    + 
    --------------------- INDEXES ----------------------------------------------------------------------------------------------------------
    CAST((CASE WHEN @GenerateMessages = 1 and @GenerateIndexes = 1 THEN 
        N'RAISERROR(''CREATING INDEXES OF  %s'',10,1, ''' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N''') WITH NOWAIT;' + @CR           
    ELSE N'' END) as nvarchar(max)) 
    +
    case when @GenerateIndexes = 1 THEN 
        CAST(
            ISNULL(((SELECT
                @CR + N'CREATE' + CASE WHEN i.is_unique = 1 THEN N' UNIQUE ' ELSE N' ' END 
                        + i.type_desc + N' INDEX ' + quotename(i.name) + N' ON ' + + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + + N' (' +
                        STUFF((
                        SELECT N', ' + quotename(c.name) + N'' + CASE WHEN c.is_descending_key = 1 THEN N' DESC' ELSE N' ASC' END
                        FROM index_column c
                        WHERE c.is_included_column = 0
                            AND c.index_id = i.index_id
                        FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'') + N')'  
                        + ISNULL(@CR + N'INCLUDE (' + 
                            STUFF((
                            SELECT N', ' + quotename(c.name) + N''
                            FROM index_column c
                            WHERE c.is_included_column = 1
                                AND c.index_id = i.index_id
                            FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)'), 1, 2, N'') + N')', N'')  + @CR
                FROM sys.indexes i WITH (NOWAIT)
                WHERE i.[object_id] = @object_id
                    AND i.is_primary_key = 0
                    AND i.[type] in (1,2)
                    and @GenerateIndexes = 1
                FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)')
            ), N'')
        as nvarchar(max))
    ELSE 
        CAST(N'' as nvarchar(max))
    END 
    +
    ------------------------  @GenerateDelete     ----------------------------------------------------------
    CAST((CASE WHEN @GenerateMessages = 1 and @GenerateDelete = 1 THEN 
        N'RAISERROR(''TRUNCATING  %s'',10,1, ''' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N''') WITH NOWAIT;' + @CR            
    ELSE N'' END) as nvarchar(max)) 
    +
    CASE WHEN @GenerateDelete = 1 THEN
        CAST(
            (CASE WHEN exists (SELECT * FROM sys.foreign_keys WHERE referenced_object_id = @object_id) THEN 
                N'DELETE FROM ' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N';' + @CR
            ELSE
                N'TRUNCATE TABLE ' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N';' + @CR
            END)
        AS NVARCHAR(max))
    ELSE 
        CAST(N'' as nvarchar(max))
    END 
    +
    ------------------------- @GenerateInsertInto ----------------------------------------------------------
    CAST((CASE WHEN @GenerateMessages = 1 and @GenerateDropFKIfItExists = 1 THEN 
        N'RAISERROR(''INSERTING INTO  %s'',10,1, ''' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N''') WITH NOWAIT;' + @CR            
    ELSE N'' END) as nvarchar(max)) 
    +
    CASE WHEN @GenerateInsertInto = 1
    THEN 
        CAST(
                CASE WHEN EXISTS (SELECT * from sys.columns c where c.[object_id] = @object_id and is_identity = 1) AND @GenerateIdentityInsert = 1 THEN 
                    N'SET IDENTITY_INSERT ' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N' ON;' + @CR
                ELSE 
                    CAST('' AS nvarchar(max))
                END 
   


小智 5

“最简单的方法是使用 SQL Management Studio 的内置功能”\n但是...\n我已经用一个函数和几个过程解决了这个问题。\n例如,获取名为 \' 的表的创建表table_name\',您只需执行名为 sp_ppinScriptTabla 的过程:

\n\n
Exec sp_ppinScriptTabla \'table_name\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是tsql脚本代码:

\n\n
Use Master\nGO\n\nCreate Function sp_ppinTipoLongitud\n(\n    @xtype int,\n    @length int,\n    @isnullable int\n)\nReturns Varchar(512)\nAs \nBegin\n    -- Funci\xc3\xb3n que a partir de un tipo de datos y una logitud, devuelve el texto del tipo.\n    -- Por ejemplo: para xtype=varchar y length=10 devolver\xc3\xa1 "varchar(10)"\n    Declare @ret varchar(512)\n    Set @ret = \'\'\n\n    Select @ret = t.name +\n    Case When name in (\'varchar\', \'nvarchar\', \'char\', \'nchar\') Then \'(\' + Convert(varchar, @length) + \')\' Else \'\' End + \' \' +\n    Case @isnullable When 1 Then \'NULL\' Else \'NOT NULL\' End\n    From systypes t \n    Where t.xtype = @xtype\n\n    Return @ret\nEnd\nGO\n\nCreate Procedure sp_ppinScriptLlavesForaneas\n(\n    @vchTabla sysname,\n    @vchResultado varchar(8000) output\n)\nAS \nBegin\n\n    DECLARE @tmpFK table(\n        TablaF sysname,\n        TablaR sysname,\n        ColF sysname,\n        ColR sysname,\n        FKName sysname)\n\n    -- obtengo las llaves foraneas en @vchForeign\n    Declare @vchForeign varchar(8000), @FKName sysname, @vchColumnasF varchar(4000), @vchColumnasR varchar(4000), @ColF sysname, @ColR sysname\n    Declare @vchTemp varchar(1000), @TablaR sysname\n\n    Insert into @tmpFK\n    Select TablaF.name AS TablaF, TablaR.name AS TablaR, ColF.name AS ColF, ColR.name AS ColR, ofk.name AS FKName\n    From sysforeignkeys fk, sysobjects ofk, sysobjects TablaF, sysobjects TablaR, \n    syscolumns ColF, syscolumns ColR\n    Where TablaF.name = @vchTabla\n    And ofk.id = fk.constid\n    And TablaF.id = fk.fkeyid\n    And TablaR.id = fk.rkeyid\n    And ColF.id = TablaF.id And ColF.colid = fk.fkey\n    And ColR.id = TablaR.id And ColR.colid = fk.rkey\n    order by FKName\n\n    Set @vchForeign = \'\'\n    While Exists ( Select * From @tmpFK )\n    Begin\n        Select Top 1 @FKName = FKName From @tmpFK\n        Set @vchColumnasF = \'\'\n        Set @vchColumnasR = \'\'\n        While Exists ( Select * From @tmpFK Where FKName = @FKName )\n        Begin\n            Select Top 1 @ColF = ColF, @ColR = ColR, @TablaR = TablaR From @tmpFK Where FKName = @FKName\n            Delete From @tmpFK Where ColF = @ColF And ColR = @ColR And TablaR = @TablaR And FKName = @FKName\n            Set @vchColumnasF = @vchColumnasF + @ColF + \', \'\n            Set @vchColumnasR = @vchColumnasR + @ColR + \', \'\n        End\n\n        Set @vchColumnasF = LEFT(@vchColumnasF, LEN(@vchColumnasF) - 1)\n        Set @vchColumnasR = LEFT(@vchColumnasR, LEN(@vchColumnasR) - 1)\n        Set @vchTemp = \'Constraint \' + @FKName + \' Foreign Key (\' + @vchColumnasF + \') \'\n        Set @vchTemp = @vchTemp + \'References \' + @TablaR + \' (\' + @vchColumnasR + \')\'\n        Set @vchForeign = @vchForeign + char(9) + @vchTemp + \',\' + char(13) \n    End\n\n    Select @vchResultado = Case When Len(@vchForeign) >=2 Then Left(@vchForeign, Len(@vchForeign) - 2) Else @vchForeign End\nEnd\nGO\n\nCreate Procedure sp_ppinScriptTabla\n(\n    @vchTabla sysname\n)\nAS\n\nSet nocount on\n\n-- Obtengo las foreign keys\nDeclare @foreign varchar(8000)\nExec sp_ppinScriptLlavesForaneas @vchTabla, @foreign output\n\n-- SELECT que devuelve el script de Create Table de la tabla\nSelect \'Create \' + \nCase o.xtype When \'U\' Then \'Table\' When \'P\' Then \'Procedure\' Else \'??\' End + \' \' +\n@vchTabla + char(13) + \'(\'\nFrom sysobjects o\nWhere o.name = @vchTabla\nUnion all\n-- Campos + identitys + DEFAULTS\nselect char(9) + c.name + \' \' +                                 -- Nombre\ndbo.sp_ppinTipoLongitud(t.xtype, c.length, c.isnullable) +          -- Tipo(longitud)\nCase When c.colstat & 1 = 1                                     -- Identity (si aplica)\n    Then \' Identity(\' + convert(varchar, ident_seed(@vchTabla)) + \',\' + Convert(varchar, ident_incr(@vchTabla)) + \')\' \n    Else \'\' \nEnd + \nCase When not od.name is null                                   -- Defaults (si aplica)\n    Then \' Constraint \' + od.name + \' Default \' + replace(replace(cd.text, \'((\', \'(\'), \'))\', \')\')\n    Else \'\'\nEnd + \', \'\nfrom sysobjects o, syscolumns c\nLEFT OUTER JOIN sysobjects od On od.id = c.cdefault LEFT OUTER join syscomments cd On cd.id = od.id, \nsystypes t\nwhere o.id = object_id(@vchTabla)\nand o.id = c.id\nand c.xtype = t.xtype\nUnion all\n-- Primary Keys y Unique keys\nselect char(9) + \'Constraint \' + o.name + \' \' +\nCase o.xtype When \'PK\' Then \'Primary Key\' Else \'Unique\' End + \' \' +\ndbo.sp_ppinCamposIndice (db_name(), @vchTabla, i.indid) + \', \'\nfrom sysobjects o, sysindexes i\nwhere o.parent_obj = object_id(@vchTabla)\nand o.xtype in (\'PK\',\'UQ\')\nand i.id = o.parent_obj\nand o.name = i.name\nUnion all\n-- Check constraints\nselect char(9) + \'Constraint \' + o.name + \' Check \' + c.text + \', \'\nfrom sysobjects o, syscomments c\nwhere o.parent_obj = object_id(@vchTabla)\nand o.xtype in (\'C\')\nand o.id = c.id\nUnion all\n-- Foreign keys\nSelect @foreign\nUnion all\nSelect \')\'\n\nSet nocount off\nGO\n
Run Code Online (Sandbox Code Playgroud)\n


小智 5

我意识到这个问题已经过时了,但是最近我刚刚开始进行搜索,所以我想我会发布上述答案的替代方案.

如果您希望create在.Net中以编程方式生成脚本,我强烈建议您查看服务器管理对象(SMO)或分布式管理对象(DMO) - 具体取决于您使用的SQL Server版本(前者是2005 +,后者2000).使用这些库,脚本编写表非常简单:

Server server      = new Server(".");
Database northwind = server.Databases["Northwind"];
Table categories   = northwind.Tables["Categories"];

StringCollection script = categories.Script();
string[] scriptArray    = new string[script.Count];

script.CopyTo(scriptArray, 0);
Run Code Online (Sandbox Code Playgroud)

是一篇包含更多信息的博客文章.