注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

零售创新,创新那些事儿,SPSS,VBA

零售创新

 
 
 

日志

 
 
关于我

新浪微博,零售创新 研究经理,数据分析师 希望和市场研究和零售业的同事共同进步! 本博客发表的都是免费或试用的资料,如果有版权问题请发邮件wangli12a@163.com联系删除。 spss excel vba blog

网易考拉推荐

SQL Server 数据库应用程序的无值守部署  

2013-04-02 17:15:02|  分类: 数据库 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
SQL Server 数据库应用程序的无值守部署

一、引言

软件部署是一个获得应用程序并将它安装到另一台机器上的过程,一般通过安装程序完成。一个项目完成之后,在软件交互发布前,安装程序的制作是一个必要的过程。由于Microsoft SQL Server 2000的低成本、可管理性和易维护性,现在很多数据库应用程序都是基于SQL Server 2000数据库平台运行的,但对于最终用户而言,部署SQL Server 2000数据库环境却是一件很复杂的事情,因此设计人员在安装打包时,应充分考虑不同用户使用相同的SQL Server 2000安装配置等情况,减少软件发布成本,实现软件部署的“傻瓜化”。

二、设计

在默认情况下,当使用SQL Server 2000的安装程序屏幕进行值守安装时,所指定的所有选项都被记录进安装程序初始化文件(setup.iss)中,该文件存放在系统根目录(%windir%)下,用于为以后提供安装设置。而通过调用程序执行该文件,即可实现SQL Server 2000的无值守安装,整个安装过程基本不需要用户的干预,在 MicrosoftSQL Server? 2000 安装光盘中提供了示例的批处理文件(如Sqlins.bat)和安装程序初始化文件(如Sqlins.iss)。在安装完毕数据库后,就可通过SQL Serverosql.exe 实用工具执行Transact-SQL 语句、系统存储过程和脚本文件实现数据库实例的初始化。以下是具体的实施步骤:

1步:通过注册表判断SQL Server是否已经安装,如果已经安装,则启动服务器(第4步)。

2步:通过调用批处理文件等方式执行SQL Server的安装命令:setupsql.exe -s -m -SMS -f1 " setup.iss"

3步:建一个循环,通过进程来判断安装程序的结束,一旦结束则启动服务器(第4步)。

4步:通过进程或服务判断SQL Server服务是否已经启动,如果已经启动则配置数据库(第5步),否则调用sqlservr.exe程序或Windows服务启动服务。

5步:通过批处理文件等方式调用SQL Serverosql.exe命令执行外部SQL脚本文件(该文件通过调用“CREATE DATABASECREATE DEVICERESTORE DATABASE”等Transact-SQL语句和“sp_dropdevicesp_addumpdevicesp_attach_db”等系统存储过程,实现数据库初始数据文件与日志文件的导入),将初始的数据库附加到服务器上。

6步:建一个循环,通过进程来判断配置程序的结束,一旦结束则启动服务器,安装应用程序。

三、编码

设计人员需要把执行SQL Server安装命令的批处理文件setup.bat、经过值守安装后并记录在系统根目录(%windir%)的安装程序初始化文件setup.iss、数据库初始化文件MyInstance.mdf(假设数据库实例名为MyInstance)、应用系统安装文件Setup.exe一起发布至Microsoft SQL Server 2000安装根目录下。

其中setup.bat文件的内容为:

@echo on

start /wait x86\setup\setupsql.exe -s -m -SMS -f1 "setup.iss"

@echo off

1.功能实现的核心代码

//-从注册表中检索是否安装 Microsoft SQL Server 2000 数据库-///

procedure TForm1.FormCreate(Sender: TObject);

var

Registry: TRegistry;

begin

Registry := TRegistry.Create;

Registry.RootKey := HKEY_LOCAL_MACHINE;

if Registry.OpenKey('\SOFTWARE\Microsoft\MSSQLServer\Setup', False) then

//-从注册表中检索是否安装 MyInstance 数据库实例-

if not FileExists(Registry.ReadString('SQLDataRoot') + '\Data\MyInstance_Data.mdf') then

BitBtn2Click(nil);

else//没有安装 Microsoft SQL Server 2000 数据库

BitBtn1Click(nil);

Registry.Free;

end;

///-安装 SQL Server 2000数据库-///

procedure TForm1.BitBtn1Click(Sender: TObject);

var

sBatFileName: string;

iWinExecAndWait32: Integer;

begin

if Application.MessageBox('确认执行"安装 SQL Server 2000数据库"吗?', '提示', MB_YESNO + MB_ICONINFORMATION) = IDNO then

Exit;

//-生成调用osql.exe命令的批处理文件setup.bat'并等待其执行完毕-

sBatFileName := ExtractFileDir(ParamStr(0)) + '\setup.bat';

iWinExecAndWait32 := WinExecAndWait32(sBatFileName, SW_HIDE);

if iWinExecAndWait32 = 0 then

begin

//-启动MSSQLSERVER服务并等待-

RunService('MSSQLSERVER');

Sleep(6000);

Application.MessageBox('"安装 SQL Server 2000数据库"执行完毕!', '提示', MB_OK + MB_ICONINFORMATION);

///-配置 SQL Server 2000数据库-

BitBtn2Click(nil);

end;

end;

///-配置 SQL Server 2000数据库-///

procedure TForm1.BitBtn2Click(Sender: TObject);

var

Registry: TRegistry;

sCrlf, sMdfFileName, sSQL, sDataInstallLocation: string;

slSQL, slBAT: TStringList;

iWinExecAndWait32: Integer;

begin

if QueryServiceState('MSSQLSERVER') = 0 then

begin

if Application.MessageBox('确认执行"配置 SQL Server 2000数据库"吗?', '提示', MB_YESNO + MB_ICONINFORMATION) = IDNO then

Exit;

//-启动MSSQLSERVER服务并等待-

if QueryServiceState('MSSQLSERVER') = 0 then

begin

RunService('MSSQLSERVER');

Sleep(5000);

end;

///-配置MyInstance数据库-///

sCrlf := Chr(13) + Chr(10);

sMdfFileName := ExtractFilePath(ParamStr(0)) + '\MyInstance.mdf';

Registry := TRegistry.Create;

Registry.RootKey := HKEY_LOCAL_MACHINE;

Registry.OpenKey('\SOFTWARE\Microsoft\MSSQLServer\Setup', False);

sDataInstallLocation := Registry.ReadString('SQLDataRoot') + '\Data\MyInstance_Data.mdf';

Registry.Free;

//-生成SQL文件,并保存临时文件-

sSQL := 'USE master' + sCrlf +

'if not exists (select * from sysdatabases where name=''MyInstance'')' + sCrlf +

'CREATE DATABASE MyInstance' + sCrlf +

'if exists (select * from sysdevices where name=''MyInstance'')' + sCrlf +

'EXEC sp_dropdevice ''MyInstance''' + sCrlf +

'EXEC sp_addumpdevice ''disk'', ''MyInstance'', ''' + sDataInstallLocation + '''' + sCrlf +

'RESTORE DATABASE MyInstance' + sCrlf +

'FROM DISK=''' + sMdfFileName + '''' + sCrlf +

'WITH REPLACE';

slSQL := TStringList.Create;

slSQL.Add(sSQL);

slSQL.SaveToFile('c:\temp1.sql');

slSQL.Clear;

//-生成并执行调用osql.exe命令的批处理文件-

slBAT:= TStringList.Create;

slBAT.Add('@echo off');

slBAT.Add('osql.exe -E -S -i "c:\temp1.sql"' + ' -o "c:\result1.txt"');

slBAT.Add('exit');

slBAT.SaveToFile('c:\temp1.bat');

slBAT.Clear;

iWinExecAndWait32 := WinExecAndWait32('c:\temp1.bat', SW_HIDE);

if iWinExecAndWait32 = 0 then

begin

Application.MessageBox('"配置 SQL Server 2000数据库"执行完毕!', '提示', MB_OK + MB_ICONINFORMATION);

///-安装 xxxxxxxxxx信息管理系统-

BitBtn3Click(nil);

end;

end;

end;

///-安装 xxxxxxxxxx信息管理系统-///

procedure TForm1.BitBtn3Click(Sender: TObject);

var

sExeFileName: string;

iWinExecAndWait32: Integer;

begin

if Application.MessageBox('确认执行"安装 xxxxxxxxxx信息管理系统"吗?', '提示', MB_YESNO + MB_ICONINFORMATION) = IDNO then

Exit;

//-执行系统安装程序-

sExeFileName := ExtractFilePath(ParamStr(0)) + '\Setup.exe';

iWinExecAndWait32 := WinExecAndWait32(sExeFileName, SW_SHOW);

if iWinExecAndWait32 = 0 then

begin

Application.MessageBox('"安装 xxxxxxxxxx信息管理系统"执行完毕!', '提示', MB_OK + MB_ICONINFORMATION);

end;

end;

2.调用的几个关键函数和过程的核心代码

///-执行一个外部程序并等待其执行结束-///

function WinExecAndWait32(FileName: string; Visibility: Integer): Cardinal;

var

zAppName: array[0..512] of char;

zCurDir: array[0..255] of char;

WorkDir: string;

StartupInfo: TStartupInfo;

ProcessInfo: TProcessInformation;

Msg: TagMsg;

ExitCode: cardinal;

begin

StrPCopy(zAppName, FileName);

GetDir(0, WorkDir);

StrPCopy(zCurDir, WorkDir);

FillChar(StartupInfo, Sizeof(StartupInfo), #0);

StartupInfo.cb := Sizeof(StartupInfo);

StartupInfo.dwFlags := STARTF_USESHOWWINDOW;

StartupInfo.wShowWindow := Visibility;

if CreateProcess(nil, zAppName, nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then

begin

repeat

while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do

begin

if (Msg.message = WM_QUIT) then

Result := Msg.wParam;

TranslateMessage(msg);

Dispatchmessage(msg);

Sleep(100);

end;

GetExitCodeProcess(ProcessInfo.hProcess, ExitCode);

until (ExitCode <> STILL_ACTIVE);

CloseHandle(ProcessInfo.hThread);

CloseHandle(ProcessInfo.hProcess);

Result := 0;

end

else

Result := GetLastError;

end;

///-查询某一Windows服务-///

function QueryServiceState(ServiceName: String): Cardinal;

var

svcmgr, svc: Integer;

temp: _SERVICE_STATUS;

begin

svcmgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);

if svcmgr = 0 then

begin

Result := 0;

Exit;

end;

svc := OpenService(svcmgr, PChar(ServiceName), SERVICE_ALL_ACCESS);

if svc = 0 then

begin

CloseServiceHandle(svcmgr);

Result := 0;

Exit;

end;

QueryServiceStatus(svc, temp);

if temp.dwCurrentState = SERVICE_STOPPED then

Result := 1

else

Result := 0;

CloseServiceHandle(svcmgr);

CloseServiceHandle(svc);

if (Result <> 1) and (Result <> 0) then

Result := 1;

end;

///-启动某一Windows服务-///

Procedure RunService(ServiceName: String);

var

svcmgr, svc: Integer;

temp: _SERVICE_STATUS;

s: Pchar;

begin

svcmgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);

if svcmgr = 0 then

Exit;

svc := OpenService(svcmgr, PChar(ServiceName), SERVICE_ALL_ACCESS);

if svc = 0 then

begin

CloseServiceHandle(svcmgr);

Exit;

end;

QueryServiceStatus(svc, temp);

if temp.dwCurrentState = SERVICE_STOPPED then

StartService(svc, 0, s);

CloseServiceHandle(svcmgr);

CloseServiceHandle(svc);

end;

四、结语

本文介绍了使用Delphi实现一个完整的Microsoft SQL Server 2000数据库应用程序的部署过程,包括数据库全部自动安装运行,基本不需要用户的干预。以上所有程序在Delphi7.0SQL Server 2000环境下调试通过。

  评论这张
 
阅读(1166)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017