123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
-
- namespace Vit.Db.DbMng.MsSql
- {
-
- public partial class MsSqlDbMng
- {
- public static string DataBaseStructBuilder = @"
- -------------------
- --生成建库语句
- --1.生成 表字段、字段备注、默认值约束 、unique约束、primary key约束、索引的创建语句
- --2.生成触发器、函数、存储过程、视图的创建语句
- -- by lith on 2021-01-21 v2.3
- -------------------
- -- ------------------------------------------------------------------------------------
- -- 1.构建表头 备份时间、数据库版本、数据库名称
- select '
- -- (x.1)备份信息
- /* ';
- select '
- 备份时间 :',CONVERT(varchar(100), GETDATE(), 120);
- select '
- SqlServer版本 :',CONVERT(varchar(1000),@@version);
- --select '
- -- 数据库名称 :',(Select Name From Master..SysDataBases Where DbId=(Select Dbid From Master..SysProcesses Where Spid = @@spid)) as dbName;
- select '
- */
- ';
- -- ------------------------------------------------------------------------------------
- -- 2.生成 表字段、字段备注、默认值约束 、unique约束、primary key约束、索引的创建语句
- select ('
- /* (x.2)表 */
- ') comment;
- --(x.1)创建表用来存储数据库表的结构
- create table #Proc_S_TableStruct_ColInfo([col_id] int,[col_name] varchar(200),[col_typename] varchar(200),[col_len] int,[col_identity] int,[col_seed] int,[col_increment] int,[collation] varchar(200),[col_null] int,[col_DefaultValue] varchar(2000),[ConstraintName_DefaultValue] varchar(200),[ExtendedProperty] varchar(4000),[ConstraintName_PrimaryKey] varchar(200),[ConstraintName_Unique] varchar(200))
-
- create table #Proc_S_TableStruct_MShelpcolumns([col_name] varchar(200),[col_id] int,[col_typename] varchar(200),[col_len] int,[col_prec] varchar(200),[col_scale] varchar(200),[col_basetypename] varchar(200),[col_defname] varchar(200),[col_rulname] varchar(200),[col_null] int,[col_identity] int,[col_flags] int,[col_seed] int,[col_increment] int,[col_dridefname] varchar(200),[text] text ,[col_iscomputed] varchar(200),[col_text] varchar(200),[col_NotForRepl] int,[col_fulltext] int,[col_AnsiPad] int,[col_DOwner] int,[col_DName] varchar(200),[col_ROwner] int,[col_RName] varchar(200),[collation] varchar(200),[ColType] varchar(200),[column1] int ,[column2] int)
- create table #Proc_S_TableStruct_SqlCreateTb([id] int identity(1,1),sql varchar(700));
- select [Name] into #Proc_S_TableStruct_tbName from sysobjects where [type] = 'U' and [Name]!='dtproperties';
-
- --(x.2)获取所有的索引
- SELECT
- SCHEMA_NAME(t.schema_id) AS [架构名称],
- t.name AS [数据表名称],
- i.name AS [索引名称],
- i.type_desc as [索引类型],
- i.is_primary_key as [是否主键],
- i.is_unique as [是否唯一],
- i.is_unique_constraint as [是否外键],
- STUFF(REPLACE(REPLACE((
- SELECT QUOTENAME(c.name) + CASE WHEN ic.is_descending_key = 1 THEN ' DESC' ELSE '' END AS [data()]
- FROM sys.index_columns AS ic
- INNER JOIN sys.columns AS c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
- WHERE ic.object_id = i.object_id AND ic.index_id = i.index_id AND ic.is_included_column = 0
- ORDER BY ic.key_ordinal
- FOR XML PATH
- ), '<row>', ', '), '</row>', ''), 1, 2, '') AS [索引键列表],
- STUFF(REPLACE(REPLACE((
- SELECT QUOTENAME(c.name) AS [data()]
- FROM sys.index_columns AS ic
- INNER JOIN sys.columns AS c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
- WHERE ic.object_id = i.object_id AND ic.index_id = i.index_id AND ic.is_included_column = 1
- ORDER BY ic.index_column_id
- FOR XML PATH
- ), '<row>', ', '), '</row>', ''), 1, 2, '') AS [包含列信息]
-
- -- ,u.user_seeks
- -- ,u.user_scans
- -- ,u.user_lookups
- -- ,u.user_updates
- into #Proc_S_TableStruct_Index
- FROM sys.tables AS t
- INNER JOIN sys.indexes AS i ON t.object_id = i.object_id
- -- LEFT JOIN sys.dm_db_index_usage_stats AS u ON i.object_id = u.object_id AND i.index_id = u.index_id and u.database_id= db_id()
- WHERE t.is_ms_shipped = 0
- AND i.type <> 0;
- --(x.3)循环处理各个表
- declare @tbName varchar(100);
- declare @tbCount int;
- declare @tbIndex int;
- set @tbCount=(select count(*) from #Proc_S_TableStruct_tbName);
- set @tbIndex=0;
- while 1=1
- begin
- --(x.x.1)
- set @tbIndex=@tbIndex+1;
- --(x.x.2)获取表信息
- set @tbName=( SELECT top 1 [Name] from #Proc_S_TableStruct_tbName)
- if @tbName is null
- break;
- delete #Proc_S_TableStruct_tbName where [Name]=@tbName;
- --(x.x.2.1) 获取字段基础信息
- insert into #Proc_S_TableStruct_MShelpcolumns exec sp_MShelpcolumns @tbName;
-
- select [col_id],[col_name],col_typename,col_len,col_identity,col_seed,col_increment,collation
- ,col_null,[text] col_DefaultValue,col_dridefname [ConstraintName_DefaultValue]
- into #Proc_S_TableStruct_Col
- from #Proc_S_TableStruct_MShelpcolumns;
- truncate table #Proc_S_TableStruct_MShelpcolumns;
- --(x.x.2.2) 获取字段的备注
- select objname [col_name],[value] [ExtendedProperty]
- into #Proc_S_TableStruct_Property
- from ::fn_listextendedproperty(null,N'user',N'dbo',N'table',@tbName,N'column',null)
- where 1=1;
- --(x.x.2.3)主码 和 唯一 约束 。 CONSTRAINT_TYPE: 'PRIMARY KEY' 和 'UNIQUE'
- select t1.COLUMN_NAME [col_name],t2.CONSTRAINT_TYPE ,t1.Constraint_Name
- into #Proc_S_TableStruct_Constraint
- from information_schema.key_column_usage t1
- left join information_schema.table_constraints t2 on t1.Constraint_Name=t2.Constraint_Name
- where t1.TABLE_NAME=@tbName;
- --(x.x.2.4) 合并最终结构数据
- insert into #Proc_S_TableStruct_ColInfo
- select c.*
- ,convert(varchar(8000) , p.[ExtendedProperty])
- ,conPrimary.Constraint_Name [ConstraintName_PrimaryKey]
- ,conUnique.Constraint_Name [ConstraintName_Unique]
- from #Proc_S_TableStruct_Col c
- left join #Proc_S_TableStruct_Property p on c.[col_name] Collate Database_Default =p.[col_name]
- left join #Proc_S_TableStruct_Constraint conPrimary on c.[col_name]=conPrimary.[col_name] and conPrimary.[CONSTRAINT_TYPE]='PRIMARY KEY'
- left join #Proc_S_TableStruct_Constraint conUnique on c.[col_name]=conUnique.[col_name] and conUnique.[CONSTRAINT_TYPE]='UNIQUE';
-
- --(x.x.2.5)清理数据
- drop table #Proc_S_TableStruct_Col;
- drop table #Proc_S_TableStruct_Property;
- drop table #Proc_S_TableStruct_Constraint;
- --(x.x.3)输出
- select ('
- /* ['+ CONVERT(varchar(10),@tbIndex)+'/'+ CONVERT(varchar(10),@tbCount) +']创建表 '+@tbName+' */
- ') comment;
- --(x.x.x.1)建表
- select ('
- /* 创建表字段 */') comment;
- insert into #Proc_S_TableStruct_SqlCreateTb(sql)
- select '
- create table [dbo].['+@tbName+'] ( ';
- insert into #Proc_S_TableStruct_SqlCreateTb(sql)
- select
- ' ['+[col_name]+'] ['+[col_typename]+']'
- -- [类型] (长度)
- +(case when(0!=charindex('char',col_typename)) then (case when [col_len]<=0 then '(MAX)' else ' ('+convert(varchar(100),[col_len])+')' end) else '' end)
- -- IDENTITY(2010,100)
- +(case when(1=col_identity) then ' IDENTITY('+convert(varchar(100),[col_seed]) +','+ convert(varchar(100),[col_increment]) +')' else '' end)
- -- COLLATE Chinese_PRC_CI
- +(case when(collation is not null) then ' COLLATE '+[collation] else '' end)
- -- NOT NULL
- +(case when(1=col_null) then ' NULL' else ' NOT NULL' end)
- +'
- ,'
- from #Proc_S_TableStruct_ColInfo;
- update #Proc_S_TableStruct_SqlCreateTb set sql=(isnull(left(sql,len(sql)-1),'')+'); ') where [ID]= (select max([ID]) from #Proc_S_TableStruct_SqlCreateTb);
- select sql from #Proc_S_TableStruct_SqlCreateTb;
- truncate table #Proc_S_TableStruct_SqlCreateTb;
-
- --(x.x.x.2)默认值约束
- select ('
- /* 默认值约束 */') comment;
- select ('
- alter table '+ quotename(@tbName)
- +' add constraint '+quotename(ConstraintName_DefaultValue)
- +' default'+col_DefaultValue
- +' for ' + quotename([col_name])
- +';') [sql]
- from #Proc_S_TableStruct_ColInfo
- where ConstraintName_DefaultValue is not null;
-
-
- --(x.x.x.3)unique约束 ALTER TABLE table_a ADD unique(aID);
- select ('
- /* unique约束 */') comment;
- select ('
- alter table '+ quotename(@tbName)
- +' add unique( '+quotename([col_name])+')'
- +';') [sql]
- from #Proc_S_TableStruct_ColInfo
- where ConstraintName_Unique is not null
-
- --(x.x.x.4)primary key约束
- --'ALTER TABLE ['+@tbName+'] ADD CONSTRAINT PK__'+@tbName+'_'+@colName+'__lit17032317 PRIMARY KEY CLUSTERED (['+@colName+']) '
- select ('
- /* primary key约束 */') comment;
- select('
- alter table '+ quotename(@tbName)
- +' add constraint '+quotename(ConstraintName_PrimaryKey)
- +' PRIMARY KEY CLUSTERED ('+quotename([col_name])+')'
- +';') [sql]
- from #Proc_S_TableStruct_ColInfo
- where ConstraintName_PrimaryKey is not null;
-
- --(x.x.x.5)索引
- -- CREATE NONCLUSTERED INDEX IX_Tileset_File ON dbo.Tileset_File
- -- (professionalTreeId, creator DESC,floorId)
- -- WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
- select ('
- /* 索引 */') comment;
- select('
- CREATE NONCLUSTERED INDEX '+ quotename([索引名称])
- +' ON '+quotename([架构名称])+'.'+quotename([数据表名称])
- +'
- ('+[索引键列表]+')'
- +'
- WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY];
- ') [sql]
- from #Proc_S_TableStruct_Index
- where [索引类型]='NONCLUSTERED' and [数据表名称]=@tbName;
-
- truncate table #Proc_S_TableStruct_ColInfo;
- end
- select '
- GO
- ';
- drop table #Proc_S_TableStruct_Index;
- drop table #Proc_S_TableStruct_tbName;
- drop table #Proc_S_TableStruct_MShelpcolumns;
- drop table #Proc_S_TableStruct_ColInfo;
- drop table #Proc_S_TableStruct_SqlCreateTb;
-
- -- ------------------------------------------------------------------------------------
- -- 3.生成触发器、函数、存储过程、视图的创建语句
- --(x.1)获取数据的语句
- declare @IDStart int;
- declare @IDNext int;
- --定义text 指针
- declare @ptrval BINARY(16)
- declare @sqlNext varchar(8000)
- SELECT Identity(int,1,1) [ID],
- o.xtype,
- (CASE o.xtype WHEN 'X' THEN '扩展存储过程' WHEN 'TR' THEN '触发器' WHEN 'PK' THEN '主键' WHEN 'F' THEN '外键' WHEN 'C' THEN '约束' WHEN 'V' THEN '视图' WHEN 'FN' THEN '函数-标量' WHEN 'IF' THEN '函数-内嵌' WHEN 'TF' THEN '函数-表值' ELSE '存储过程' END)
- AS [类型]
- , o.name AS [对象名]
- , o.crdate AS [创建时间]
- , o.refdate AS [更改时间]
- ,convert(text,c.[text]) AS [声明语句]
- into #tb
- FROM dbo.sysobjects o LEFT OUTER JOIN
- dbo.syscomments c ON o.id = c.id
- WHERE (o.xtype IN ('X', 'TR', 'C', 'V', 'F', 'IF', 'TF', 'FN', 'P', 'PK')) AND
- (OBJECTPROPERTY(o.id, N'IsMSShipped') = 0)
- --order BY o.xtype
- while(1=1)
- begin
- set @IDStart=null;
- select top 1 @IDStart=start.[ID], @IDNext=nex.[ID], @ptrval=TEXTPTR(start.[声明语句]),@sqlNext=convert(varchar(8000),nex.[声明语句])
- from #tb start,#tb nex where start.[ID]<nex.[ID] and start.[xtype]=nex.[xtype] and start.[对象名]=nex.[对象名];
- if( @IDStart is null) break;
- UPDATETEXT #tb.[声明语句] @ptrval NULL 0 @sqlNext;
- delete #tb where [id]=@IDNext;
- end
-
- --(x.3)触发器
- select ('
- /* (x.3)触发器 */
- ') comment;
- select [声明语句],'
- GO
- ' from #tb where xtype='TR';
- --(x.4)函数
- select ('
- /* (x.4)函数 */
- ') comment;
- select [声明语句],'
- GO
- ' from #tb where xtype='FN';
- select [声明语句] ,'
- GO
- ' from #tb where xtype='TF';
- --(x.5)存储过程
- select ('
- /* (x.5)存储过程 */
- ') comment;
- select [声明语句],'
- GO
- ' from #tb where xtype='P';
- --(x.6)视图 (考虑 依附关系)
- select ('
- /* (x.6)视图 */
- ') comment;
- select identity(int,1,1) [id],[对象名] [name], convert(smallint,null) SortCode into #tmp_Enty from #tb where xtype='V';
-
- SELECT distinct o.[name], p.[name] dependOn
- into #tmp_R
- FROM sysobjects o
- INNER JOIN sysdepends d ON d.id = o.id
- INNER JOIN sysobjects p ON d.depid = p.id and p.xtype='v' and exists(select 1 from #tmp_Enty where p.[name] = #tmp_Enty.[name] )
- where o.xtype='v' and exists(select 1 from #tmp_Enty where o.[name] = #tmp_Enty.[name] );
-
- declare @sc int;
- set @sc=1;
- while 1=1
- begin
- set @sc=@sc+1;
- update #tmp_Enty set SortCode=@sc from #tmp_Enty enty where SortCode is null
- and not exists(select 1 from #tmp_R r inner join #tmp_Enty parent on r.[dependOn]=parent.[name] where r.[name]=enty.[name] and parent.SortCode is null )
- if(0=@@ROWCOUNT)
- break;
-
- end
- update #tmp_Enty set SortCode=@sc+1 where SortCode is null;
-
- select [声明语句],'
- GO
- ' from #tb inner join #tmp_Enty on #tb.对象名=#tmp_Enty.[name] order by SortCode;
- drop table #tmp_Enty;
- drop table #tmp_R;
-
-
- drop table #tb;
-
- ";
- }
- }
|