MSSQL编程:对照两个数据库的表布局差别
上面我们说了DML的闪回方案。但对于DDL却无能为力,对于大多数的DDL,即使是rowbase格式,二进制日志binlog中仍只记录语句本身。对于删表操作,只记录一个语句droptablet。仅凭这句话,无法还原表的数据。对照|数据|数据库/*--对照两个数据库的表布局差别
--*/
/*--挪用示例
execp_comparestructurexzkh_model,xzkh_new
--*/
ifexists(select*fromdbo.sysobjectswhereid=object_id(N.)andOBJECTPROPERTY(id,NIsProcedure)=1)
dropprocedure.
GO
createprocp_comparestructure
@dbname1varchar(250),--要对照的数据库名1
@dbname2varchar(250)--要对照的数据库名2
as
createtable#tb1(表名1varchar(250),字段名varchar(250),序号int,标识bit,主键bit,范例varchar(250),
占用字节数int,长度int,小数位数int,同意空bit,默许值varchar(500),字段申明varchar(500))
createtable#tb2(表名2varchar(250),字段名varchar(250),序号int,标识bit,主键bit,范例varchar(250),
占用字节数int,长度int,小数位数int,同意空bit,默许值varchar(500),字段申明varchar(500))
--失掉数据库1的布局
exec(insertinto#tb1SELECT
表名=d.name,字段名=a.name,序号=a.colid,
标识=casewhena.status=0x80then1else0end,
主键=casewhenexists(SELECT1FROM+@dbname1+..sysobjectswherextype=PKandnamein(
SELECTnameFROM+@dbname1+..sysindexesWHEREindidin(
SELECTindidFROM+@dbname1+..sysindexkeysWHEREid=a.idANDcolid=a.colid
)))then1else0end,
范例=b.name,占用字节数=a.length,长度=a.prec,小数位数=a.scale,同意空=a.isnullable,
默许值=isnull(e.text,),字段申明=isnull(g.,)
FROM+@dbname1+..syscolumnsa
leftjoin+@dbname1+..systypesbona.xtype=b.xusertype
innerjoin+@dbname1+..sysobjectsdona.id=d.idandd.xtype=Uandd.namedtproperties
leftjoin+@dbname1+..syscommentseona.cdefault=e.id
leftjoin+@dbname1+..syspropertiesgona.id=g.idanda.colid=g.smallid
orderbya.id,a.colorder)
--失掉数据库2的布局
exec(insertinto#tb2SELECT
表名=d.name,字段名=a.name,序号=a.colid,
标识=casewhena.status=0x80then1else0end,
主键=casewhenexists(SELECT1FROM+@dbname2+..sysobjectswherextype=PKandnamein(
SELECTnameFROM+@dbname2+..sysindexesWHEREindidin(
SELECTindidFROM+@dbname2+..sysindexkeysWHEREid=a.idANDcolid=a.colid
)))then1else0end,
范例=b.name,占用字节数=a.length,长度=a.prec,小数位数=a.scale,同意空=a.isnullable,
默许值=isnull(e.text,),字段申明=isnull(g.,)
FROM+@dbname2+..syscolumnsa
leftjoin+@dbname2+..systypesbona.xtype=b.xusertype
innerjoin+@dbname2+..sysobjectsdona.id=d.idandd.xtype=Uandd.namedtproperties
leftjoin+@dbname2+..syscommentseona.cdefault=e.id
leftjoin+@dbname2+..syspropertiesgona.id=g.idanda.colid=g.smallid
orderbya.id,a.colorder)
--andnotexists(select1from#tb2where表名2=a.表名1)
select对照了局=casewhena.表名1isnullandb.序号=1then库1短少表:+b.表名2
whenb.表名2isnullanda.序号=1then库2短少表:+a.表名1
whena.字段名isnullandexists(select1from#tb1where表名1=b.表名2)then库1[+b.表名2+]短少字段:+b.字段名
whenb.字段名isnullandexists(select1from#tb2where表名2=a.表名1)then库2[+a.表名1+]短少字段:+a.字段名
whena.标识b.标识then标识分歧
whena.主键b.主键then主键设置分歧
whena.范例b.范例then字段范例分歧
whena.占用字节数b.占用字节数then占用字节数
whena.长度b.长度then长度分歧
whena.小数位数b.小数位数then小数位数分歧
whena.同意空b.同意空then是不是同意空分歧
whena.默许值b.默许值then默许值分歧
whena.字段申明b.字段申明then字段申明分歧
elseend,
*
from#tb1a
fulljoin#tb2bona.表名1=b.表名2anda.字段名=b.字段名
wherea.表名1isnullora.字段名isnullorb.表名2isnullorb.字段名isnull
ora.标识b.标识ora.主键b.主键ora.范例b.范例
ora.占用字节数b.占用字节数ora.长度b.长度ora.小数位数b.小数位数
ora.同意空b.同意空ora.默许值b.默许值ora.字段申明b.字段申明
orderbyisnull(a.表名1,b.表名2),isnull(a.序号,b.序号)--isnull(a.字段名,b.字段名)
go
两个到底是哪一个给出了MySQL这个名字至今依然是个迷,包括开发者在内也不知道。 其中最有名的应该是row_number了。这个终于解决了用临时表生成序列号的历史,而且SQLServer2005的row_number比Oracle的更先进。因为它把Orderby集成到了一起,不用像Oracle那样还要用子查询进行封装。 习惯敲命令行的朋友可能会爽一些。但是功能有限。适合机器跑不动SQLServerManagementStudio的朋友使用。 如果我们从集合论(关系代数)的角度来看,一张数据库的表就是一组数据元的关系,而每个SQL语句会改变一种或数种关系,从而产生出新的数据元的关系(即产生新的表)。 是否碎片会引发效率问题?这都是需要进一步探讨的东西。varbinary(max)代替image也让SQLServer的字段类型更加简洁统一。 作了些试验,发现使用CLR的存储过程或函数在达到一定的阀值的时候,系统性能会呈指数级下滑!这是非常危险的!只使用几个可能没有问题,当一旦大规模使用会造成严重的系统性能问题! 但换公司用MSSQL2K感觉自己好像根本就不了解MSSQL。什么DTS触发器以前根本没用过。 SQL语言是学习所有数据库产品的基础,无论你是做数据库管理还是做数据库开发都是这样。不过具体学习的侧重点要看你将来做哪一块,如果是做数据库管理(DBA),侧重点应该放在SQLServer的系统管理上. 比如,MicrosoftSQLServer2008的某一个版本可以满足现在的这个业务的需要,而且价格还比Oracle11g要便宜,那么这一产品就是适合的。
页:
[1]