我是个负责数据库应用的开发人员,昨夜和旧同事电话聊天中谈到了一个
大家共同的苦恼:因为几乎每天都要将自己的数据库项目生成sql scripts
以供备份存档或发给客户更新,所以生成sql scripts就成了每天的必修课。
而sqlserver的企业管理器又无法支持将生成sql scripts的过程保存为一个设置
文件,每次都必须做许多相同的工作,
如:选择对象呀、设置格式呀、表脚本选项、文件选项。。老是重复这样的操作
实在太麻烦了!电话闲聊完后就想:能不能写个小工具,在可以提供sqlserver
企业管理器所支持所有功能外,再增加个支持将各个选项的设置保存为
配置文件(如:ini或xm格式)的功能呢?这样我以后只要选取不同的配置文件就可以
直接生成出自己需要的scripts格式,那样多好呀。。。
但如何实现scripts的生成呢?就考虑使用下以前很少用的sql-dmo吧!
心动不如行动,虽然夜已深,但有新鲜的体验总让我精神抖擞。。。呵呵,好了
不废话了。。就先简单地谈谈如何使用sql-dmo来实现自己的需求吧~~~~
(代码示例使用pascal语言表述)
1. 枚举局域网内所有的sqlserver实例
函数:
function getallserverinstances :tstringlist;
var
oapplication ,
osevernamelist : variant ;
i : integer ;
snamelist : tstringlist ;
begin
snamelist := tstringlist.create ;
oapplication := createoleobject (sqldmo.application) ;
osevernamelist := oapplication.listavailablesqlservers ;
for i:= 1 to osevernamelist.count do
snamelist.append (osevernamelist.item(i)) ;
result := snamelist ;
oapplication := null;
osevernamelist := null;
end;
2.登陆到指定的sqlserver实例
函数:
function loginserverinstances (sserver,suser,spassword :string):variant;
var
osqlserver : variant ;
begin
osqlserver := createoleobject (sqldmo.sqlserver);
osqlserver.logintimeout := 30;
osqlserver.loginsecure := false;
osqlserver.autoreconnect := true;
osqlserver.connect(sserver,suser,spassword);
result := osqlserver;
osqlserver := null ;
end;
以上两个函数可以帮助我们完成取得局域网内所有的sqlserver实例并且
登陆上一个指定的实例。接下来就看看如何取得指定数据库的表名称和存储
过程名称 :
3.枚举指定sqlserver实例所有database的名称
函数:
function getalldatabasenamelist (osqlserver : variant ):tstringlist;
var
snamelist : tstringlist ;
i : integer;
begin
snamelist := tstringlist.create ;
for i:= 1 to osqlserver.databases.count do
snamelist.append (osqlserver.databases.item(i).name) ;
result := snamelist ;
end;
4.枚举指定数据库所有table的名称
函数:
function getalltablenamelist (osqlserver : variant ; sdatabasename : string ):tstringlist;
var
odatabase : variant ;
snamelist : tstringlist ;
i : integer;
begin
snamelist := tstringlist.create ;
odatabase := createoleobject (sqldmo.database);
odatabase := osqlserver.databases.item(sdatabasename);
for i:= 1 to odatabase.tables.count do
snamelist.append (odatabase.tables.item(i).name) ;
result := snamelist ;
odatabase := null ;
end;
5.枚举指定数据库所有storeprocedure的名称
函数:
function getallstoreprocedurenamelist (osqlserver : variant ; sdatabasename : string ):tstringlist;
var
odatabase : variant ;
snamelist : tstringlist ;
i : integer;
begin
snamelist := tstringlist.create ;
odatabase := createoleobject (sqldmo.database);
odatabase := osqlserver.databases.item(sdatabasename);
for i:= 1 to odatabase.storedprocedures.count do
snamelist.append (odatabase.storedprocedures.item(i).name) ;
result := snamelist ;
odatabase := null ;
end;
通过以上3个函数就可以把生成scripts前的准备工作做好了,然后就可以开始
着重了解如何生成scripts了。scripts也同样是sql-dmo某些对象的method。这些
对象如:database,view ,storedprocedure ,trigger ,check 等等。
scripts method 的syntax是:
object.script( [ scripttype ] [, scriptfilepath ] [, script2type ] ) as string
scripttype (integer type) 参数是来设定产生什么内容的scripts ,如对其赋值sqldmoscript_default,
这样就产生的是 该对象普通的脚本,如storedprocedure object,那肯定就是
其create storedprocedure 的内容咯。如果赋值sqldmoscript_drops的话,
那就产生的是drop object的内容。关于scripttype,script2type (integer type)
这个参数的详细使用可以 参阅 : c:\program files\microsoft sql server\80\tools\books qldmo.chm
的帮助文件。script方法的返回值是文本类型,不管你填不填scriptfilepath参数,
你都能得到该文本,也就是script 的内容。
而table ,userdefineddatatype 这两个对象生成scripts的method比较特殊,
它们调用的是generatesql method,其syntax是:
object.generatesql( database ) as string ,比较简单没有过多的参数,返回值
也是script 的内容。
建议:把scripttype,script2type两个参数可以赋予的值做成常量,这样在程序
中调用更直观些。如:sqldmoscript_databasepermissions = 32;
sqldmoscript_default = 4; ….
根据上面的说明可以建立这个函数(在申明此函数时填加overload表示同名不同参函数的重载):
file://6.生成指定objects的sql scripts
file://(osqlobjcet : database,view ,storedprocedure ,trigger ,check)
// sscriptfilepath defalut is
function getthisobjectscripts (osqlobjcet : variant ;sscriptfilepath : string ;
iscripttype,iscript2type : integer) : string ;
begin
result := osqlobjcet.script(iscripttype,sscriptfilepath,iscript2type) ;
end;
file://7.生成指定objects的sql scripts
// overload method
file://(osqlobjcet : table ,userdefineddatatype)
function tform1.getthisobjectscripts (odatabase ,osqlobjcet : variant ) : string ;
begin
result := osqlobjcet.generatesql(odatabase) ;
end;
调用的时候可以根据界面选择生成什么样格式的对象就传入相应的参数
写个简单的例子,取出master的存储过程ms_sqlctrs_users的内容:
procedure tform1.button4click(sender: tobject);
var
osqlserver,
odatabase,
ostoredprocedure : variant ;
returnstr : string;
begin
odatabase := createoleobject (sqldmo.database);
osqlserver := loginserverinstances(david,sa,);
odatabase := osqlserver.databases.item(master);
ostoredprocedure := osqlserver.databases.item(master).storedprocedures.item(ms_sqlctrs_users);
file://生成create procedure的scripts,将第一个4换成1就成了drop procedure的 scripts了
returnstr := getthisobjectscripts(ostoredprocedure,,4,4);
showmessage(returnstr);
end;
如果多个对象都需要导出 scripts 话,可以用个string 变量保存被循环调用的
getthisobjectscripts过程,就可以实现导出多个对象的脚本了!
关于保存和取出配置生成scripts的过程,我想不用详细描述了吧?
只需把设置好的控件状态保存到配置文件中,并且可以调用配置文件
反向对控件状态来设置,这样就简单的实现了自定义的过程呀。
呵呵,到这里就进入尾声了,通过组合上面这些函数,
并且设置合理的界面调用,这程序应该很容易完成吧~~~~
既然这样,那让我们为提供自己工作效率而建立更多小工具呀!
更多详情,请参阅 :
c:\program files\microsoft sql server\80\tools\books qldmo.chm
