1.1 创建存储过程时需要注意变量声明的顺序
创建存储过程时,声明变量顺序不符合规范将提示:
SQL0104N An unexpected token "
Expected tokens may include: "
SQLSTATE=42601
解答:声明变量、游标以及条件处理要有序进行;普通变量声明在先,其次到游标的声明,最后才能声明condition handler。
1.11 因为死锁或超时,所以当前事务已回滚。
当前事务因死锁或超时而回滚,将提示:
SQL0911N The current transaction has been rolled back because of a deadlock or timeout. Reason code "2".
根据原因码确定具体原因,原因码如下:
2 由于死锁而导致事务已回滚。
68 由于锁定超时而导致事务已回滚。
72 因为存在与事务中所涉及的 DB2 Data Links Manager 有关的错误,所以事务已回滚。
常见原因码为2、68。应用程序已回滚至上一次 COMMIT。
解答:为了帮助避免死锁或锁定超时,对长时间运行的应用程序或有可能遇到死锁的应用程序频繁发出 COMMIT 操作(若有可能的话)。并适当地增大锁超时时间:db2 update db cfg using LOCKTIMEOUT 60(此处60秒为例)。
1.12 在客户端查询数据库中文信息会产生乱码
解答:在服务器端或客户端将编码类型设置为1208以支持中文:db2set DB2CODEPAGE=1208。
1.13 重启动机器后,用于创建表空间的裸设备与逻辑卷挂接失效,数据库无法使用,提示:SQL0290N Table space access is not allowed. SQLSTATE=55039
解答:按原来的对应关系重新将裸设备和逻辑卷挂接起来;或创建一个机器重启时自动执行的脚本,将该脚本放在/etc/init.d目录下,并在/etc/init.d/rcN.d(N为当前系统运行级别,使用runlevel或who –r获得,不同系统命令不同)目录下建一个硬连接。
1.14 编目时确保使用正确的服务端口号
若在编目时使用的服务端口号与通过db2 get dbm cfg | grep SVCENAME查看到不一致,那在连接节点或数据库时,将出现如下提示信息:
db2inst1@osta1:~> db2 connect to l2cache
SQL30081N A communication error has been detected. Communication protocol
being used: "TCP/IP". Communication API being used: "SOCKETS". Location
where the error was detected: "10.71.122.196". Communication function
detecting the error: "connect". Protocol specific error code(s): "111", "*",
"*". SQLSTATE=08001
Administrator>db2 attach to L194 user db2inst1
输入 db2inst1 的当前密码:
SQL30081N 检测到通信错误。正在使用的通信协议:"TCP/IP"。正在使用的通信API:
"SOCKETS"。检测到错误的位置:"10.71.100.191"。检测到错误的通信函数:"connect"。
协议特定的错误代码:"10061"、"*"、"*"。 SQLSTATE=08001
解答:
1、 检查网络工作状态是否良好;
2、 通过db2 get dbm cfg | grep SVCENAME查看服务端口号,确认编目时使用的这个服务名称或端口号;并确定服务器端和客户端在etc/services文件中对服务名称、端口号和协议的配置一致;
3、 确定编目时使用的通信协议或etc/services文件中配置的通信协议跟服务器设置的一致(通过db2set DB2COMM查看服务器使用的通信协议);
4、 前面没问题,再去看看日志/sqllib/db2dump/db2diag.log是否有异常提示信息,根据提示解决问题。
1.15 不能分配“应用程序支持层“堆
内存不足(系统中可用的调页空间量或交换空间量或系统中可用的物理内存量),可能会导致问题,并提示如下错误信息:
SQL1221N The Application Support Layer heap cannot be allocated. SQLSTATE=57011
解答:确认有足够的内存资源可用于满足数据库管理器和系统上正在运行其它程序的需求。通过db2 update dbm cfg using ASLHEAPSZ 40(单位为4KB)适当增大应用程序支持层堆大小,或在适当的地方,停止使用该系统的其它程序。注意修改管理器的配置后,一定要重新启动实例,修改才能生效。
1.16 如何查看数据库占用内存情况
解答:1、db2pd –memsets
1.17 如何查看DB2的进程
解答:使用db2_ps 可以确定db2是否正常启动。
1.18 如何将数据库运行的环境收集起来
解答:使用db2support ./ –d 数据库名 –s 将数据库环境及系统环境收集起来打成包,对于数据库管理器出现严重错误的情况,可以将此包发送给IBM的技术支援分析。
1.19 如何扩大表空间的容量
解答:给表空间增加新的容器:alter tablespace
1.20 数据库实例用户无法访问裸设备
当数据库实例用户没有权限访问创建数据库所用的裸设备时,数据库将无法使用,并会提示:The system attempted to write to a read-only file. SQLSTATE=55009
解答:修改裸设备的归属属性:chown db2inst1:db2grp1 /dev/raw/rawX(X为裸设备id)。
1.21 如何让数据库支持中文字符集
解答:在服务器端修改数据库字符集以支持中文字符集:db2set db2codepage=1208。
1.22 如何查看节点目录和数据库目录的信息
解答:使用db2 list node directory 可以查看到所有节点编目信息,使用db2 list db directory 可以查看到所有数据库的编目信息。
1.23 db2 select * from …类似这样含有特殊字符的语句在Linux/Unix平台下,执行总是提示错误,无法执行
解答:由于sql语句含有特殊字符,所以需要将sql语句加上双引号。但在db2命令行下则不需要加。
1.24 如何获取当前时间
解答:使用db2 "select current time from sysibm.sysdummy1" 可以查看到当前的时间。
2、db2mtrk –i –d –v
3、db2 get snapshot for all on 数据库名 | more +/ Memory usage for database
4、db2 update db cfg using DFT_MON_BUFPOOL on永久打开Buffer pool监视开关,或通过db2 update monitor switches using bufferpools on 数据库名临时打开某个数据库对Buffer pool监视的开关(通过db2 get monitor switches查看临时开关),然后使用定期执行db2 get snapshot for bufferpools on 数据库名,并观察Buffer pool data logical reads、Buffer pool data physical reads,Buffer pool index logical reads、Buffer pool index physical reads字段来确定系统的数据与索引的页面命中率。
1.25 如何统计某个模式的对象数,并避免在删除数据库对象时误删除其他模式的对象
解答:可以在select语句的where字句中增加对模式的限制:select * from tabname where tabschema = ‘大写的模式名’ (前提是之前要对对象设置模式:set schema = ‘大写的模式名’),在删除某个模式的对象时,可以使用,类似此例的方法:drop procedure db2inst1.procname。
1.26 如何在命令行下查看错误代码的说明
解答:使用db2 ? sqlcode 可以查看到相应错误码的说明。如db2 ? sql01450n。
1.27 如何在一个存储过程中调用另一个存储过程
解答:在需要调用的地方,使用类似此例的方法及可:CALL xp_VerifyTables(i,nTableType,nVerifyTableResult,sError); 其中xp_VerifyTables为要调用的存储过程名,其参数在调用之前一定要声明,最好都进行初始化。
1.28 如果查询结果的字段比较少,如何将每条纪录的列在同一行,以增强可读性
解答:使用substr(col,exp1,exp2)对查询结果的各字段进行处理,如:db2 "select substr(procschema,1,15),substr(procname,1,25),create_time,valid from syscat.procedures"。exp1为输出字段col显示的起始位置,exp2为col显示的长度。
1.29 如果认为某个错误不必理会,如何屏蔽它,不进行捕捉它
解答:对全局使用,可以在db2安装目录下的cfg/db2cli.ini文件里添加如下:
IgnoreWarnList = "'sqlstate1', 'sqlstate2', ..." ,或使用命令db2 update cli cfg for section 段名 using "'sqlstate1', 'sqlstate2', ...";对某个应用,如在存储过程中,使用DECLARE CONTINUE HANDLER FOR SQLSTATE ‘01504’这种方式,跳过这种错误。
1.30 常用的几中数据类型的精确度和长度为多少
解答:
SMALLINT -32768~32767(精度为5的两字节的整型)
INTEGER -2147483648~2147483647(精度为10的4字节的整型)
BIGINT -9223372036854775808~9223372036854775807(精度为19的8字节整型)
REAL -3.402E+38~-1.175E-37或1.175E-37~3.402E+38(单精度浮点数
是一个实数的32位近似值)
DOUBLE/FLOAT (双精度浮点数是一个实数的64位近似值)
DECIMAL/NUMERIC (小数点的位置是由该DECIMAL数的精度和规模决定,规模
是该数的小数部分个数,其不能为负数和大于精度;最大精度为31)
CHAR 字符串的长度是有序字节数;长度一分配好就固定了,其长度从1~254。
VARCHAR 有三种变长字符串:
VARCHAR 32672字节长
LONG VARCHAR 32700字节长
CLOB 2G字节长(2147483647字节长)
1.31 使用EXECUTE执行SQL语句时需要注意些什么
解答:EXECUTE IMMEDIATE host-variable中的host-variable必须是小于最大语句的长度65535的字符串;如果SQL语句值需要执行一次或不频繁,可以使用EXECUTE IMMEDIATE;如果SQL语句需要重复地执行,应该使用PREPARE和EXECUTE语句,使用EXECUTE语句可以用参数标志;注意EXECUTE语句不能和SELECT和VALUES语句一起使用。PREPARE跟游标一起使用,就不需要EXECUTE语句。
1.32 通常如何使用GET DIAGNOSTICS语句
解答:使用GET DIAGNOSTICS 变量 = ROW_COUNT语句可以获取最后一次执行INSERT、UPDATE或DELETE之后的记录数;DB2 SQL PL 支持GET DIAGNOSTICS语句获取SQL语句执行的信息,它可以用来返回CONDITION HANDLER的错误信息;GET DIAGNOSTICS EXCEPTION 1 变量 = MESSAGE_TEXT;但这样就不能再获取行数了。注意:GET DIAGNOSTICS语句是不支持SELECT和SELECT INTO语句的。
1.33 如何查看DB2的日志
解答:在$HOME/sqllib/db2dump目录下,以c开头的目录为核心文件所在的目录(如:c56772.010),目录名以字母“c”开头,后跟受影响进程的进程标识(pid)号,扩展名是数据库分区号;没有字符开头的文件转储文件,它是在发生错误时创建的,它包含将有助于诊断问题(例如,内部控制块)的其它信息;db2diag.log为诊断日志,db2inst1.nfy纪录管理日志。
1.34 无法删除数据库
如果当前数据库仍在被使用,删除时将无法删除,并提示:
SQL1035N The database is currently in use. SQLSTATE=57019
解答:先将所有与数据库的连接断连:db2 connect reset(或db2 terminate),并将数据库离线(offline):db2 deactivate db 数据库名,然后再删除数据库。或者使用stopsap或db2stop停止db2数据库,然后db2start
1.35 查询数据库系统表中的对象失败
比如我们要从系统存储过程表中查询我们创建的某个存储过程的信息,如下所示:
SELECT count(*) FROM syscat.procedures where procname = sObjectName
如果sObjectName为小写的字符串,执行该查询语句将返回:
0 record(s) selected
解答:由于我们创建的对象,会在系统表中保存相关信息,而对象名在系统表中会变成大写,所以我们要从系统表中指定查询我们创建的对象时一定要使用大写,可以使用upper()来改为大写。
1.36 在DB2数据库中如何将整型转换为字符型
解答:在oracle中有一个to_char()的函数可以将整型转换为字符型,在DB2中也存在相似的函数char()来转换。
1.37 在对某个对象操作时,其名称由几部分连接而成,这样有时无法操作成功
解答:由于对象名由几部分组成,这样在连接组合时,各部分之间可能存在空白带,导致对象名和数据库实际的不一致,从而无法进行访问操作。因此,需要在连接之前,使用ltrim和rtrim将各部分的左右空白带去掉。
1.38 在多处使用同一个游标时,第一次使用后,第二次使用就发生错误,这是怎么回事呢?
解答:可能是前面使用完游标后,没有将游标关闭,下次接着再使用该游标时,发现该游标已打开,在使用中,将发生错误。应在每次使用完游标后,将其关闭。
1.39 在SuSe9下执行raw命令将裸设备和逻辑卷挂接时裸设备的归属属性会发生改变。
执行含有raw命令的脚本时,原归属于db2inst1.db2grp1的裸设备,变为归属属性为root.disk,在raw命令后加上修改归属命令chown无法执行。
解答:执行raw命令后归属属性会变为root.disk,但在刚执行raw命令后无法接着执行chown命令,因此,我们在raw命令后加上sleep 2语句,再执行chown命令即可。