作者:empty 出版社:empty |
1前言
该部分经验主要是在首都国际机场,海口梅兰国际机场系统的开发过程中得到的。环境是使用IBM s80机器,AIX4.3操作系统,4G内存,DB2数据库(UDB 7.2版本),
存储设备是EMC磁盘阵列,12对硬盘,做RAID 1,即可用12个硬盘,每个36G。其中4个被用做bcv(也是一个镜像系统,和工作库中的数据一模一样,可以用于快速创建一个和工作环境一样的开发环境。具体不是很懂)。实际可用8个物理硬盘,每个划为4个9G盘。
2DB2专有名词解释
2.1Instance(实例)
相当于Informix的Informix Server的概念, 在一台机器上可以有多个相互独立的实例, 并同时运行. 每个实例可以管理若干个数据库, 一个数据库只属于一个实例.
2.2DB2 Administration Server(管理服务器)
与DB2 Administration Client对称. 一个DB2数据库如果需要远端的管理, 就需要在有DB2数据库的机器上有管理服务进程以接收远端的管理客户进程的请求. 一般来讲, 一个在R/6000上的DB2, 由于AIX一般无图形界面, 最好在局域网内有一台有图形界面的机器(例如装有Win 98或Win NT)来对其进行远程管理. 因为用带图形界面的DB2控制中心, 可以很方便的查看DB2的状态, 详细形象的监控DB2的性能, 对DB2的配置参数进行精确的调整, 而这些都是用DB2的命令行难以实现的. 控制中心提供的Smart Guide功能, 更可以让数据库管理员不用关心数据库内部实现的细节, 而对数据库进行较精确的调整.
2.3Container(容器)
与Informix中的chunk概念基本一样. 但DB2数据库管理进程在向容器内写数据时, 所有一个表空间内的容器是均衡着写入的. 并且这种均衡是实时的, 例如在一个表空间中加入一个容器后, 该容器所处的表空间中其它容器的数据会很快的均衡到该容器来.
2.4DRDA
分布式关系数据库结构 Distributed Relational Database Architecture
2.5DARI
数据库应用远程接口 Database Application Remote Interface
2.6SPM
Synchronous Point Management, 相当于Informix的check point
2.7FCM
Fast Communication Management, 用于数据库分区间通信
2.8ADSM
ADSTAR Distributed Storage Manager
2.9DCE
Distributed Compute Environment
3DB2编程
3.1建存储过程时Create 后一定不要用TAB键
createprocedure
的create后只能用空格,而不可用tab健,否则编译会通不过。
切记,切记。
3.2使用临时表
要注意,临时表只能建在user tempory tables space 上,如果database只有system tempory table space是不能建临时表的。
另外,DB2的临时表和sybase及oracle的临时表不太一样,DB2的临时表是在一个session内有效的。所以,如果程序有多线程,最好不要用临时表,很难控制。
建临时表时最好加上 with replace选项,这样就可以不显示的drop 临时表,建临时表时如果不加该选项而该临时表在该session内已创建且没有drop,这时会发生错误。
注意:一旦rollback,该临时表将不存在。
临时表有好几种定义方式。但如果是对not null及default值有什么要求的话,最好还是使用完整字段列表来定义。因为有一次,我使用了like table including column default 来定义,但default还是没有按预料的那样带过来.
如下例,可以作为常用的临时表的定义方式。
declare global temporary table tmp_tb_clear_match_detail (
tradedate char(8) not null--业务日期
)
with replace on commit preserve rows not logged ;
on commit preserve:是在commit时不将临时表的内容释放。
临时表中也可以使用自增字段:
declare global temporary table tt(aa char(1),bb int generated always as identity) not logged
经过本人测试,对临时表做插入比做update速度要快很多,插入50000条记录是用15秒,再对该表中插入1000条记录,用时不到1秒,而update其中1000条,用时60秒。
临时表中不能建索引,很不好用。
3.3从数据表中取指定前几条记录
select * from tb_market_code fetch first 1 rows only
但下面这种方式不允许
select market_code into v_market_code
from tb_market_code fetch first 1 rows only;
选第一条记录的字段到一个变量以以下方式代替
declare v_market_code char(1);
declare cursor1 cursor for select market_code from tb_market_code
fetch first 1 rows only for update;
open cursor1;
fetch cursor1 into v_market_code;
close cursor1;
3.4游标的使用
注意commit和rollback
使用游标时要特别注意如果没有加with hold 选项,在Commit和Rollback时,该游标将被关闭。Commit 和Rollback有很多东西要注意。特别小心
游标的两种定义方式
一种为
declare continue handler for not found
begin
set v_notfound = 1;
end;
declare cursor1 cursor with hold for select market_code from tb_market_code for update;
open cursor1;
set v_notfound=0;
fetch cursor1 into v_market_code;
while v_notfound=0 Do
--work
set v_notfound=0;
fetch cursor1 into v_market_code;
end while;
close cursor1;
这种方式使用起来比较复杂,但也比较灵活。特别是可以使用with hold 选项。如果循环内有commit或rollback 而要保持该cursor不被关闭,只能使用这种方式。
另一种为
pcursor1: for loopcs1 as cousor1 cursor as
select market_code as market_code
from tb_market_code
for update
do
end for;
这种方式的优点是比较简单,不用(也不允许)使用open,fetch,close。
但不能使用with hold 选项。如果在游标循环内要使用commit,rollback则不能使用这种方式。如果没有commit或rollback的要求,推荐使用这种方式(看来For这种方式有问题)。
修改游标的当前记录的方法
update tb_market_code set market_code='0' where current of cursor1;
不过要注意将cursor1定义为可修改的游标
declare cursor1 cursor for select market_code from tb_market_code
for update;
for update 不能和GROUP BY、 DISTINCT、 ORDER BY、 FOR READ ONLY及UNION, EXCEPT, or INTERSECT但 UNION ALL除外)一起使用。
3.5类似decode的转码操作
oracle中有一个函数 select decode(a1,'1','n1','2','n2','n3') aa1 from
db2没有该函数,但可以用变通的方法
select case a1
when '1' then 'n1'
when '2' then 'n2'
else 'n3'
end as aa1 from
3.6类似charindex查找字符在字串中的位置
Locate(‘y’,’dfdasfay’)
查找’y’ 在’dfdasfay’中的位置。
3.7类似datedif计算两个日期的相差天数
days(date(‘2001-06-05’)) – days(date(‘2001-04-01’))
days 返回的是从 0001-01-01 开始计算的天数
下面一个例子是取该天所在的周的星期一的日:
date(days('2001-08-20')-dayofweek('2001-08-20')+2)
3.8写UDF的例子
C写见sqllib samples cli udfsrv.c
3.9创建含identity值(即自动生成的ID)的表
建这样的表的写法
CREATE TABLE test
(t1 SMALLINT NOT NULL
GENERATED ALWAYS AS IDENTITY
(START WITH 500, INCREMENT BY 1),
t2 CHAR(1));
在一个表中只允许有一个identity的column.
3.10预防字段空值的处理
SELECT DEPTNO ,DEPTNAME ,COALESCE(MGRNO ,'ABSENT'),ADMRDEPT
FROM DEPARTMENT
COALESCE函数返回()中表达式列表中第一个不为空的表达式,可以带多个表达式。
和oracle的isnull类似,但isnull好象只能两个表达式。
3.11取得处理的记录数
declare v_count int;
updatetb_testsett1=’0’
wheret2=’2’;
--检查修改的行数,判断指定的记录是否存在
get diagnosticsv_ count=ROW_COUNT;
只对update,insert,delete起作用.
不对select into 有效
3.12从存储过程返回结果集(游标)的用法
1、建一sp返回结果集
CREATE PROCEDURE DB2INST1.Proc1 ( )
LANGUAGE SQL
result sets 2(返回两个结果集)
------------------------------------------------------------------------
-- SQL 存储过程
------------------------------------------------------------------------
P1: BEGIN
declare c1 cursor with return to caller for
select market_code
from tb_market_code;
--指定该结果集用于返回给调用者
declare c2 cursor with return to caller for
select market_code
from tb_market_code;
open c1;
open c2;
END P1
2、建一SP调该sp且使用它的结果集
CREATE PROCEDURE DB2INST1.Proc2 (
out out_market_code char(1))
LANGUAGE SQL
------------------------------------------------------------------------
-- SQL 存储过程
------------------------------------------------------------------------
P1: BEGIN
declare loc1,loc2 result_set_locator varying;
--建立一个结果集数组
call proc1;
--调用该SP返回结果集。
associate result set locator(loc1,loc2) with procedure proc1;
--将返回结果集和结果集数组关联
allocate cursor1 cursor for result set loc1;
allocate cursor2 cursor for result set loc2;
--将结果集数组分配给cursor
fetch cursor1 into out_market_code;
--直接从结果集中赋值
close cursor1;
END P1
3、动态SQL写法
DECLARE CURSOR C1 FOR STMT1;
PREPARE STMT1 FROM
'ALLOCATE C2 CURSOR FOR RESULT SET ?';
4、注意:
一、如果一个sp调用好几次,只能取到最近一次调用的结果集。
二、allocate的cursor不能再次open,但可以close,是close sp中的对应cursor。
3.13类型转换函数
select cast ( current time as char(8)) from tb_market_code
3.14存储过程的互相调用
目前,c sp可以互相调用。
Sql sp 可以互相调用,
Sql sp 可以调用C sp,
但C sp 不可以调用Sql sp(最新的说法是可以)
3.15C存储过程参数注意
create procedure pr_clear_task_ctrl(
IN IN_BRANCH_CODE char(4),
IN IN_TRADEDATE char(8),
IN IN_TASK_ID char(2),
IN IN_SUB_TASK_ID char(4),
OUT OUT_SUCCESS_FLAG INTEGER )
DYNAMIC RESULT SETS 0
LANGUAGE C
PARAMETER STYLE GENERAL WITH NULLS(如果不是这样,sql 的sp将不能调用该用c写的存储过程,产生保护性错误)
该参数的实际意义是,如果不是with nulls则sql在调用该存储过程时,如果有一个参数为null的话,存储过程的调用会出错。
NO DBINFO
FENCED
MODIFIES SQL DATA
EXTERNAL NAME 'pr_clear_task_ctrl!pr_clear_task_ctrl'@
3.16存储过程fence及unfence
fence的存储过程单独启用一个新的地址空间,而unfence的存储过程和调用它的进程使用同一个地址空间。
一般而言,fence的存储过程比较安全。
但有时一些特殊的要求,如要取调用者的pid,则fence的存储过程会取不到,而只有unfence的能取到。
1前言9
2DB2专有名词解释9
2.1INSTANCE(实例)9
2.2DB2 ADMINISTRATION SERVER(管理服务器)9
2.3CONTAINER(容器)9
2.4DRDA10
2.5DARI10
2.6SPM10
2.7FCM10
2.8ADSM10
2.9DCE10
3DB2编程10
3.1建存储过程时CREATE 后一定不要用TAB键10
3.2使用临时表11
3.3从数据表中取指定前几条记录11
3.4游标的使用12
注意commit和rollback12
游标的两种定义方式12
修改游标的当前记录的方法13
3.5类似DECODE的转码操作13
3.6类似CHARINDEX查找字符在字串中的位置13
3.7类似DATEDIF计算两个日期的相差天数14
3.8写UDF的例子14
3.9创建含IDENTITY值(即自动生成的ID)的表14
3.10预防字段空值的处理14
3.11取得处理的记录数14
3.12从存储过程返回结果集(游标)的用法15
3.13类型转换函数16
3.14存储过程的互相调用16
3.15C存储过程参数注意16
3.16存储过程FENCE及UNFENCE17
3.17SP错误处理用法17
3.18VALUES的使用18
3.19给SELECT 语句指定隔离级别18
3.20ATOMIC及NOT ATOMIC区别18
3.21C及SQL存储过程名称都要注意长度18
3.22怎样获得自己的数据库连接句柄19
3.23类似于ORACLE的NAME PIPE19
3.24类似于ORACLE的TRUNCATE清表但不记日志的做法19
3.25用CLI编程批量的INSERT19
4DB2一些不好的限制24
4.1临时表不能建索引24
4.2CURSOR不能定义为WITH UR(可以但…)24
4.3CURSOR ORDER BY以后不能FOR UPDATE24
4.4程序中间不能自由改变隔离级别24
4.5UPDATE 不能用一个表中的记录为条件修改另一个表中的记录。24
4.6如果显示调用存储过程时传 NULL值要注意24
5DB2编程性能注意25
5.1大数据的导表的使用(EXPORT,LOAD,IMPORT)(小心)25
5.1.1import的用法25
5.1.2性能比较25
5.1.3export用法25
5.2SQL语句尽量写复杂SQL26
5.3SQL SP及C SP的选择26
5.4查询的优化(HASH及RR_TO_RS)26
5.5避免使用COUNT(*) 及EXISTS的方法27
5.6COMMIT的次数要适当27
5.7INSERT和UPDATE速度比较27
5.8使用临时表取代一条一条插入28
5.9循环次数很多时注意减少执行语句(附例子)28
5.10看程序执行时间及结果DB2BATCH30
5.11看程序或语句具体的执行计划SHELL(改写后的语句)30
5.12两个表做JOIN的不同方式的区别30
5.12.1not in方式30
5.12.2except方式31
5.12.3not exist方式32
6其他系统和DB2的交互32
7DB2表及SP管理33
7.1权限管理33
7.1.1数据库权限控制33
7.1.2schema权限控制33
7.1.3tablespace权限控制33
7.1.4table权限控制34
7.1.5package权限控制34
7.2建存储过程会占用很多的系统资源(特别是IO)34
7.3看存储过程文本34
7.4看表结构34
7.5看表的索引信息35
7.6查看各表对SP的影响(被哪些SP使用)35
7.7查看SP使用了哪些表35
7.8查看FUNCTION被哪些SP使用35
7.9查SP的ID号35
7.10从SP的ID号查存储过程名称35
7.11创建及使用SUMMARY TABLE36
7.12修改表结构36
7.13给一个表改名36
7.14得到一个表或库的相关脚本37
7.15在对表操作的性能下降后对表做整理37
7.16查看语句的执行计划38
7.17查看SP的执行计划38
7.18更改存储过程的隔离级别38
7.19取全部表的大小39
8DB2系统管理40
8.1DB2 EE及WORKGROUP版本的区别40
8.2怎样判断DB2实例的版本号和修补级别?40
8.3DB2客户端安装时选择语言41
8.4DB2安装42
8.4.1AIX中自动启动db242
8.4.2AIX中用户使用db2的环境44
8.4.3在win98下安装db2报Jdbc错误44
8.4.4将一台机器上的数据库复制到另外一台机器45
8.4.5在WIN2000下编译本地sp设置46
8.5启动支持远程管理数据库服务(DB2ADMIN)46
8.6安装另一个INSTANCE要注意的地方46
8.6.1通讯配置46
8.6.2更改文件权限46
8.7DB2的C编译报没有LICSENCE47
8.8DB2的进程管理47
8.9创建DATABASE47
8.10DATABASE的备份47
8.11TABLESPACE48
8.11.1创建临时表空间48
8.11.2将Tablespace授权给用户使用49
8.11.3看Tablespace信息49
8.11.4去掉tag49
8.12手工做数据库别名配置及去除该别名配置49
8.13手工做数据库远程(别名)配置49
8.14停止启动数据库实例50
8.15连接数据库及看当前连接数据库50
8.16停止启动数据库HEAD50
8.17查看及停止数据库当前的应用程序50
8.18查看本INSTANCE下有哪些DATABASE51
8.19查看及更改数据库HEAD的配置51
8.19.1设置使用2G以外的内存51
8.19.2更改Buffer pool的大小51
8.19.3更改dbheap的大小52
8.19.4改catalogcache的大小52
8.19.5改事务buff的大小52
8.19.6改工具堆大小52
8.19.7改排序堆的大小52
8.19.8改stmtheap的大小53
8.19.9改事务日志的大小53
8.19.10改锁的相关参数的大小54
8.19.11出现程序堆内存不足时修改程序堆内存大小54
8.19.12NUM_IOCLEANERS及NUM_IOSERVERS数量设置54
8.19.13成组commit设置MINICOMMIT54
8.19.14设置连接数的相关参数MAXAPPLS55
8.19.15设置包缓冲区PCKCACHESZ55
8.20日志管理55
8.20.1更改日志文件的存放路径55
8.20.2监控应用程序日志使用情况55
8.20.3循环日志和归档日志55
8.20.4循环日志日志满的原因56
8.21查看及更改数据库实例的配置56
8.21.1打开对锁定情况的监控。56
8.21.2更改诊断错误捕捉级别56
8.21.3更改最大代理数56
8.22DB2环境变量57
8.23DB2命令环境设置58
8.24改变隔离级别58
8.25管理DB INSTANCE的参数58
8.26升级后消除版本问题59
8.27查看数据库表的死锁59
8.28查看数据库的事件59
8.29数据库性能下降后做RUNSTATS及REBIND包。60
8.30修复诊断数据库DB2DART的使用60
8.31获取数据库的信息DB2SUPPORT的使用60
8.32分析DB2DIAG.LOG的方法61
8.32.1Obj={pool:2;obj:10;type:0}含义61
8.32.2错误信息所在位置1(errno)61
8.32.3错误信息所在位置1(FFFF nnnn 或 nnnn FFFF)61
9DB2一般问题62
9.1有关锁的知识62
9.2有关锁的对象知识63
10DB2疑难问题63
10.1建SP时DROP不掉怎么办63
10.2C的过程老是出现时间戳问题?63
10.3FOR CURSOR问题?64
10.4数据库启动资源冲突问题64
10.5DB2STOP不下去问题65
10.6数据库日志满问题65
10.7FORCE APPLICATION导致INSTANCE崩溃问题66
10.8存储过程名称和过程运行有关的问题66
10.9看DB2DIAG.LOG中的内容66
10.10DECIMAL除法的问题,DB2做SUM时有BUG(实际上不是)66
10.11CASE的问题68
10.12一个较复杂SQL语句错误69
10.13编译语句挂起的现象73
10.14远程连接连不上去,报TCP/IP错误76
10.15TABSPCE实际上没有表,但还是报满76
11DB2编程教训77
11.1常被大家访问同一记录的表的修改77
11.2大表改小表77
11.3查询表数据使用UR的隔离级别77
11.4DELETE,UPDATE后及时COMMIT78
12AIX系统管理78
12.1查看磁盘使用情况78
12.2看目录的文件占用硬盘情况78
12.3看IO情况78
12.4查看CPU情况79
12.5查看系统资源总的使用情况79
12.6看正在运行的线程/进程79
12.6.1看正在运行的线程79
12.6.2看按占cpu比例排序的进程79
12.6.3看按占内存比例排序的进程79
12.7查看内存使用情况79
12.8查看共享内存、消息队列等使用情况80
12.9根下不要建文件系统80
12.10文件操作80
12.10.1看文本文件自动新增长内容80
12.10.2将大文件拆分80
12.10.3文件打包80
12.10.4文件压缩80
12.10.5文件解压81
12.10.6bz2文件处理81
12.11看逻辑卷信息81
12.12重启机器81
13AIX系统限制81
13.1FORK太多会导致系统崩溃81
13.2对文件大小的限制82
13.3磁带备份的速度82
14AIX及DB2相关文档及网站82
14.1取DB2最新补丁程序82
14.2国际化的DB2用户组织82
14.3错误信息所在位置1(ERRNO)82
14.4错误信息所在位置1(FFFF NNNN 或 NNNN FFFF)83
15DB2和ORACLE的对比83
15.1用户管理不一样83
15.2表空间使用不一样83
15.3保证事务的一致性方式不一样83
16ORACLE上SQL语句性能优化(DB2也可以参考)84
16.1ORACLE中索引问题84
16.2ORACLE中索引问题85
17怎样判断DB2实例的版本号和修补级别?87
18在LINUX 上创建DB2裸设备方法90
19DB2 RELATIONAL CONN连接SQLSERVER 的方法步骤91
20数据库配置参数摘要94
21数据库管理程序配置参数摘要97
22如何实施存储过程的发布100
23表空间重定向101
24如何设置RAID环境下的DB2表空间101
25DB2的安全管理机制有哪些?102
26DB2V7.1在REDHATV7.2下的安装说明102
27如何在 RED HAT LINUX 7.1上安装DB2 EEE(扩展企业版)107
28DB2DIAG.LOG中大量出现关于TCP/IP协议的DIA3208E错误112
29如何在命令行用FETCH命令查看用DECLARE CURSOR(游标)指定的结果集113
30问题 如何配置 ODBC.INI?114