隔了很长时间,2004年7月8日第二次安装了ibm udb v7.2版本的数据库,前次好象是2003年年中吧,没怎么用,就过去了。
因为我无法运行db2sampl.exe创建sample样本数据库,所以发现我安装的是connect 企业版。我可以创建数据库bafwzx, 但是我不能创建sp,老是报错,这是第一个挫折,后来知道,这正是一个和ms sql server不同的一个重要区别,oracle和db2的存储过程要想返回记录集必须要使用光标(服务器端光标),这很重要,第一个有用的经验。
后来上了ibm站点下了它的个人版,安装了,之后很顺利。但使用sqlj时来了个麻烦,运行sqlj会出现这个错:Error in sqlj: path or file name "java" not found.网上也没有人解答这个问题,在万般无奈之下,我去检查了环境变量path的情况,发现只有下面的值:
H:/Program Files/IBM/SQLLIB/BIN;H:/PROGRA~1/IBM/SQLLIB/FUNCTION;H:/PROGRA~1/IBM/SQLLIB/SAMPLES/REPL;
看来安装db2后,它强硬的替换了这个path的值,真的是很不应该。我在其后加了:
D:/j2sdk1.4.2/bin以能在命令行中运行javac,java等工具,但再次运行sqlj时给出了这个错:
Exception in thread "main" java.lang.NoClassDefFoundError: sqlj/tools/Sqlj,看来sqlj有了动静,
经过检查类路径classpath发现在Administrator的用户变量中有一个classpath,如图:
系统变量中也有一个,而且我发现db2改写了它的值:
H:/PROGRA~1/IBM/SQLLIB/java/db2java.zip;H:/PROGRA~1/IBM/SQLLIB/java/db2jcc.jar;H:/PROGRA~1/IBM/SQLLIB/java/sqlj.zip;H:/PROGRA~1/IBM/SQLLIB/java/db2jcc_license_cu.jar;H:/PROGRA~1/IBM/SQLLIB/bin;H:/PROGRA~1/IBM/SQLLIB/tools/db2XTrigger.jar;H:/PROGRA~1/IBM/SQLLIB/java/common.jar;d:/JBuilder9/jdk1.4/jre/lib/ext/QTJava.zip;C:/PROGRA~1/JMF21~1.1E/lib/sound.jar;C:/PROGRA~1/JMF21~1.1E/lib/jmf.jar;C:/PROGRA~1/JMF21~1.1E/lib;%systemroot%/java/classes;D:/rmitest;H:/fileinter;J:/javacode/rmidemo/rmitest/classes;.;
我把Administrator的用户变量中有一个classpath改成了Classpath2之后,再在命令行中运行sqlj后,成功了,如下图。
J:/my download/Installing the DB2 Universal JDBC Driver.htm会对以上问题有个好的解释。
接下来就是创建sqlj的存储过程:
H:/Program Files/IBM/SQLLIB/samples/java/sqlj>bldsqlj Util sfliu cherubangel
[ibm][db2][jcc][sqlj]
[ibm][db2][jcc][sqlj] Begin Customization
[ibm][db2][jcc][sqlj] encoding not supported!!
看来好象是代码页的问题,于是在命令窗口执行下面的命令
H:/Program Files/IBM/SQLLIB/BIN>db2 CONNECT TO sample
数据库连接信息
数据库服务器 = DB2/NT 8.1.3
SQL 授权标识 = ADMINIST...
本地数据库别名 = SAMPLE
连上之后,我查看数据库的数据库配置:
H:/Program Files/IBM/SQLLIB/BIN>db2 get db cfg
数据库 的数据库配置
数据库配置发行版级别 = 0x0a00
数据库发行版级别 = 0x0a00
数据库领域 = CN
数据库代码页 = 1386
数据库代码集 = GBK
数据库国家/地区代码 = 86
动态 SQL 查询管理 (DYN_QUERY_MGMT) = DISABLE
对此数据库的发现支持 (DISCOVER_DB) = ENABLE
缺省查询优化类 (DFT_QUERYOPT) = 5
并行度 (DFT_DEGREE) = 1
在算术异常时继续 (DFT_SQLMATHWARN) = NO
缺省刷新有效期 (DFT_REFRESH_AGE) = 0
保留的高频值的数目 (NUM_FREQVALUES) = 10
保留的分位点数目 (NUM_QUANTILES) = 20
备份暂挂 = NO
数据库是一致的 = YES
前滚暂挂 = NO
复原暂挂 = NO
启用的多页文件分配 = NO
恢复状态的日志保留 = NO
记录状态的用户出口 = NO
Data Links 标记到期时间间隔(秒) (DL_EXPINT) = 60
Data Links 写标记初始时间间隔 (DL_WT_IEXPINT) = 60
副本的 Data Links 数目 (DL_NUM_COPIES) = 1
删除后的 Data Links 时间(天数) (DL_TIME_DROP) = 1
大写的 Data Links 标记 (DL_UPPER) = NO
Data Links 标记算法 (DL_TOKEN) = MAC0
数据库堆(4KB) (DBHEAP) = 300
数据库共享内存大小(4KB) (DATABASE_MEMORY) = AUTOMATIC
目录高速缓存大小(4KB) (CATALOGCACHE_SZ) = (MAXAPPLS*4)
日志缓冲区大小(4KB) (LOGBUFSZ) = 8
实用程序堆大小(4KB) (UTIL_HEAP_SZ) = 5000
缓冲池大小(页) (BUFFPAGE) = 250
扩充存储段大小(4KB) (ESTORE_SEG_SZ) = 16000
扩充存储段的数目 (NUM_ESTORE_SEGS) = 0
锁定列表的最大存储量(4KB) (LOCKLIST) = 25
应用程序组内存集的最大大小(4KB) (APPGROUP_MEM_SZ) = 10000
应用程序组堆的内存百分比 (GROUPHEAP_RATIO) = 70
最大应用程序控制堆大小(4KB) (APP_CTL_HEAP_SZ) = 64
共享排序的排序堆域值(4KB) (SHEAPTHRES_SHR) = (SHEAPTHRES)
排序列表堆(4KB) (SORTHEAP) = 256
SQL 语句堆(4KB) (STMTHEAP) = 2048
缺省应用程序堆(4KB) (APPLHEAPSZ) = 256
程序包高速缓存大小(4KB) (PCKCACHESZ) = (MAXAPPLS*8)
统计信息堆大小(4KB) (STAT_HEAP_SZ) = 4384
检查死锁的时间间隔(毫秒) (DLCHKTIME) = 10000
每个应用程序的锁定百分比列表 (MAXLOCKS) = 22
锁定超时(秒) (LOCKTIMEOUT) = -1
更改的页阈值 (CHNGPGS_THRESH) = 60
异步页清除程序的数目 (NUM_IOCLEANERS) = 1
I/O 服务器的数目 (NUM_IOSERVERS) = 3
索引排序标志 (INDEXSORT) = YES
顺序检测标志 (SEQDETECT) = YES
缺省预取大小(页) (DFT_PREFETCH_SZ) = 16
跟踪修改的页数 (TRACKMOD) = OFF
容器的缺省数目 = 1
缺省表空间数据块大小(页) (DFT_EXTENT_SZ) = 32
活动应用程序的最大数目 (MAXAPPLS) = AUTOMATIC
活动应用程序的平均数目 (AVG_APPLS) = 1
每个应用程序的最大打开 DB 文件数 (MAXFILOP) = 64
日志文件大小(4KB) (LOGFILSIZ) = 250
主日志文件的数目 (LOGPRIMARY) = 3
辅助日志文件的数目 (LOGSECOND) = 2
已更改的至日志文件的路径 (NEWLOGPATH) =
日志文件路径 = H:/DB2/NODE0000/SQL00
002/SQLOGDIR/
溢出日志路径 (OVERFLOWLOGPATH) =
镜像日志路径 (MIRRORLOGPATH) =
首个活动日志文件 =
磁盘上已满的块日志 (BLK_LOG_DSK_FUL) = NO
事务使用的最大活动日志空间的百分比 (MAX_LOG) = 0
1 个活动 UOW 的活动日志文件的数目 (NUM_LOG_SPAN) = 0
组落实计数 (MINCOMMIT) = 1
软检查点前回收的日志文件的百分比 (SOFTMAX) = 100
启用的恢复的日志保留 (LOGRETAIN) = OFF
启用的记录的用户出口 (USEREXIT) = OFF
启用的自动重新启动 (AUTORESTART) = ON
索引重新创建时间 (INDEXREC) = SYSTEM (ACCESS)
loadrec 会话的缺省数目 (DFT_LOADREC_SES) = 1
要保留的数据库备份的数目 (NUM_DB_BACKUPS) = 12
恢复历史记录保留时间(天数) (REC_HIS_RETENTN) = 366
TSM 管理类 (TSM_MGMTCLASS) =
TSM 节点名 (TSM_NODENAME) =
TSM 所有者 (TSM_OWNER) =
TSM 密码 (TSM_PASSWORD) =
网上也没有该问题的说明,于是开始摸索,我注意到我用了比较新的j2sdk1.4以上的版本,而ibm使用的是jdk1.31的版本:
C:/Documents and Settings/Administrator>java -version
java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1)
Classic VM (build 1.3.1, J2RE 1.3.1 IBM Windows 32 build cn131-20020403 (JIT ena
bled: jitc))
所以我把D:/j2sdk1.4.2/bin换为H:/Program Files/IBM/SQLLIB/java/jdk/bin自己提供的java和javac工具后问题得到解决,不是代码页的问题。
执行成功了,sqlj对该sqlj文件进行了处理,并得到了应该得到的输出文件:
DbConn.java,DbConn.class,DbConn_SJProfileKeys.class,DbConn_SJProfile0.ser。
但是bind却失败了,不成功的结果是:当在控制中心中查看数据库的程序包就不会有该包出现,客户当然也就调用不了,你发布的功能就是没有加入到该数据库中。
但为什么没成功呢?
首先由上面的图可以看到,表staff前加上了模式sfliu,实际上,该表属于administrator模式,看来要改变该表的模式。我卸了sample后,再创建,所有用户表仍然是administrator的, 经过摸索,我认为:sample的创建是使用当前windows帐户的,我当前的帐户正是administrator,我查看了计算机的用户管理,发现了db2安装期间创建的db2admin和sfliu两个帐户,这正是我的想法:db2集成了window安全管理。
还有一点要注意:实际上在一开始就有这个想法,所以我以试试的态度使用以下的语句样式运行:Bldsqlj DbConn Administrator 1*2&&67 执行后报告错误,说口令不合法,我没进一步的深入思考。后来我想通了那种机制后,把Administrator的口令修改为1*2@@67,这样我成功的编译了该代码。问题就在于口令中&符号,可能因为它在xml中是实体引用的特别符号,换成了@后,问题解决,
后来发现原来是批处理文件运行时不能使用&符号,如下图:
其次看看sqlj的工作原理:
因为sqlj是把sql语句嵌入到java中,并被sqlj转换成能在sqlj环境下运行的代码,可以说这是一种静态sql运行方法,就是说sql语句的句法检查和执行路径这两个过程的确定都在编译期间(或者说是被sqlj翻译期间)就完成了,因此调用sqlj时,就是直接进入实质性的查询阶段,比起jdbc的动态sql执行要快。
正是因为sqlj要对嵌入到java中sql语句进行分析,我们碰到了因表属于不同的模式而不能访问的错误,并最终没有成功绑定。
实际上还遇到了一个小问题:
现象是:
copy DbConn*.class H:/Program Files/IBM/SQLLIB/function/ 命令语法不正确。
为什么不正确呢,经过测试,原来是路径中存在空格,如果是这样,就要用引号把该路径引起来,如下:copy DbConn*.class “H:/Program Files/IBM/SQLLIB/function/”,就可以解决了,
原因:
这是命令行解释器的问题。
结论:安装db2的时候指定它的安装路径中不要有空格。
参考资料:
http://www-128.ibm.com/developerworks/cn/db2/library/techarticles/0302tsui/0302tsui.html