【问题标题】:SSIS: generate create table DDL programmaticallySSIS:以编程方式生成创建表 DDL
【发布时间】:2013-08-29 14:39:05
【问题描述】:

是否有可以帮助我即时生成 DDL 的源或库?

我有几百个远程数据库需要复制到本地服务器。现场升级程序是创建一个新的数据库。在本地,我也这样做。

因此,我不想为字段中的所有不同数据库版本生成 DDL,而是想从源表中读取 DDL 并在本地创建一个相同的表。

有这样的库或者源码吗?

【问题讨论】:

    标签: sql sql-server tsql ssis


    【解决方案1】:

    实际上,您会发现自己可以做到这一点,并且您会在此过程中学到一些东西。我在我维护的几个数据库上使用它。我使用 DDL 样式信息创建了一个易于查看的视图。

    create view vw_help as
    select 
      Table_Name as TableName
    , Column_Name as ColName
    , Ordinal_Position as ColNum
    , Data_Type as DataType
    , Character_Maximum_Length as MaxChars
    , coalesce(Datetime_Precision, Numeric_Precision) as [Precision]
    , Numeric_Scale as Scale
    , Is_Nullable as Nullable
    , case when (Data_Type in ('varchar', 'nvarchar', 'char', 'nchar', 'binary', 'varbinary')) then
           case when (Character_Maximum_Length = -1) then Data_Type + '(max)'
                      else Data_Type + '(' + convert(varchar(6),Character_Maximum_Length) + ')'
                      end
           when (Data_Type in ('decimal', 'numeric')) then
                Data_Type + '(' + convert(varchar(4), Numeric_Precision) + ',' + convert(varchar(4), Numeric_Scale) + ')'
           when (Data_Type in ('bit', 'money', 'smallmoney', 'int', 'smallint', 'tinyint', 'bigint', 'date', 'time', 'datetime', 'smalldatetime', 'datetime2', 'datetimeoffset', 'datetime2', 'float', 'real', 'text', 'ntext', 'image', 'timestamp', 'uniqueidentifier', 'xml')) then Data_Type
      else 'unknown type'
      end as DeclA
    , case when (Is_Nullable = 'YES') then 'null' else 'not null' end as DeclB
    , Collation_Name as Coll
    -- ,* 
    from Information_Schema.Columns
    GO
    

    我使用以下内容来“显示表结构”

    /*
    
    exec ad_Help TableName, 1
    
    */
    
    ALTER proc [dbo].[ad_Help] (@TableName nvarchar(128), @ByOrdinal int = 0) as
    begin
    set nocount on
    
    declare @result table
    (
      TableName nvarchar(128)
    , ColName nvarchar(128)
    , ColNum int
    , DataType nvarchar(128)
    , MaxChars int
    , [Precision] int
    , Scale int
    , Nullable varchar(3)
    , DeclA varchar(max)
    , DeclB varchar(max)
    , Coll varchar(128)
    )
    
    insert @result
    select TableName, ColName, ColNum, DataType, MaxChars, [Precision], Scale, Nullable, DeclA, DeclB, Coll
    from dbo.vw_help
    where TableName like @TableName
    
    if (select count(*) from @result) <= 0
    begin
      select 'No tables matching ''' + @TableName + '''' as Error
      return
    end
    
    if (@ByOrdinal > 0)
    begin
      select * from @result order by TableName, ColNum
    end else begin
      select * from @result order by TableName, ColName
    end
    
    end
    GO
    

    如果您还需要生成外键等,您可以在 InformationSchemas 中使用其他信息。这有点复杂,我从来没有费心充实生成 DDL 所需的所有内容,但您应该有正确的想法。当然,如果您可以使用已经建议的内容,我不会费心滚动您自己的。

    添加了评论——我没有给你一个确切的答案,但很高兴能提供帮助。您将需要生成大量动态字符串操作才能完成这项工作—— varchar(max) 会有所帮助。我会指出 TSQL 不是此类项目的首选语言。就个人而言,如果我必须生成全表 DDL,我可能会想将其编写为 CLR proc 并在 C# 中进行繁重的字符串操作。如果这对您有意义,我仍然会在 SQL Server 之外调试该过程(例如,用于测试和用餐的表单项目)。请记住,CLR procs 是 Net 2.0 框架。

    您绝对可以创建一个返回一组结果的存储过程,即 1 表示表列,1 表示外键等,然后在 C# 中使用该组结果并构建 DDL 语句。在 C# 代码中。

    【讨论】:

    • 谢谢,这就是我要找的。​​span>
    【解决方案2】:

    建议查看SQL Server Management Objects (SMO),或Red Gate 的一些工具。

    【讨论】:

      【解决方案3】:

      Gary Walker,根据您的脚本,我创建了我需要的内容。非常感谢您的帮助。

      在这里,如果其他人需要它:

      with ColumnDef (TableName, ColName, ColNum, DeclA, DeclB)
      as
      (
          select 
            Table_Name as TableName
          , Column_Name as ColName
          , Ordinal_Position as ColNum
          , case when (Data_Type in ('varchar', 'nvarchar', 'char', 'nchar', 'binary', 'varbinary')) then
                 case when (Character_Maximum_Length = -1) then Data_Type + '(max)'
                            else Data_Type + '(' + convert(varchar(6),Character_Maximum_Length) + ')'
                            end
                 when (Data_Type in ('decimal', 'numeric')) then
                      Data_Type + '(' + convert(varchar(4), Numeric_Precision) + ',' + convert(varchar(4), Numeric_Scale) + ')'
                 when (Data_Type in ('bit', 'money', 'smallmoney', 'int', 'smallint', 'tinyint', 'bigint', 'date', 'time', 'datetime', 'smalldatetime', 'datetime2', 'datetimeoffset', 'datetime2', 'float', 'real', 'text', 'ntext', 'image', 'timestamp', 'uniqueidentifier', 'xml')) then Data_Type
            else 'unknown type'
            end as DeclA
          , case when (Is_Nullable = 'YES') then 'null' else 'not null' end as DeclB
          from Information_Schema.Columns
      )
      select 'CREATE TABLE ' + TableName + ' (' + 
      substring((select ', ' + ColName + ' ' + declA + ' ' + declB
      from ColumnDef
      where tablename = t.TableName
      order by ColNum
      for xml path ('')),2,8000) + ') '
      from 
      (select distinct TableName from ColumnDef) t
      

      【讨论】:

      • +1 用于发布您自己完整的答案——似乎很少有人会打扰。您的最终选择应该是(从 Information_Schema.Tables 中选择 Table_Name)t
      • 顺便说一句,我使用视图有两个原因——我从多个地方使用它,并且我发现它在大多数时候都比基于 WITH 的 SQL 更快。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-05
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多