设为首页 收藏本站
查看: 1071|回复: 0

[经验分享] SQL SERVER 自动生成 MySQL 表结构及索引 的建表SQL

[复制链接]

尚未签到

发表于 2017-12-13 16:44:58 | 显示全部楼层 |阅读模式
-- =============================================  
--
Author: suxinyu  
--
Create date: 20170612  
--
Description: 根据表名自动把表格的所有建表DDL SQL转化为 MySQL的建表SQL,不包含分区表,不处理区域数据类型;执行过程中,需要把存储过程建立在需要导出的数据库中。  
--
Example: exec p_tb_mssqltomysql 'orders,ordernums,channels'  
--
=============================================  
--存储过程建立在需要导出表结构的DB上
  USE db
  GO
  
CREATE  PROC [dbo].[p_tb_mssqltomysql]
  
@tbsql varchar(1000)
  
AS
  
SET NOCOUNT ON ;
  

  
--处理tablename的字符串,把tablename字符串分割成每一行存储进入表变量中
  
DECLARE @tab_tablename table(tbname varchar(100))
  
DECLARE @tbname varchar(100)
  
INSERT INTO @tab_tablename(tbname)
  
SELECT
  

  
SUBSTRING(@tbsql,NUMBER,CHARINDEX(',',@tbsql+',',NUMBER)-number)
  
FROM master.dbo.spt_values
  
WHERE TYPE='P'  AND number>0 AND SUBSTRING(','+@tbsql,number,1)=','
  

  
--把mysql跟mssql的数据类型对应起来存储
  
--空间数据类型不处理
  
--money类型处理为float
  
--timestamp处理为 timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
  
DECLARE @tbtype table(mssql varchar(20),mysql varchar(20))
  
INSERT INTO @tbtype(mssql,mysql) values( 'bigint','bigint'),('binary','binary'),('binary','binary'),('bit','tinyint'),('char','char'),('date','date'),('datetime','datetime'),('datetime2','datetime'),('datetimeoffset','datetime'),('decimal','decimal'),('float','float'),('int','int'),('money','decimal'),('nchar','char'),('ntext','text'),('numeric','decimal'),('nvarchar','varchar'),('real','float'),('smalldatetime','datetime'),('smallint','smallint'),('smallmoney','decimal'),('text','text'),('time','time'),('timestamp','timestamp'),('tinyint','tinyint'),('uniqueidentifier','varchar(40)'),('varbinary','varbinary'),('varchar','varchar'),('xml','text')
  

  
DECLARE @tb_exec_sql table(tbname varchar(100),sql nvarchar(max),indexs nvarchar(max))
  
DECLARE @indexs_sql nvarchar(max)
  

  
--转化表格SQL
  
DECLARE NAME CURSOR FOR
  

  
SELECT tbname FROM @tab_tablename
  
OPEN NAME
  
FETCH NEXT FROM name INTO @tbname
  
WHILE @@FETCH_STATUS =0
  
BEGIN
  
;WITH data AS (
  
SELECT
  
case when b.is_unique=1 then ' UNIQUE ' else ' ' end is_unique,
  
OBJECT_NAME(A.OBJECT_ID) obj_name,
  
COL_NAME(A.object_id,A.column_id) colname,
  
SUBSTRING(COL_NAME(A.object_id,A.column_id),1,3) col_short,
  
is_included_column,
  
index_column_id,
  
a.index_id,
  
A.OBJECT_ID
  
FROM SYS.index_columns A INNER JOIN SYS.INDEXES B ON A.OBJECT_ID=B.OBJECT_ID AND A.index_id=B.index_id
  
WHERE b.type!=1 and OBJECT_NAME(A.OBJECT_ID)=@tbname
  
)
  
SELECT
  
@indexs_sql=
  
REPLACE(
  
(STUFF(
  
(
  
SELECT
  
' CREATE '
  
+ a.is_unique
  
+' INDEX '
  
+ CASE WHEN COUNT(*) >=3 THEN SUBSTRING(('IX_'+stuff((SELECT '_'+col_short FROM data b where a.object_id=b.object_id and a.index_id=b.index_id FOR XML PATH('')),1,1,'')),1,64)
  
ELSE 'IX_'+stuff((SELECT '_'+colname FROM data b where a.object_id=b.object_id and a.index_id=b.index_id FOR XML PATH('')),1,1,'')
  
END
  
+' ON '
  
+ a.obj_name
  
+'( '
  
+ stuff((SELECT ','+colname FROM data b where a.object_id=b.object_id and a.index_id=b.index_id FOR XML PATH('')),1,1,'')
  
+' );
  
'
  
FROM data a
  
GROUP BY a.is_unique,a.obj_name,a.object_id,a.index_id
  
ORDER BY a.object_id,a.index_id
  
FOR XML PATH('')
  

  
),1,1,'')
  
),'
','')
  

  

  
INSERT INTO @tb_exec_sql(tbname,indexs,sql)
  
SELECT
  
@tbname,@indexs_sql,
  
'CREATE TABLE '+@tbname+'('+
  
REPLACE(
  
STUFF( (
  
SELECT
  
','+a.name
  
+
  
case when b.name = 'timestamp' then ' timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP '
  
when b.name = 'uniqueidentifier' then ' varchar(40) '
  
when b.name in ('char','nchar','nvarchar','varbinary','varchar') then ( case when a.length<0 then ' text ' else ' '+c.mysql+'('+ (case when b.name like 'n%' then cast(a.length/2 as varchar(10)) else cast(a.length as varchar(10)) end )+')'  end )
  
when b.name in ('decimal','float','money','numeric','smallmoney') then ' '+c.mysql+'('+ cast(a.prec as varchar(10)) +','+ cast(a.scale as varchar(10)) +') '
  
else ' '+c.mysql+' ' end
  
+
  
case when a.isnullable=0 then ' not null ' else ' null ' end
  
+
  
case when COLUMNPROPERTY( A.ID,A.NAME,'ISIDENTITY')=1 then ' auto_increment ' else '' end
  
+
  
case when a.length<0 or b.name in ('text') then ' '
  
when e.text like ' ((%' then ' default '+substring(e.text,3,len(e.text)-4)
  
when e.text like ' (''%' then ' default '+substring(e.text,2,len(e.text)-2)
  
else ' '
  
end
  
+
  
ISNULL(' comment "'+cast(g.value as varchar(1000))+'"
  
','
  
')
  

  
FROM sys.syscolumns A
  
LEFT JOIN sys.systypes B ON A.XUSERTYPE=B.XUSERTYPE
  
LEFT JOIN @tbtype C ON b.name collate Chinese_PRC_CI_AS  = c.mssql
  
LEFT JOIN sys.sysobjects D ON A.ID=D.ID AND D.XTYPE='U' AND D.NAME<>'DTPROPERTIES'
  
LEFT JOIN sys.syscomments E ON A.CDEFAULT=E.ID
  
LEFT JOIN sys.extended_properties G ON A.ID=G.major_id AND A.COLID=G.minor_id
  
WHERE D.NAME =@tbname
  
order by a.colid
  
FOR XML PATH('')
  
),1,1,'')
  
,'&#x0D;','')
  
+
  
ISNULL(
  

  
( SELECT
  

  
', primary key ('+STUFF(
  
(
  
SELECT
  

  
','+col_name(i.object_id,ik.column_id)
  
FROM sys.indexes i
  
JOIN sys.index_columns ik ON i.index_id=ik.index_id and i.object_id=ik.object_id
  
WHERE i.type=1 and i.object_id=object_id(@tbname)
  
ORDER BY key_ordinal
  
FOR XML PATH('')
  
),1,1,'')
  

  
+') '
  
)
  
,'')
  
+
  
')'
  
+
  
ISNULL( (
  
SELECT
  
' COMMENT "'+CAST(value AS VARCHAR(1000))+'";
  
'
  

  
FROM sys.extended_properties
  

  
where major_id=object_id(@tbname) and minor_id=0
  
),';')
  

  
FETCH NEXT FROM NAME INTO @tbname
  
END
  
CLOSE NAME
  
DEALLOCATE NAME
  

  

  
SELECT * FROM @tb_exec_sql

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-423723-1-1.html 上篇帖子: SQL SERVER Buffer Pool扩展 下篇帖子: 浅析SQL Server在可序列化隔离级别下,防止幻读的范围锁的锁定问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表