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


77

我正在尝试获取SQL Server 2008中现有表的CREATE脚本。我假设我可以通过以某种方式查询sys.tables来做到这一点,但是这并没有返回CREATE脚本数据。


CREATE TABLE或所有其他行李,如索引,关系,检查约束,触发器(点火顺序保存!),...?一旦开始添加关系,创建的顺序就变得至关重要。
HABO

Answers:


164

可能对您有帮助。该脚本为任何表生成索引,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]

查询:

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

输出:

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])

另请查看这篇文章-

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


5
没问题:)我明天添加对计算列的支持。
Devart

1
另外,我注意到这些列是按字母顺序重新排列的,没有保持其原始顺序。
enb081

5
请查看更新后的答案(增加了对计算列的支持,修复了列的顺序并加快了查询速度)。
Devart

1
@Devart我已经更新我的查询,请参阅DDL更新的问题:stackoverflow.com/questions/38998330/...
尼拉姆夏尔马

3
您应该使用quotename()的,而不是'[' + thing + ']'
DJL

18

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

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

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

否则,需要从各种系统表中选择各种有趣的东西。


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

谢谢!我知道有一种方法可以将所有创建脚本都放在一个地方,您的回答指出了我要找出的地方。
Tschallacka

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);

是具有更多信息的博客文章。



3

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

Exec sp_ppinScriptTabla 'table_name'

这是tsql脚本代码:

Use Master
GO

Create Function sp_ppinTipoLongitud
(
    @xtype int,
    @length int,
    @isnullable int
)
Returns Varchar(512)
As 
Begin
    -- Función que a partir de un tipo de datos y una logitud, devuelve el texto del tipo.
    -- Por ejemplo: para xtype=varchar y length=10 devolverá "varchar(10)"
    Declare @ret varchar(512)
    Set @ret = ''

    Select @ret = t.name +
    Case When name in ('varchar', 'nvarchar', 'char', 'nchar') Then '(' + Convert(varchar, @length) + ')' Else '' End + ' ' +
    Case @isnullable When 1 Then 'NULL' Else 'NOT NULL' End
    From systypes t 
    Where t.xtype = @xtype

    Return @ret
End
GO

Create Procedure sp_ppinScriptLlavesForaneas
(
    @vchTabla sysname,
    @vchResultado varchar(8000) output
)
AS 
Begin

    DECLARE @tmpFK table(
        TablaF sysname,
        TablaR sysname,
        ColF sysname,
        ColR sysname,
        FKName sysname)

    -- obtengo las llaves foraneas en @vchForeign
    Declare @vchForeign varchar(8000), @FKName sysname, @vchColumnasF varchar(4000), @vchColumnasR varchar(4000), @ColF sysname, @ColR sysname
    Declare @vchTemp varchar(1000), @TablaR sysname

    Insert into @tmpFK
    Select TablaF.name AS TablaF, TablaR.name AS TablaR, ColF.name AS ColF, ColR.name AS ColR, ofk.name AS FKName
    From sysforeignkeys fk, sysobjects ofk, sysobjects TablaF, sysobjects TablaR, 
    syscolumns ColF, syscolumns ColR
    Where TablaF.name = @vchTabla
    And ofk.id = fk.constid
    And TablaF.id = fk.fkeyid
    And TablaR.id = fk.rkeyid
    And ColF.id = TablaF.id And ColF.colid = fk.fkey
    And ColR.id = TablaR.id And ColR.colid = fk.rkey
    order by FKName

    Set @vchForeign = ''
    While Exists ( Select * From @tmpFK )
    Begin
        Select Top 1 @FKName = FKName From @tmpFK
        Set @vchColumnasF = ''
        Set @vchColumnasR = ''
        While Exists ( Select * From @tmpFK Where FKName = @FKName )
        Begin
            Select Top 1 @ColF = ColF, @ColR = ColR, @TablaR = TablaR From @tmpFK Where FKName = @FKName
            Delete From @tmpFK Where ColF = @ColF And ColR = @ColR And TablaR = @TablaR And FKName = @FKName
            Set @vchColumnasF = @vchColumnasF + @ColF + ', '
            Set @vchColumnasR = @vchColumnasR + @ColR + ', '
        End

        Set @vchColumnasF = LEFT(@vchColumnasF, LEN(@vchColumnasF) - 1)
        Set @vchColumnasR = LEFT(@vchColumnasR, LEN(@vchColumnasR) - 1)
        Set @vchTemp = 'Constraint ' + @FKName + ' Foreign Key (' + @vchColumnasF + ') '
        Set @vchTemp = @vchTemp + 'References ' + @TablaR + ' (' + @vchColumnasR + ')'
        Set @vchForeign = @vchForeign + char(9) + @vchTemp + ',' + char(13) 
    End

    Select @vchResultado = Case When Len(@vchForeign) >=2 Then Left(@vchForeign, Len(@vchForeign) - 2) Else @vchForeign End
End
GO

Create Procedure sp_ppinScriptTabla
(
    @vchTabla sysname
)
AS

Set nocount on

-- Obtengo las foreign keys
Declare @foreign varchar(8000)
Exec sp_ppinScriptLlavesForaneas @vchTabla, @foreign output

-- SELECT que devuelve el script de Create Table de la tabla
Select 'Create ' + 
Case o.xtype When 'U' Then 'Table' When 'P' Then 'Procedure' Else '??' End + ' ' +
@vchTabla + char(13) + '('
From sysobjects o
Where o.name = @vchTabla
Union all
-- Campos + identitys + DEFAULTS
select char(9) + c.name + ' ' +                                 -- Nombre
dbo.sp_ppinTipoLongitud(t.xtype, c.length, c.isnullable) +          -- Tipo(longitud)
Case When c.colstat & 1 = 1                                     -- Identity (si aplica)
    Then ' Identity(' + convert(varchar, ident_seed(@vchTabla)) + ',' + Convert(varchar, ident_incr(@vchTabla)) + ')' 
    Else '' 
End + 
Case When not od.name is null                                   -- Defaults (si aplica)
    Then ' Constraint ' + od.name + ' Default ' + replace(replace(cd.text, '((', '('), '))', ')')
    Else ''
End + ', '
from sysobjects o, syscolumns c
LEFT OUTER JOIN sysobjects od On od.id = c.cdefault LEFT OUTER join syscomments cd On cd.id = od.id, 
systypes t
where o.id = object_id(@vchTabla)
and o.id = c.id
and c.xtype = t.xtype
Union all
-- Primary Keys y Unique keys
select char(9) + 'Constraint ' + o.name + ' ' +
Case o.xtype When 'PK' Then 'Primary Key' Else 'Unique' End + ' ' +
dbo.sp_ppinCamposIndice (db_name(), @vchTabla, i.indid) + ', '
from sysobjects o, sysindexes i
where o.parent_obj = object_id(@vchTabla)
and o.xtype in ('PK','UQ')
and i.id = o.parent_obj
and o.name = i.name
Union all
-- Check constraints
select char(9) + 'Constraint ' + o.name + ' Check ' + c.text + ', '
from sysobjects o, syscomments c
where o.parent_obj = object_id(@vchTabla)
and o.xtype in ('C')
and o.id = c.id
Union all
-- Foreign keys
Select @foreign
Union all
Select ')'

Set nocount off
GO


2

首先,我喜欢由devart编写的脚本,我想使用它,但是我发现了一些局限性,因此我决定对其进行改进:

  • 我修复了将脚本限制为4000个字符的错误(仍然有一些疯狂的表格仍然超出了限制)
  • 我修复了错误/限制,以防表使用非集群主键
  • 我用引号替换了[[]
  • 我添加了默认约束的名称
  • 我更改了识别源表的逻辑
  • 我添加了删除并重新创建表及其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 
                +
                N'INSERT INTO ' + QUOTENAME(@TargetDatabase) + N'.' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id)) + N'(' 
                + @CR
                +
                (
                    @TB + N' ' + SUBSTRING(
                        (
                        SELECT @TB + ','+ quotename(Name) + @CR 
                        from sys.columns c 
                        where 
                                c.[object_id] = @object_id 
                            AND system_type_ID <> 189 /*timestamp*/ 
                            AND is_computed = 0
                            and (is_identity = 0 or @GenerateIdentityInsert in (0,1))
                        FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)')
                    ,3,99999)

                )
                + N')' + @CR + N'SELECT ' 
                + @CR
                +
                (
                    @TB + N' ' + SUBSTRING(
                        (
                        SELECT @TB + ','+ quotename(Name) + @CR 
                        FROM sys.columns c 
                        WHERE   c.[object_id] = @object_id 
                            and system_type_ID <> 189 /*timestamp*/ 
                            and is_computed = 0                     
                            and (is_identity = 0 or @GenerateIdentityInsert  in (0,1))
                        FOR XML PATH(N''), TYPE).value(N'.', N'NVARCHAR(MAX)')
                    ,3,99999)
                )
                + N'FROM ' + @SourceDatabase +  N'.' + quotename(OBJECT_schema_name(@object_id)) + N'.' + quotename(OBJECT_NAME(@object_id))            
                + N';' + @CR
                + 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' OFF;'+ @CR
                ELSE 
                    CAST('' AS nvarchar(max))
                END              
        as nvarchar(max))
    ELSE 
        CAST(
                N'' 
        as nvarchar(max))
    END 
    +
    --------------------  USE TRANSACTION  --------------------------------------------------------------------------------------------------
    CAST(
        CASE WHEN @UseTransaction = 1
        THEN 
            @CR + N'COMMIT TRAN; '
            + @CR + N'END TRY'
            + @CR + N'BEGIN CATCH'
            + @CR + N'  IF XACT_STATE() IN (-1,1)'
            + @CR + N'      ROLLBACK TRAN;'
            + @CR + N''
            + @CR + N'  SELECT   ERROR_NUMBER() AS ErrorNumber  '
            + @CR + N'          ,ERROR_SEVERITY() AS ErrorSeverity  '
            + @CR + N'          ,ERROR_STATE() AS ErrorState  '
            + @CR + N'          ,ERROR_PROCEDURE() AS ErrorProcedure  '
            + @CR + N'          ,ERROR_LINE() AS ErrorLine  '
            + @CR + N'          ,ERROR_MESSAGE() AS ErrorMessage; '
            + @CR + N'END CATCH'
        ELSE N'' END 
    as nvarchar(max))

--print is limited to 4000 chars, if necessary, I use multiple print
--to maintain the consistency of the script, I split near the closest CrLF to the max chunk size
DECLARE @i  int = 1;
DECLARE @maxChunk integer = 3990;
DECLARE @len integer = @maxChunk;

WHILE @i < len(@SQL)
BEGIN 
    IF len(@SQL) > (@i + @len)
        set @len = len(substring(@SQL, @i, @maxChunk)) - CHARINDEX(@CR, reverse(substring(@SQL, @i, @len))) + 1
    PRINT substring(@SQL, @i, @len)
    set @i      =  @i + @len
    set @len    =  @maxChunk
END

--SELECT datalength(@SQL), @sql
--EXEC sys.sp_executesql @SQL

goto backFromCreateScript;

尝试运行此对象时收到无效对象错误-有Invalid object name 'sys.Tables'.任何想法吗?
尼克,

@Nick:sys.tables存在是在SQL Server 2008中引入的。您正在使用哪个版本的SQL Server?您可以执行“ SELECT * from sys.tables”吗?您是否尝试过执行DevArt编写的脚本版本?你有同样的错误吗?
ildanny

我正在使用SQL Server 2014,否,我无法执行SELECT * FROM SYS.TABLES我收到与上面相同的无效对象名称错误。
尼克

1
“ SELECT * from sys.tables”与“ SELECT * FROM SYS.TABLES”不同。它旨在检查数据库排序规则。您是否正在使用CS(区分大小写)数据库排序规则?您是否以dbo身份登录?数据库的兼容性级别是否可能是SQL Server 2005(从2008年开始存在sys.tables)?
ildanny

1
@尼克:我更新了脚本并将sys.tables更改为sys.table,让我知道您是否仍然有问题。感谢您的反馈:)
ildanny

2

这与@Devart的答案略有不同,因此您可以获取临时表的CREATE脚本。

请注意,由于@SQL变量是一种NVARCHAR(MAX)数据类型,您可能无法仅使用SSMS从结果中复制它。请参阅此问题以查看如何获取MAX字段的完整值。

DECLARE @temptable_objectid INT = OBJECT_ID('tempdb..#Temp');

DECLARE 
      @object_name SYSNAME
    , @object_id INT

SELECT  
      @object_name = '[' + s.name + '].[' + o.name + ']'
    , @object_id = o.[object_id]
FROM tempdb.sys.objects o WITH (NOWAIT)
JOIN tempdb.sys.schemas s WITH (NOWAIT) ON o.[schema_id] = s.[schema_id]
WHERE object_id = @temptable_objectid

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 tempdb.sys.index_columns ic WITH (NOWAIT)
    JOIN tempdb.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 tempdb.sys.foreign_key_columns k WITH (NOWAIT)
    JOIN tempdb.sys.columns rc WITH (NOWAIT) ON rc.[object_id] = k.referenced_object_id AND rc.column_id = k.referenced_column_id 
    JOIN tempdb.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 tempdb.sys.columns c WITH (NOWAIT)
    JOIN tempdb.sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id
    LEFT JOIN tempdb.sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id] AND c.column_id = cc.column_id
    LEFT JOIN tempdb.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 tempdb.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 tempdb.sys.index_columns ic WITH (NOWAIT)
                         JOIN tempdb.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 tempdb.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 tempdb.sys.foreign_keys fk WITH (NOWAIT)
        JOIN tempdb.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 tempdb.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)')
    ), '')

SELECT @SQL

1

最简单的方法是使用SQL Management Studio的内置功能。

右键单击数据库,转到任务,生成脚本,然后逐步完成向导。您可以选择要编写脚本的对象,这一切将为您完成。

现在,如果您要使自己的OWN脚本执行相同的操作,则可能需要进行很多工作……


这为我工作,为我节省了大量时间和潜在的错误。目前尚不清楚向导将生成哪种类型的脚本。如果选择表,它确实会生成CREATE TABLE脚本。这个答案较早被否决了。有什么特殊原因吗?
jward01 '16

1
@ jward01耸肩。不知道,通过SSMS向导的详细演练,它可能会获得更多的投票,显示您可以在其中选择包括索引和外键之类的选项。
BradC

我可以在SSMS v18.0预览版(可能是较早的版本)中确认,您可以打开“对象资源管理器”,展开数据库,展开“可编程性”,展开“类型”,展开“用户定义的表类型”,右键单击您的类型,然后单击“用户定义的脚本”。在“表类型为”选项中可以选择“创建到”脚本。
大卫·艾伦·康迪

1
如果您要自动化设计过程,这不是最简单的方法。
乍得


0

使用SSMS的最简单方法您也可以为其配置选项(例如,排序规则,语法,drop ... create)

否则,SSMS工具包或CodePlex上的DbFriend可以帮助您生成脚本


0

请参阅此问题的答案:如何在SQL Server中使用SQL查询生成表的创建脚本

使用此查询:

DROP FUNCTION [dbo].[Get_Table_Script]
Go

Create Function Get_Table_Script
(
    @vsTableName varchar(50)
)

Returns
    VarChar(Max)
With ENCRYPTION

Begin

Declare @ScriptCommand varchar(Max)

Select @ScriptCommand =
    ' 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 As SO
    Cross Apply

    (
        Select 
            '  [' + column_name + '] ' + 
             data_type + 
             (
                Case data_type
                    When 'sql_variant' 
                        Then ''
                    When 'text' 
                        Then ''
                    When 'decimal' 
                        Then '(' + Cast( numeric_precision_radix 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 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)

        Inner Join information_schema.table_constraints As TC On (
                                                                    ( TC.Table_name = SO.Name )
                                                                    AND 
                                                                    ( TC.Constraint_Type  = 'PRIMARY KEY' )
                                                                    And 
                                                                    ( TC.TABLE_NAME = @vsTableName )
                                                                 )
        Cross Apply
            (
                Select '[' + Column_Name + '], '
                From  information_schema.key_column_usage As kcu
                Where 
                    ( kcu.Constraint_Name = TC.Constraint_Name )
                Order By ORDINAL_POSITION
                FOR XML PATH('')
            ) As j (list)
Where
    ( xtype = 'U' )
    AND 
    ( Name NOT IN ('dtproperties') )

Return @ScriptCommand

End

您可以这样触发Function

Select [dbo].Get_Table_Script '<Your_Table_Name>'

0

尝试以下操作(使用“结果转换为文本”):

SELECT
ISNULL(smsp.definition, ssmsp.definition) AS [Definition]
FROM
sys.all_objects AS sp
LEFT OUTER JOIN sys.sql_modules AS smsp ON smsp.object_id = sp.object_id
LEFT OUTER JOIN sys.system_sql_modules AS ssmsp ON ssmsp.object_id = sp.object_id
WHERE
(sp.type = N'V' OR sp.type = N'P' OR sp.type = N'RF' OR sp.type=N'PC')and(sp.name=N'YourObjectName' and SCHEMA_NAME(sp.schema_id)=N'dbo')
  • C:检查约束
  • D:默认约束
  • F:外键约束
  • L:日志
  • P:存储过程
  • PK:主键约束
  • RF:复制过滤器存储过程
  • S:系统表
  • TR:触发
  • U:用户表
  • UQ:唯一约束
  • V:检视
  • X:扩展存储过程

干杯,


对于表不起作用(这是主要问题)。
Deadsheep39 '18


0

孤独的潜伏者,第一次的海报...

扩展@Devart和@ildanny解决方案...

我需要针对数据库中的所有表运行此文件,还需要针对链接服务器执行代码。

所有表格...

/*
Ex. 
EXEC etl.GetTableDefinitions '{friendlyname}', '{DatabaseName}', 'All', 0, NULL;
EXEC etl.GetTableDefinitions '{friendlyname}', '{DatabaseName}', 'dbo', 0, NULL;
EXEC etl.GetTableDefinitions '{friendlyname}', '{DatabaseName}', 'All', 1, '{linkedservername}';
*/
CREATE PROCEDURE etl.GetTableDefinitions
(
  @SystemName NVARCHAR(128)
, @DatabaseName NVARCHAR(128)
, @SchemaName NVARCHAR(128)
, @linkedserver BIT
, @linkedservername NVARCHAR(128)
)

AS

DECLARE @sql NVARCHAR(MAX) = N'';
DECLARE @sql1 NVARCHAR(MAX) = N'';
DECLARE @inSchemaName NVARCHAR(MAX) = N'';

SELECT @inSchemaName = CASE WHEN @SchemaName = N'All' THEN N's.[name]' ELSE '''' + @SchemaName + '''' END;

IF @linkedserver = 0
BEGIN

SELECT @sql = N'
SET NOCOUNT ON;

--- options ---
DECLARE @UseTransaction BIT = 0; 
DECLARE @GenerateUseDatabase BIT = 0;
DECLARE @GenerateFKs BIT = 0;
DECLARE @GenerateIdentity BIT = 1;
DECLARE @GenerateCollation BIT = 0;
DECLARE @GenerateCreateTable BIT = 1;
DECLARE @GenerateIndexes BIT = 0;
DECLARE @GenerateConstraints BIT = 1;
DECLARE @GenerateKeyConstraints BIT = 1;
DECLARE @GenerateConstraintNameOfDefaults BIT = 1;
DECLARE @GenerateDropIfItExists BIT = 0;
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 = 0; --0 ignore set,1=set on, 2=set off 
DECLARE @GenerateMessages BIT = 0; --print with no wait
DECLARE @GenerateDataCompressionOptions BIT = 0; --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
--- variables ---
DECLARE @DataTypeSpacer INT = 1; --this is just to improve the formatting of the script ...
DECLARE @name SYSNAME;
DECLARE @sql NVARCHAR(MAX) = N'''';
DECLARE @int INT = 1;
DECLARE @maxint INT;
DECLARE @SourceDatabase NVARCHAR(MAX) = N''' + @DatabaseName + '''; --this is used by the INSERT 
DECLARE @TargetDatabase NVARCHAR(MAX) = N''' + @DatabaseName + '''; --this is used by the INSERT AND USE <DBName>
DECLARE @cr NVARCHAR(20) = NCHAR(13);
DECLARE @tab NVARCHAR(20) = NCHAR(9);

DECLARE @Tables TABLE
(
      id INT IDENTITY(1,1)
    , [name] SYSNAME
    , [object_id] INT 
    , [database_id] SMALLINT
);

BEGIN 

    INSERT INTO @Tables([name], [object_id], [database_id])
    SELECT s.[name] + N''.'' + t.[name] AS [name]
        , t.[object_id]
        , DB_ID(''' + @DatabaseName + ''') AS [database_id]
    FROM [' + @DatabaseName + '].sys.tables t
        JOIN [' + @DatabaseName + '].sys.schemas s ON t.[schema_id] = s.[schema_id]
    WHERE t.[name] NOT IN (''Tally'',''LOC_AND_SEG_CAP1'',''LOC_AND_SEG_CAP2'',''LOC_AND_SEG_CAP3'',''LOC_AND_SEG_CAP4'',''TableNames'')
        AND s.[name] = ' + @inSchemaName + '
    ORDER BY s.[name], t.[name];

    SELECT @maxint = COUNT(0) 
    FROM @Tables;

    WHILE @int <= @maxint
    BEGIN

        ;WITH 
        index_column AS 
        (
            SELECT ic.[object_id]
                , OBJECT_NAME(ic.[object_id], DB_ID(N''' + @DatabaseName + ''')) AS ObjectName
                , ic.index_id
                , ic.is_descending_key
                , ic.is_included_column
                , c.[name] 
            FROM [' + @DatabaseName + '].sys.index_columns ic WITH (NOLOCK)
                JOIN [' + @DatabaseName + '].sys.columns c WITH (NOLOCK) ON ic.[object_id] = c.[object_id] 
                    AND ic.column_id = c.column_id
                JOIN [' + @DatabaseName + '].sys.tables t ON c.[object_id] = t.[object_id]
        ) 
        , fk_columns AS 
        (
            SELECT k.constraint_object_id
                , cname = c.[name]
                , rcname = rc.[name]
            FROM [' + @DatabaseName + '].sys.foreign_key_columns k WITH (NOWAIT)
                JOIN [' + @DatabaseName + '].sys.columns rc WITH (NOWAIT) ON rc.[object_id] = k.referenced_object_id 
                    AND rc.column_id = k.referenced_column_id 
                JOIN [' + @DatabaseName + '].sys.columns c WITH (NOWAIT) ON c.[object_id] = k.parent_object_id 
                    AND c.column_id = k.parent_column_id
                JOIN [' + @DatabaseName + '].sys.tables t ON c.[object_id] = t.[object_id]
            WHERE @GenerateFKs = 1
        )
        SELECT @sql = @sql +

            --------------------  USE DATABASE   --------------------------------------------------------------------------------------------------
                CAST(
                    CASE WHEN @GenerateUseDatabase = 1
                    THEN N''USE '' + @TargetDatabase + N'';'' + @cr
                    ELSE N'''' END 
                AS NVARCHAR(200))
                +
            --------------------  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(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''',''''SN'''') IS NOT NULL DROP SYNONYM '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'';'' + @cr AS NVARCHAR(MAX))
                ELSE CAST(N'''' AS NVARCHAR(MAX))   END 
                +
            --------------------  DROP TABLE IF EXISTS --------------------------------------------------------------------------------------------------
                CASE WHEN @GenerateDropIfItExists = 1
                THEN 
                    --Drop TABLE if EXISTS
                    CAST(N''IF OBJECT_ID('''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''',''''U'''') IS NOT NULL DROP TABLE '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'';'' + @cr AS NVARCHAR(MAX))
                    + @cr
                ELSE N'''' END 
                +
            --------------------  DROP CONSTRAINT IF EXISTS --------------------------------------------------------------------------------------------------
                CAST((CASE WHEN @GenerateMessages = 1 AND @GenerateDropFKIfItExists = 1 THEN 
                    N''RAISERROR(''''DROP CONSTRAINTS OF %s'''',10,1, '''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_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 [' + @DatabaseName + '].sys.tables t
                            INNER JOIN [' + @DatabaseName + '].sys.foreign_keys f ON f.parent_object_id = t.[object_id]
                            INNER JOIN [' + @DatabaseName + '].sys.schemas s ON s.[schema_id] = f.[schema_id]
                        WHERE f.referenced_object_id = t.[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(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + @cr           
            ELSE CAST(N'''' AS NVARCHAR(MAX)) END) AS NVARCHAR(MAX)) 
            +
            CASE WHEN @GenerateCreateTable = 1 THEN 
                CAST(
                    N''CREATE TABLE '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + @cr + N''('' + @cr + STUFF((
                    SELECT 
                        CAST(
                            @tab + N'','' + QUOTENAME(c.[name]) + N'' '' + ISNULL(REPLICATE('' '',@DataTypeSpacer - LEN(QUOTENAME(c.[name]))),'''') 
                            +  
                            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 [' + @DatabaseName + '].sys.columns c WITH (NOWAIT)
                        INNER JOIN [' + @DatabaseName + '].sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id
                        LEFT JOIN [' + @DatabaseName + '].sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id] 
                            AND c.column_id = cc.column_id
                        LEFT JOIN [' + @DatabaseName + '].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 [' + @DatabaseName + '].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] = t.[object_id]
                    ORDER BY c.column_id
                    FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)''), 1, 2, @tab + N'' '') AS NVARCHAR(MAX))
            ELSE CAST(N'''' AS NVARCHAR(MAX)) END 
            + 
            ---------------------- Key Constraints ----------------------------------------------------------------
            CAST(
                CASE WHEN @GenerateKeyConstraints <> 1 THEN N'''' 
                ELSE 
                    ISNULL((SELECT @tab + 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 [' + @DatabaseName + '].sys.index_columns ic WITH (NOWAIT)
                                        JOIN [' + @DatabaseName + '].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 [' + @DatabaseName + '].sys.key_constraints k WITH (NOWAIT) 
                            LEFT JOIN [' + @DatabaseName + '].sys.indexes kidx ON k.parent_object_id = kidx.[object_id] 
                                AND k.unique_index_id = kidx.index_id
                        WHERE k.parent_object_id = t.[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 [' + @DatabaseName + '].sys.partitions WHERE OBJECT_ID = t.[object_id] AND index_id = 1) <> N''NONE''
                THEN N''WITH (DATA_COMPRESSION='' + (SELECT TOP 1 data_compression_desc FROM [' + @DatabaseName + '].sys.partitions WHERE OBJECT_ID = t.[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(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + @cr            
            ELSE N'''' END) AS NVARCHAR(MAX)) 
            +
            CAST(
                ISNULL((SELECT (
                    SELECT @cr +
                    N''ALTER TABLE '' +  QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_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]
                            AND fk.[object_id] = t.[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]
                            AND fk.[object_id] = t.[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(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'' CHECK CONSTRAINT '' + QUOTENAME(fk.[name])  + N'''' + @cr
                FROM [' + @DatabaseName + '].sys.foreign_keys fk WITH (NOWAIT)
                    JOIN [' + @DatabaseName + '].sys.objects ro WITH (NOWAIT) ON ro.[object_id] = fk.referenced_object_id
                WHERE fk.parent_object_id = t.[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(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_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(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_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.[object_id] = t.[object_id]
                                    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.[object_id] = t.[object_id]
                                        AND c.index_id = i.index_id
                                    FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)''), 1, 2, N'''') + N'')'', N'''')  + @cr
                        FROM [' + @DatabaseName + '].sys.indexes i WITH (NOWAIT)
                        WHERE i.[object_id] = t.[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 N'''' END 
            +
            ------------------------  @GenerateDelete     ----------------------------------------------------------
            CAST((CASE WHEN @GenerateMessages = 1 AND @GenerateDelete = 1 THEN 
                N''RAISERROR(''''TRUNCATING  %s'''',10,1, '''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + @cr            
            ELSE N'''' END) AS NVARCHAR(MAX)) 
            +
            CASE WHEN @GenerateDelete = 1 THEN
                CAST(
                    (CASE WHEN EXISTS (SELECT TOP 1 [name] FROM [' + @DatabaseName + '].sys.foreign_keys WHERE referenced_object_id = t.[object_id]) THEN 
                        N''DELETE FROM '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'';'' + @cr
                    ELSE
                        N''TRUNCATE TABLE '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'';'' + @cr
                    END)
                AS NVARCHAR(MAX))
            ELSE N'''' END 
            +
            ------------------------- @GenerateInsertInto ----------------------------------------------------------
            CAST((CASE WHEN @GenerateMessages = 1 AND @GenerateDropFKIfItExists = 1 THEN 
                N''RAISERROR(''''INSERTING INTO  %s'''',10,1, '''''' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'''''') WITH NOWAIT;'' + @cr            
            ELSE N'''' END) AS NVARCHAR(MAX)) 
            +
            CASE WHEN @GenerateInsertInto = 1
            THEN 
                CAST(
                        CASE WHEN EXISTS (SELECT TOP 1 c.[name] FROM [' + @DatabaseName + '].sys.columns c WHERE c.[object_id] = t.[object_id] AND c.is_identity = 1) AND @GenerateIdentityInsert = 1 THEN 
                            N''SET IDENTITY_INSERT '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'' ON;'' + @cr
                        ELSE N'''' END 
                        +
                        N''INSERT INTO '' + QUOTENAME(@TargetDatabase) + N''.'' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N''('' 
                        + @cr
                        +
                        (
                            @tab + N'' '' + SUBSTRING(
                                (
                                SELECT @tab + '',''+ QUOTENAME(c.[name]) + @cr 
                                FROM [' + @DatabaseName + '].sys.columns c 
                                WHERE c.[object_id] = t.[object_id] 
                                    AND c.system_type_ID <> 189 /*timestamp*/ 
                                    AND c.is_computed = 0
                                    AND (c.is_identity = 0 or @GenerateIdentityInsert in (0,1))
                                FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)'')
                            ,3,99999)

                        )
                        + N'')'' + @cr + N''SELECT '' 
                        + @cr
                        +
                        (
                            @tab + N'' '' + SUBSTRING(
                                (
                                SELECT @tab + '',''+ QUOTENAME(c.[name]) + @cr 
                                FROM [' + @DatabaseName + '].sys.columns c 
                                WHERE c.[object_id] = t.[object_id] 
                                    AND c.system_type_ID <> 189 /*timestamp*/ 
                                    AND c.is_computed = 0                     
                                    AND (c.is_identity = 0 or @GenerateIdentityInsert  in (0,1))
                                FOR XML PATH(N''''), TYPE).value(N''.'', N''NVARCHAR(MAX)'')
                            ,3,99999)
                        )
                        + N''FROM '' + @SourceDatabase +  N''.'' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id]))            
                        + N'';'' + @cr
                        + CASE WHEN EXISTS (SELECT TOP 1 c.[name] FROM [' + @DatabaseName + '].sys.columns c WHERE c.[object_id] = t.[object_id] AND c.is_identity = 1) AND @GenerateIdentityInsert = 1 THEN 
                            N''SET IDENTITY_INSERT '' + QUOTENAME(OBJECT_SCHEMA_NAME(t.[object_id], t.[database_id])) + N''.'' + QUOTENAME(OBJECT_NAME(t.[object_id], t.[database_id])) + N'' OFF;''+ @cr
                        ELSE N'''' END              
                AS NVARCHAR(MAX))
            ELSE N'''' END 
            +
            --------------------  USE TRANSACTION  --------------------------------------------------------------------------------------------------
            CAST(
                CASE WHEN @UseTransaction = 1
                THEN 
                    @cr + N''COMMIT TRAN; ''
                    + @cr + N''END TRY''
                    + @cr + N''BEGIN CATCH''
                    + @cr + N''  IF XACT_STATE() IN (-1,1)''
                    + @cr + N''      ROLLBACK TRAN;''
                    + @cr + N''''
                    + @cr + N''  SELECT   ERROR_NUMBER() AS ErrorNumber  ''
                    + @cr + N''          ,ERROR_SEVERITY() AS ErrorSeverity  ''
                    + @cr + N''          ,ERROR_STATE() AS ErrorState  ''
                    + @cr + N''          ,ERROR_PROCEDURE() AS ErrorProcedure  ''
                    + @cr + N''          ,ERROR_LINE() AS ErrorLine  ''
                    + @cr + N''          ,ERROR_MESSAGE() AS ErrorMessage; ''
                    + @cr + N''END CATCH''
                ELSE N'''' END 
            AS NVARCHAR(700))
        FROM @Tables t
        WHERE ID = @int
        ORDER BY [name]; 
    
        SET @int = @int + 1;
    
    END

    EXEC [master].dbo.PrintMax @sql;
/* see below for PrintMax code*/

END'

EXEC (@sql);

END
ELSE

和链接服务器位...

BEGIN

SELECT @sql = N'EXECUTE (''
SET NOCOUNT ON;
BEGIN

... Same code but be sure to double up on your single quotes

END

... code for the printmax proc (not mine, @Ben B) because it may not exist at destination server

    DECLARE @CurrentEnd BIGINT; /* track the length of the next substring */
    DECLARE @offset TINYINT; /*tracks the amount of offset needed */
    DECLARE @String NVARCHAR(MAX);
    SET @String = REPLACE(REPLACE(@sql, CHAR(13) + CHAR(10), CHAR(10)), CHAR(13), CHAR(10))

    WHILE LEN(@String) > 1
    BEGIN
        IF CHARINDEX(CHAR(10), @String) BETWEEN 1 AND 4000
        BEGIN
            SET @CurrentEnd = CHARINDEX(CHAR(10), @String) -1
            SET @offset = 2
        END
        ELSE
        BEGIN
            SET @CurrentEnd = 4000
            SET @offset = 1
        END   
        PRINT SUBSTRING(@String, 1, @CurrentEnd) 
        SET @String = SUBSTRING(@String, @CurrentEnd + @offset, LEN(@String))   
    END

END'') AT [' + @linkedservername + ']';

EXEC (@sql);

END

Ben B解决方案

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.