2

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

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

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

有这样的库或来源吗?

4

3 回答 3

3

实际上,您会发现自己可以做到这一点,并且您会在此过程中学到一些东西。我在我维护的几个数据库上使用它。我创建了一个视图,可以轻松查看使用 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# 代码中。

于 2013-08-29T18:36:48.953 回答
2

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
于 2013-08-29T20:16:33.743 回答
2

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

于 2013-08-29T17:26:35.260 回答