SC 环境增加 一个常数 DBT_ ="access" '表示当前数据库的类型, 枚举: access, sqlserver, mysql
SC 环境增加一个函数 function ST_(s) 这个函数用于不同数据库的Select Top 语句的兼容.
如果你的 sql 语句里面包含了 select top n ..., 你必须把你的 语句用ST_函数处理一下, 如:
sql="select Top 10 * from ac"
sql=ST_(sql) ' 这时如果数据库类型为MySQL 则 sql 变成 "select * from ac LIMIT 10"
注意, 如果你的SQL语句里面有多个TOP关键字,你必须把SQL语句拆分成单独的只包含一个top 关键字的语句后再合并.
如果你的 sql 语句包含了 字符串字段的 链接如: select acid + ' ' + actitle from ac 也请使用ST_函数.
因为mySQL 不支持使用 + 加号来进行字符串链接, 字符串链接MySQL是使用concat 函数, ST_会在内部进行帮你转换(需要升级平台到2012.10.20之后的版本).
注意ST_函数的一下局限:
1. ST_只能处理 第一个Select 后的内容, 如果有Select嵌套,则需要先用ST_处理后再嵌套,例如:
SQL=ST_("select * from (select top 10 * from ac)") 这样是无效的,应该改为:
SQL="select * from (" & ST_("select top 10 * from ac") & ")")
SQL="select * from (select acid +' ' + actitle from ac)" 也应该参照上一句来更改
2. 为了避免 concat 转换时候, 数字类型的相加混淆 , ST_只会对包含有单引号的字段部分进行concat转换处理
例如: SQL=ST_("select acid,acptitle + actitle from ac") 这样的结果是sql语句不会改变, 你必须更改为:
SQL=ST_("select acid, ''+acptitle + actitle from ac"), 这样ST_才会认为''+acptitle + actitle 需要concat处理
SC 环境修改了GetRS_() 函数,在内部增加了:
if lcase(DBT_="mysql") then
GetRS_.CursorLocation=3
end if
一下问题中如果牵涉到 CursorLocation的,均已经由平台统一处理,但是必须注意:
A. SC虚拟机(即SC环境,)必须是最新2012-10-15以上版本的, http://www.4Fang.net/4ff/sc_setup.exe 下载更新
B. 必须通过 GetRS_() 来获得Recordset对象
1.识别符
mysql识别符是 ``;sql server识别符是[].
mysql下表名或者字段名用[]包围,都会出错。例如:
create table [tbl] (id int);
alter table tbl add [f1] text;
***解决方式: 在SQL语句中避免使用 "[]" 来包裹字段名和表名, 如果字段名和表名是关键字, 必须区别不同的数据库对待
2.定义自增字段
mysql定义自增字段用 auto_increment;sql server用indentity(1,1)
***解决方式:增加字段时, 必须区分不同的数据库书写不同的SQL语句
3.注释
mysql注释符 -- comments,注释内容和注释符号要留个空格,不然没有注释效果(命令行界面下验证);sql server注释符与注释内容间有无空格皆可。如 --comments -- comments
***解决方式: 统一使用注释内容和注释符号之间多留一个空格的兼容方式
4.取字符串长度函数
mysql用length(str);sql server用len(str)
***解决方式: 已经通过mysql的自定义函数统一一次性解决,编程人员可以不理会,直接使用 len() 函数即可
5.数据类型text 整类型unsiged
mysql的text数据类型,有65KB的存储空间,longtext有4G存储空间;sql server的Text数据类型有2G存储空间。
mysql的整型数据类型可以指定unsigned,获得更大的取值范围。如 amount int unsigned
***解决方式: 我们统一使用text就可以了,除非我们可以预见某个字段数据量超过65K,则使用longtext类型
6.增加多个字段
mysql要加括号
包围字段列表 例如:
MS sql:alter table t add f1 int,f2 int,f3 int;
Mysql: alter table t add (f1 int,f2 int,f3 int);
***解决方式:必须按不同数据库的要求进行区分书写, 没有兼容的方式
7.like子句
Mysql select ...like,like 子句不支持[0-9]这样的匹配方式,它有扩展正则表达式子句 rlike 支持 . * [] ^ $ {n}等元字符。
Ms sql: select * from teacher where tname like 'C[0-9][0-9]'; -- 没问题,可以匹配到 C02 C29 ... Mysql: select * from teacher where tname like 'C[0-9][0-9]'; -- 不会出错,但是like会认为要匹配字符串 C[0-9][0-9] 所以没结果返回 Mysql: select * from teacher where tname rlike '^C[0-9]{2}$'; -- rlike子句的等价写法
***解决方式: 区别数据库对待, 这种情况我们极少用到,只在basedatacommon中用到
8.rs.recordCount
ado连接mysql,sql server数据库,打开rs对象默认的游标位置都是服务端游标。
sql server: rs.open "select * from company",cn,1,1 -- rs.recordCount返回正确的记录数
sql server: rs.open "select * from company",cn,1,1 -- rs.recordCount返回-1,解决方法:在rs.open之前 设置 rs.cursorLocation=3 或rs.cursorLocation=aduseClient。注:cursorLocation在记录集打开之前是可读可写的。打开记录集后为只读。可通过connection对象或recordset对象设置 如:cn.cursorLocation=3, rs.cursorLocation=3
***解决方式:碰到这种问题,把改成rs.cursorLocation=3
9.rs.addnew ....rs.update问题
如product表有数据如下:
Pname
产品A
产品B
SC页面:
rs.open "select * from product" cn,1,3
rs.addnew
rs("Pname")="产品C"
rs.update
response.write rs("Pname") '结果显示 产品B 而不是新记录的值
***解决方法:rs.open语句前设置游标位置为客户端游标 rs.cursorLocation=3
若用循环语句批量增加记录数很多 例如超过80条,如:
rs.open "select * from product" cn,1,3
for i=1 to 200
rs.addnew
rs("Pname")="产品"&i
rs.update
next
***解决方式:设置客户端游标后还是会有部分记录不能增加进去的情况,这时应把设置lockType=4,rs.update改用rs.updateBatch
10.rs.update多条记录的问题
同样是product表,更新一条记录马上去更新的值没问题;通过循环更新多条记录,就马上取更新后的值有问题。
rs.open "select * from product" cn,1,3
rs("Pname")=rs("Pname")&"modified" '游标位于第一条记录
rs.update
response.write rs("Pname") '结果为修改后的新值
更新多条记录的情况:
rs.open "select * from product" cn,1,3
do while not rs.eof
rs("Pname")=rs("Pname")&"modified" '游标位于第一条记录
rs.update
rs.movenext
loop
response.write "<h2>更新后的结果</h2><br>"
rs.movefirst
do while not rs.eof
response.write rs("Pname")&"<br>"
loop
'此时显示的是更新前的数据
***解决方法:在rs.open语句之前,设置为客户端游标 rs.cursorLocation=3
11. select count(*) from mytable 返回的记录的值的数据类型是VBS不能识别的, 必须用Clng函数强制转换后才能进行运算和比较:
rs.open "select count(*) from mytable",cn
if rs(0)>0 then ''这样会导致VBS引擎崩溃 应该改成:
if clng(rs(0))>0 then
12. 使用记录集修改操作
打开记录集的语句如为 sql = " select invoiceitem.lo as lo from invoice,invoiceitem where invoice.id = invoiceitem.iid "
rs.open sql,cn,1,3
rs("lo") = 2
rs.update
这种情况下将会报出 "缺少更新或刷新的键列信息" 错误,如是有主外键关系的请使用 inner join 语句联接打开需要修改的记录集
sql = "select invoiceitem.lo as lo from invoice inner join invoiceitem on invoice.id = invoiceitem.iid "
13 .mysql判断字段是否存在有简单的方法 只需要 rs.open "describe yourtbl yourFiled" ,cn,1,3
if not rs.eof then 字段存在