简述

InstallShield已经内建了对MySQL和Oracle的支持。但是这个功能是通过ODBC实现的,它对SQL脚本的格式要求非常严格,因此已经通过官方客户端测试的脚本在IS中执行时往往就会报错。

一般来说,数据库脚本只保证通过官方客户端测试即可,同时维护一份供IS执行的脚本费时费力。因此,考虑安装程序对两数据库的支持通过官方客户端实现。

MySQL

 
function InstallMySQLComponent(szComponent)
NUMBER nResult;
STRING szServer,szDB,szUser,szPassword,sCMD,sOPT,sResult1,sResult2,svLine,sMsg,sPath;
NUMBER nvFileHandle,nvCount;
LIST listStatus;
begin
sMsg = '安装'+szComponent+' ...';
SdShowMsg(sMsg, TRUE);
// source命令不认识windows路径中的反斜杠,故将SRCDIR中的反斜杠替换成斜杠
sPath = SRCDIR;
StrReplace(sPath, '//', '/', );
// Fetch database connection information
SQLRTGetConnectionInfo( 'mysql', szServer, szDB, szUser, szPassword );
sCMD = WINSYSDIR^'cmd.exe';
sOPT = ' /c '+SRCDIR^'mysql.exe -h'+szServer+' -u'+szUser+' -p'+szPassword+' -D'+szDB;
sOPT = sOPT+' -e "source '+sPath^szComponent+'.sql" > '+SRCDIR^'dbstatus.txt 2>&1';
// Execute the script associated with the given component in database
nResult=LaunchAppAndWait(sCMD, sOPT, WAIT|LAAW_OPTION_HIDDEN);
if (nResult < ) then
MessageBox('Failed installing '+szComponent+' !', SEVERE);
abort;
endif;
// 关闭安装提示
SdShowMsg('', FALSE);
// Read dbstatus.txt
OpenFileMode(FILE_MODE_NORMAL);
if (OpenFile(nvFileHandle, SRCDIR, 'dbstatus.txt')<) then
MessageBox('Failed checking the status of installing '+szComponent+' !', SEVERE);
abort;
endif;
listStatus = ListCreate(STRINGLIST);
while GetLine(nvFileHandle, svLine) =
ListAddString(listStatus, svLine, AFTER);
endwhile;
CloseFile(nvFileHandle);
// Count how many lines fetched from dbstatus.txt
nvCount = ListCount(listStatus);
if nvCount > then
sMsg = "更新数据库出错,点“是”打开日志文件并退出安装,点“否”直接退出安装。/n";
sMsg = sMsg+"若错误可忽略,可选择数据库类型“none”以跳过数据库更新并直接更新程序,/n";
sMsg = sMsg+"然后在数据库中手工执行SQL脚本(安装后保存在script目录下)";
nResult = AskYesNo(sMsg, YES);
if (nResult = YES) then
LaunchApp(WINSYSDIR^'notepad.exe', SRCDIR^'dbstatus.txt');
endif;
abort;
endif;
end;

Oracle

 
function InstallOracleComponent(szComponent)
NUMBER nResult,nvFileHandle,nIndex,nvCount;
STRING sMsg,szServer,szDB,szUser,szPassword,sCMD,sOPT,sInstance,sTmp,svLine;
LIST listStatus;
begin
sMsg = '安装'+szComponent+' ...';
SdShowMsg(sMsg, TRUE);
// Fetch database connection information
SQLRTGetConnectionInfo( 'oracle', szServer, szDB, szUser, szPassword );
nIndex = StrFind(szServer, ':');
nIndex = StrFindEx(szServer, '/', nIndex);
StrSub(sInstance, szServer, nIndex+, );
sCMD = WINSYSDIR^'cmd.exe';
sOPT = ' /c '+'sqlplus.exe -L -S '+szUser+'/'+szPassword+'@'+sInstance;
sOPT = sOPT+' @'+SRCDIR^szComponent+'.sql > '+SRCDIR^'dbstatus.txt 2>&1';
// Execute the script associated with the given component in database
nResult=LaunchAppAndWait(sCMD, sOPT, WAIT|LAAW_OPTION_HIDDEN);
if (nResult < ) then
MessageBox('Failed installing '+szComponent+' !', SEVERE);
abort;
endif;
// 关闭安装提示
SdShowMsg('', FALSE);
// 在dbstatus.txt中查询字符串holytail,如果存在,说明脚本已执行完
if (FileGrep(SRCDIR^'dbstatus.txt', 'holytail', svLine, nIndex, RESTART) = ) then
// 在dbstatus.txt中查询字符串ORA-,如果存在,说明脚本执行出现错误
if (FileGrep(SRCDIR^'dbstatus.txt', 'ORA-', svLine, nIndex, RESTART) = ) then
sMsg = "更新数据库出错,点“是”打开日志文件并退出安装,点“否”直接退出安装。/n";
sMsg = sMsg+"若错误可忽略,可选择数据库类型“none”以跳过数据库更新并直接更新程序,/n";
sMsg = sMsg+"然后在数据库中手工执行SQL脚本(安装后保存在script目录下)";
nResult = AskYesNo(sMsg, YES);
if (nResult = YES) then
LaunchApp(WINSYSDIR^'notepad.exe', SRCDIR^'dbstatus.txt');
endif;
abort;
endif;
else
sMsg = "更新数据库出错,点“是”打开日志文件并退出安装,点“否”直接退出安装。/n";
sMsg = sMsg+"若错误可忽略,可选择数据库类型“none”以跳过数据库更新并直接更新程序,/n";
sMsg = sMsg+"然后在数据库中手工执行SQL脚本(安装后保存在script目录下)";
nResult = AskYesNo(sMsg, YES);
if (nResult = YES) then
LaunchApp(WINSYSDIR^'notepad.exe', SRCDIR^'dbstatus.txt');
endif;
abort;
endif;
end;

总结

  1. 为便于获取脚本在数据库中的执行结果,故通过官方客户端执行脚本时通过符号“>”将客户端的输出信息重定向到dbstatus.txt中;同时,使用“2>&1”将标准错误输出重定向到标准输出设备上,当然,会进一步重定向到dbstatus.txt文件中,否则,无法获取出错信息。
  2. sqlplus执行SQL脚本后不会自动退出,故应在Oracle的脚本后加上语句“exit;”。
  3. 重载OnSQLComponentInstalled()函数,并在其中禁止MySQL和Oracle的SQL脚本对应的Component被执行安装,然后通过以上两个函数更新数据库。

InstallShield在MySQL和Oracle中执行SQL脚本的方法InstallShield在MySQL和Oracle中执行SQL脚本的方法的更多相关文章

  1. Mybaits 源码解析 (七)----- Select 语句的执行过程分析(下篇)(Mapper方法是如何调用到XML中的SQL的?)全网最详细,没有之一

    我们上篇文章讲到了查询方法里面的doQuery方法,这里面就是调用JDBC的API了,其中的逻辑比较复杂,我们这边文章来讲,先看看我们上篇文章分析的地方 SimpleExecutor public & ...

  2. Oracle是如何工作的?实例是如何响应用户请求?一条SQL的执行过程~

    Oracle 是如何工作的? Select id,name from t order by id ; – SQL 解析(查看语法是否错误,如果没有错误,分析语意,执行此语句的权限) – 执行计划(OR ...

  3. SQL Server 执行计划利用统计信息对数据行的预估原理以及SQL Server 2014中预估策略的改变

    前提  本文仅讨论SQL Server查询时, 对于非复合统计信息,也即每个字段的统计信息只包含当前列的数据分布的情况下, 在用多个字段进行组合查询的时候,如何根据统计信息去预估行数的. 利用不同字段 ...

  4. mysql中获取一天、一周、一月时间数据的各种sql语句写法

    今天抽时间整理了一篇mysql中与天.周.月有关的时间数据的sql语句的各种写法,部分是收集资料,全部手工整理,自己学习的同时,分享给大家,并首先默认创建一个表.插入2条数据,便于部分数据的测试,其中 ...

  5. PL/SQL中批量执行SQL脚本(不可把所有的语句都复制到New SQL Windows)

    PL/SQL中批量执行SQL脚本,不可把所有的语句都复制到New SQL Window,因为这样会导致缓冲区过大而进程卡死! 最好的办法是将要执行的SQL脚本存放到指定文件中,如C:\insert.s ...

  6. 如何将.SQL文件的数据导入到Mysql的数据库中

    一.用cmd的调试环境导入.sql文件中的数据: WinR键打开cmd输入: MySQL -u root -p 进入MySQL后MySQL>use DR;   MySQL> source  ...

  7. Thinkphp中查询复杂sql查询表达式,如何表达MYSQL中的某字段不为空is not null?

    Thinkphp中查询复杂sql查询表达式,如何表达MYSQL中的某字段不为空is not null?先上两种实现方式的实例:$querys["house_type_image"] ...

  8. oracle问题:新建了一个PDM文件,建表后生成的sql语句中含有clustered

    问题描述 为了在oracle中新增表,在PDM中建表,使用其生成的sql语句,但是建表不能成功,提示 ORA-00906: 缺失左括号 原因是多了clustered 关键字 情景重现 1. 新建一个p ...

  9. 【mybatis】service层中一个方法中使用mybatis进行数据库的 多个修改操作,可能是update也可能是delete操作,但是sql语句命名执行并且在控制台打印出来了,但是数据库中未更新到数据【事务的问题】

    问题描述: service层中一个方法中使用mybatis进行数据库的 多个修改操作,可能是update也可能是delete操作,但是sql语句命名执行并且在控制台打印出来了,但是数据库中未更新到数据 ...

随机推荐

  1. python的reduce函数的使用方法详解以及使用案例,相加,相乘(处理一个序列,然后把序列进程合并操作)

    1.求列表的数字相加之和,还是之前的习惯,写for循环来实现 num_1=[1,2,3,4,5,6,7,8,9] a=0 for n in num_1: #a=a+n a+=n print (a) C ...

  2. Go_13:Go常用功能总结一阶段

    1. go语言从键盘获取输入内容 <1. 最简单的办法是使用 fmt 包提供的 Scan 和 Sscan 开头的函数.请看以下程序: package main import "fmt& ...

  3. 四大开源协议比较:BSD、Apache、GPL、LGPL

    sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...

  4. webpack的基础入门

    webpack的基础入门 这里对于 webpack 的基础入门进行一些总结,可以参考 github 上的 webpack-demo ,链接是 https://github.com/RealAndMe/ ...

  5. Java并发编程原理与实战三十六:阻塞队列&消息队列

    一.阻塞队列 1.阻塞队列BlockingQueue ---->可以理解成生产者消费者的模式---->消费者要等待到生产者生产出来产品.---->而非阻塞队列ConcurrentLi ...

  6. 经典全屏滚动插件fullPage.js

    要写简单可以写的很简单,对着github上面的参数和注释随便写了个demo.这个插件十分高端大气上档次,配上良好的配色和布局,简单几笔就可以把网站装扮得十分洋气. 唯一的缺点就是,感觉对移动端的兼容性 ...

  7. Asp.Net使用加密cookie代替session验证用户登录状态 源码分享

    首先 session 和 cache 拥有各自的优势而存在.  他们的优劣就不在这里讨论了. 本实例仅存储用户id于用户名,对于多级权限的架构,可以自行修改增加权限字段   本实例采用vs2010编写 ...

  8. Nginx upstream的5种权重分配方式【转】

    原文地址:Nginx upstream的5种权重分配方式 1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2.weight指定轮询几率,weig ...

  9. 让老版本IE支持HTML5

    一直想入手C3和H5,但因为所开发的项目一直要求兼容IE7,IE8.而这两个浏览器并不支持html5,所以一直都在观望而未真正的投入太多精力去学习.尽管我知道h5和c3是主流. 在最近的项目开发中,偶 ...

  10. 【bzoj题解】1012 最大数

    题目描述 现在请求你维护一个数列,要求提供以下两种操作:1.查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2.插入操作.语法:A ...