blogjava-凯发k8网页登录http://www.blogjava.net/i369/category/17107.html北极心空zh-cnthu, 03 apr 2008 05:14:21 gmtthu, 03 apr 2008 05:14:21 gmt60[收藏] java数据类型,hibernate数据类型,标准sql数据类型之间的对应表 http://www.blogjava.net/i369/articles/190588.html芦苇芦苇thu, 03 apr 2008 04:39:00 gmthttp://www.blogjava.net/i369/articles/190588.htmlhttp://www.blogjava.net/i369/comments/190588.htmlhttp://www.blogjava.net/i369/articles/190588.html#feedback0http://www.blogjava.net/i369/comments/commentrss/190588.htmlhttp://www.blogjava.net/i369/services/trackbacks/190588.html
java数据类型 hibernate数据类型 标准sql数据类型
(ps:对于不同的db可能有所差异)
byte、java.lang.byte byte tinyint
short、java.lang.short short smallint
int、java.lang.integer integer ingeger
long、java.lang.long long bigint
float、java.lang.float float float
double、java.lang.double double double
java.math.bigdecimal big_decimal numeric
char、java.lang.character character char(1)
boolean、java.lang.boolean boolean bit
java.lang.string string varchar
boolean、java.lang.boolean yes_no char(1)('y'或'n')
boolean、java.lang.boolean true_false char(1)('y'或'n')
java.util.date、java.sql.date date date
java.util.date、java.sql.time time time
java.util.date、java.sql.timestamp timestamp timestamp
java.util.calendar calendar timestamp
java.util.calendar calendar_date date
byte[] binary varbinary、blob
java.lang.string text clob
java.io.serializable serializable varbinary、blob
java.sql.clob clob clob
java.sql.blob blob blob
java.lang.class class varchar
java.util.locale locale varchar
java.util.timezone timezone varchar
java.util.currency currency varchar
文章来源:

芦苇 2008-04-03 12:39
]]>
几种流行的数据库sql分页 http://www.blogjava.net/i369/articles/183602.html芦苇芦苇tue, 04 mar 2008 01:14:00 gmthttp://www.blogjava.net/i369/articles/183602.htmlhttp://www.blogjava.net/i369/comments/183602.htmlhttp://www.blogjava.net/i369/articles/183602.html#feedback0http://www.blogjava.net/i369/comments/commentrss/183602.htmlhttp://www.blogjava.net/i369/services/trackbacks/183602.html1.oracle:

  select * from ( select row_.*, rownum rownum_ from ( query_sql ) row_ where rownum =< max) where rownum_ >= min

 2.sql server:

  select top @pagesize * from tablename where id not in (select top @pagesize*(@page-1) id from tablename order by id) order by id

 3.mysql

  select * from tablename limit position, counter

 4.db2

  select * from (select *,rownumber() as row_next from tablename) where row_next between min and max 



芦苇 2008-03-04 09:14
]]>
oracle数据库的自动备份http://www.blogjava.net/i369/articles/181450.html芦苇芦苇fri, 22 feb 2008 08:48:00 gmthttp://www.blogjava.net/i369/articles/181450.htmlhttp://www.blogjava.net/i369/comments/181450.htmlhttp://www.blogjava.net/i369/articles/181450.html#feedback0http://www.blogjava.net/i369/comments/commentrss/181450.htmlhttp://www.blogjava.net/i369/services/trackbacks/181450.html
oracle数据库自动备份
     

 

相信为数不少的管理员每天都在做着同一样的工作——对数据进行备份。一旦哪一天疏忽了,而这一天又恰恰发生了故障,需要进行数据恢复,那么此时就无能为力了。假如每天设定一个固定的时间,自动进行备份,那该多好啊!下面笔者结合实践经验,谈一谈unix环境下oracle自动备份,以起到抛砖引玉的作用。
  
  我们计划让
在晚上23点做export导出备份,在凌晨2点将备份拷贝到磁带上,在凌晨4点将备份拷贝到另一台unix机器上,为此我们可进行如下操作:
  
  一、导出
  export命令将
中的数据备份成一个二进制,它通常有三种模式:用户模式、表模式和整个模式。本文拟采用用户模式,备份之前,应先建立一个备份目录,以容纳备份,比如可建一个/backup目录。接着我们可在unix的oracle目录下(也可以是其它目录)分别建立两个ora—backup,tar—backup。需要说明的是,前一个需要对oracle的参数进行初始化,为了方便起见,我们不妨将初始化命令放到一个中(名姑且定为ora—env),再由第一个调用它。
  
  1. ora—env
oracle的参数进行初始化,其内容如下:
  
  oracle—home=$oracle—home;export oracle—home
  
  oracle—sid=ora73;export oracle—sid
  
  oracle—term=sun;export oracle—term
  
  ld—library—path=$oracle—home/lib;export ld—library—path
  
  ora—nls32=$oracle—home/ocommon/nls/admin/data;export ora—nls
  
  path=.:/usr/ccs/bin:/usr/ucb:$oracle—home/bin:$path;export path
  
  display=host1:0;export display
  
  nls—lang=american—america.zhs16cgb231280;export nls—lang
  
  2. ora—backup
做export导出,导出的名可以任意定,本文定为字母“xx”加当天日期,即假如当天日期是12月10号,则导出的名为“xx1210.dmp”,以区别于其它日期的备份
  
  ora—backup
内容:
  
  ./oracle/ora—env
  
  #初始化oracle

  
  rq=′date +″%m%d″ ′
  
  #把当天日期赋予变量rq
  
  rm /backup/
  
  # 清空 /backup目录
  
  exp test/test file=/backup/xx$rq.dmp log=/backup/xx$rq.log
  
  本命令用于在$提示符下,导出test用户的数据(其口令亦为test),导出
及日志均放在/backup目录下。
  
  二、磁带备份
  tar—backup
将用export命令导出的数据拷贝到磁带上。
  
  tar—backup
内容:
  
  tar rvf /dev/rmt/0n/backup/
  
  本命令可将/backup目录下当天产生的
备份到磁带上。本中,tar命令使用了三个参数,其中r选项表示向磁带上拷入而不破坏磁带原来内容,v选项表示在拷贝过程中显示信息,f选项后面加上磁带设备名,指定向何处拷贝,n选项表示磁带机不倒带。/dev/rmt/0表示unix主机第一个磁带驱动器,同理,/dev/rmt/1则表示unix主机第二个磁带驱动器,依此类推。
  
  ora—env、ora—backup、tar—backup
编写完成后,分别使用下述命令:
  
  chmod 755 ora—env
  
  chmod 755 ora—backup
  
  chmod 755 tar—backup
  
  这样,三个
就都变成了可执行
  
  三、异地备份
  我们知道,通常可用ftp命令在两台主机间传输数据,但一般是通过交互方式实现的,即需要手工输入目标主机的ip地址、用户名、口令等。显然,这不符合自动备份的要求。所幸的是,我们可以通过编写一个.netrc的
来达到目标。这一必须命名为.netrc,且必须存放在启动ftp命令的机器上的用户注册目录中,该的权限应禁止组内或其它用户进行读访问。这样,当用户使用ftp命令的时候,将会在该用户的注册目录中寻找.netrc,如果能够寻找到,将会首先执行该,否则,会交互式地提示用户输入用户名、口令等。
  
  在使用ftp命令之前,应先在另一台作备份用的unix机器上建一目录,以容纳备份
,本文建的目录是/pub 。需要指出的是,为了加快备份速度,两台主机之间的传输速率应尽可能的高,最好位于同一局域网上。
  
  .netrc
内容如下:
  
  machine host2
  
  # host2为作备份用的主机名
  
  login oracle
  
  #oracle为备份主机上的一个用户
  
  password oracle
  
  #oracle用户的口令为oracle
  
  macdef init
  
  #定义一个名为init的宏,它将在自动注册进程的最后被执行
  
  bin
  
  #
的传输方式设为二进制
  
  lcd /backup
  
  # 进入本地工作目录/backup
  
  cd /pub
  
  # 进入备份主机目录/pub
  
  mput 
  
  # 将/backup目录下的所有
传输至备份主机
  
  bye
  
  #退出ftp会话进程
  
  .netrc
编写完成后,使用下述命令:
  
  chmod 600 .netrc
  
  这样,.netrc
就只能被该用户所访问。
  
  四、启动备份进程
  cron是一个永久进程,它由/etc/rc.local启动执行。cron检查/var/spool/cron/crontabs/目录中的
,找到所要执行的任务和执行任务的时间。
  
  crontab
的每一行由六个域(minutes、hours、day of month、month、day of week、 command)组成,域之间用空格或tab分开,其中:
  
  minutes:分钟域,值的范围是0到59
  
  hours:小时域,值的范围是0到23
  
  day of month:日期,值的范围是1到31
  
  month:月份,值的范围是1到12
  
  day of week:星期,值的范围是0到6,星期日值为0
  
  command:所要运行的命令
  
  如果一个域是,表明命令可以在该域所有可能的取值范围内执行。
  
  如果一个域是由连
隔开的两个数字,表明命令可以在两个数字之间的范围内执行(包括两个数字本身)。
  
  如果一个域是由逗号隔开的一系列值组成的,表明命令可以在这些值组成的范围内执行。
  
  如果日期域和星期域都有值,则这两个域都有效。
  
  现在,我们编写一个
,用以启动自动备份进程。值得注意的是,该只能在oracle用户名下用crontab -e 命令来编辑,否则将不会被定时执行,名定为oracle将放在/var/spool/cron/crontabs 目录下。编辑完成后,可以在oracle的$提示符下,用crontab -l命令来查看。
  
  oracle
内容:
  
  0 23    /oracle/ora—backup
  
  # 每天23点对
执行备份
  
  0 2    /oracle/tar—backup
  
  # 每天2点将
备份到磁带上
  
  0 4    ftp -i host2
  
  # 每天4点将
备份到另一台主机上
  
  经过以上的操作后,
每天晚上将自动产生一个备份,并且自动将备份分别拷贝到磁带上和另一台主机上。管理员需要做的是,隔几天换一盘磁带(更换磁带的周期取决于备份的大小和磁带的容量)和清理备份目录。这样,他们就可以从备份数据的繁琐中解脱出来,去做其它更有意义的工作。而既实现了磁带备份,又实现了异地备份,相应的安全性也大大提高了。

转自:

实现脚本
rem #=========================================================================
rem # purpose:exp oracle db zytk30 to file zytk30_yyyymmddhhmm.dmp,
rem #         and delete the file,7 days ago created
rem # author :comer chu, 2006

rem # history:
rem # note   :erveryday excute this script by windows task schedule 
rem #=========================================================================

@echo off
rem 1#---获得当前日期和7天前日期,date的格式 "yyyy-mm-dd"----------
set dt=�te:~0,10%
set i=1

:forok
if %i%==1 goto i01
if %i%==2 goto i02
if %i%==3 goto i03
if %i%==4 goto i04
if %i%==5 goto i05
if %i%==6 goto i06
if %i%==7 goto i07

:i01
set i=2
goto nextok
:i02
set i=3
goto nextok
:i03
set i=4
goto nextok
:i04
set i=5
goto nextok
:i05
set i=6
goto nextok
:i06
set i=7
goto nextok
:i07
set i=8
goto nextok

:nextok
set dy=%dt:~0,4%
set dm=%dt:~5,2%
set dd=%dt:~8,2%

if %dm%�%==0101 goto l01
if %dm%�%==0201 goto l02
if %dm%�%==0301 goto l07
if %dm%�%==0401 goto l02
if %dm%�%==0501 goto l04
if %dm%�%==0601 goto l02
if %dm%�%==0701 goto l04
if %dm%�%==0801 goto l02
if %dm%�%==0901 goto l02
if %dm%�%==1001 goto l05
if %dm%�%==1101 goto l03
if %dm%�%==1201 goto l06

if �%==02 goto l10
if �%==03 goto l10
if �%==04 goto l10
if �%==05 goto l10
if �%==06 goto l10
if �%==07 goto l10
if �%==08 goto l10
if �%==09 goto l10
if �%==10 goto l11
set /a dd=dd-1
set dt=%dy%-%dm%-�%
goto end
:l10
set /a dd=�:~1,1%-1
set dt=%dy%-%dm%-0�%
goto end
:l11
set dt=%dy%-%dm%-09
goto end

:l02
set /a dm=%dm:~1,1%-1
set dt=%dy%-0%dm%-31
goto end
:l04
set /a dm=dm-1
set dt=%dy%-0%dm%-30
goto end

:l05
set dt=%dy%-09-30
goto end
:l03
set dt=%dy%-10-31
goto end
:l06
set dt=%dy%-11-30
goto end
:l01
set /a dy=dy-1
set dt=%dy%-12-31
goto end

:l07
set /a "dd=dy%%4"
if not �%==0 goto l08
set /a "dd=dy%0"
if not �%==0 goto l09
set /a "dd=dy%@0"
if �%==0 goto l09
:l08
set dt=%dy%-02-28
goto end
:l09
set dt=%dy%-02-29
goto end

:end
if %i%==2 goto forok
if %i%==3 goto forok
if %i%==4 goto forok
if %i%==5 goto forok
if %i%==6 goto forok
if %i%==7 goto forok
if %i%==8 goto db

:db
rem 2#---备份oracle数据到本机,并且只备份表空间,前提本机正确配置了oracle的客户端,否则exp无法执行!
rem td like 20060827183200
set td=�te:~0,4%�te:~5,2%�te:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%
e:\oracleback
exp tablespaces=(zytk30_ac,zytk30_op,zytk30_id,zytk30_bak) file=e:\oracleback\zytk30_%td%.dmp log=e:\oracleback\expzytk30.log buffer=800000
rar a zytk30_%td%.rar zytk30_%td%.dmp

rem set dt to format "yyyymmdd"
set dt=%dt:~0,4%%dt:~5,2%%dt:~8,2%
rem 3#---删除7天前的备份文件---------------------------------------------------------
del e:\oracleback\zytk30_%dt%*.rar

rem 4#---删除当天dmp备份文件--------------------------------------------------------
del e:\oracleback\zytk30_%td%*.dmp

定时任务
以上内容保存为exp_zytk30.bat,再使用windows自带的任务计划来计划程序每天自动去备份数据了
具体步骤:控制面板-\任务计划-\添加任务计划,选择每天,选择exp_zytk30.bat就ok了。

说明
上面是保留备份最近7天的数据,每天一个(当然也可以多个,设置任务计划即可)。你可以修改上面的代码到最近8、9甚至n天

比如:修改成保留8天的备份
在if %i%==7 goto i07 下增加
if %i%==8 goto i08
:i07
set i=8

在goto nextok 下增加
:i08
set i=9
goto nextok

将if %i%==8 goto mdb 改为
if %i%==8 goto forok
if %i%==9 goto mdb

依次类推到n天。也可以针对文件夹的删除,稍作变动即可。



芦苇 2008-02-22 16:48
]]>
在pl/sql 开发中调试存储过程和函数的一般性方法 http://www.blogjava.net/i369/articles/164185.html芦苇芦苇fri, 30 nov 2007 02:06:00 gmthttp://www.blogjava.net/i369/articles/164185.htmlhttp://www.blogjava.net/i369/comments/164185.htmlhttp://www.blogjava.net/i369/articles/164185.html#feedback0http://www.blogjava.net/i369/comments/commentrss/164185.htmlhttp://www.blogjava.net/i369/services/trackbacks/164185.html在pl/ 开发中调试和的一般性方法
摘要: 在plsql中提供的强大特性使得开发人员可以在数据库端完成功能足够复杂的任务, 本文将结合oracle提供的相关程序包(package)以及一个非常优秀的第三方开发工具来介绍在plsql中开发及调试存储过程的方法,当然也适用于函数。

凯发k8网页登录的版权声明: 本文可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息。
原文出处: http://www.aiview.com/notes/ora_using_proc.htm
作者: 张洋 alex_doesathotmail.com
最后更新: 2003-8-2
 目录 准备工作 从一个最简单的存储过程开始 调试存储过程 在存储过程中写日志文件 捕获违例
 
oracle 在plsql中提供的强大特性使得数据库开发人员可以在数据库端完成功能足够复杂的任务, 本文将结合oracle提供的相关程序包(package)以及一个非常优秀的第三方开发工具来介绍在plsql中开发及调试存储过程的方法,当然也适用于函数。

本文所采用的软件版本和环境:
: oracle 8.1.2 for 8
pl/sql developer 4.5
准备工作
在开始之前, 假设您已经安装好了oracle的数据库服务, 并已经建立数据库, 设置好监听程序, 以允许客户端进行连接; 同时您已经拥有了一台设置好本地net服务名的开发客户机, 并已经安装好pl/sql developer开发工具的以上版本或者更新.

在下面的示例代码中,我们使用oracle数据库默认提供的示例表 scott.dept 和 scott.emp. 建表的语句如下:

create table scott.dept
(
deptno number(2) not null,
dname varchar2(14),
loc varchar2(13)
)

create table scott.emp
(
empno number(4) not null,
ename varchar2(10),
job varchar2(9),
mgr number(4),
hiredate date,
sal number(7,2),
comm number(7,2),
deptno number(2)
)
从一个最简单的存储过程开始
我们现在需要编写一个存储过程, 输入一个部门的编号, 要求取得属于这个部门的所有员工信息, 包括员工编号和姓名. 员工的信息通过一个cursor返回给.

create or replace procedure usp_getempbydept(
in_deptno in number,
out_curemp out pkg_const.ref_cursor 
) as
begin
open curemp for 
select empno,
ename
from scott.emp
where deptno = in_deptno;

end usp_getempbydept;

上面我们定义了两个参数, 其中第二个参数需要利用cursor返回员工信息, plsql中提供了ref cursor的数据类型, 可以采用两种方式进行定义, 一种是强类型,一种是弱类型, 前者在定义时指定cursor返回的数据类型, 后者可以不指定, 由数据库根据查询语句进行动态绑定.

在使用前必须首先使用type关键字进行定义, 我们把数据类型ref_cursor定义在自定义的程序包中: pkg_const

create or replace package pkg_const as
type ref_cursor is ref cursor;

end pkg_const;

注意: 这个包需要在创建上面的存储过程之前被编译, 因为存储过程用到了包中定义的数据类型.
调试存储过程
使用pl/sql developer 登录数据库, 用户名scott, 密码默认为: tiger. 将包和存储过程分别编译, 然后在左侧浏览器的procedure栏目下找到新建的存储过程, 点击右键, 选择"test"/"测试", 在下面添好需要输入的参数值, 按快捷键f8直接运行存储过程, 执行完成之后, 可以点开返回参数旁边的按钮查看结果集.

如果存储过程内部语句较复杂, 可以按f9进入存储过程进行跟踪调试. pl/sql developer提供与通用开发工具类似的跟踪调试功能, 分为step、step over、step out 等多种方式, 对于变量也可进行trace或者手动赋值。
在存储过程中写日志文件
以上方法可以在开发阶段对编写和调试存储过程提供最大限度的方便,但为了在系统测试或者生产环境中确认我们的代码是否正常工作时,就需要记录log。

plsql提供了一个utl_file包,通过定义utl_file包中的file_type类型,可以获得一个文件句柄,通过此句柄可以实现一般的文件操作功能。但默认的数据库参数是不允许使用utl_file包的,需要手动进行配置,使用gui的管理工具或者手工编辑init.ora文件,找到 "utl_file_dir" 参数,如果没有,则添加一行,修改成如下:

utl_file_dir=@#/usr/tmp@#

或者

utl_file_dir=*

第一种方式限定了在utl_file包中可以存取的目录,第二种方式则不进行限定。无论哪种方式,都要保证运行数据库实例的用户,一般是oracle,拥有此目录的存取权限,否则在使用包的过程中会报出错误信息。

注意等号左右不要留空格,可能会引起解析错误,导致设置无效。

下面在上面的存储过程中加入记录log的代码:

create or replace procedure usp_getempbydept(
in_deptno in number,
out_curemp out pkg_const.ref_cursor 
) as
fi utl_file.file_type;

begin
if( pkg_const.debug ) then 
fi := utl_file.fopen( pkg_const.log_path, to_char( sysdate, @#yyyymmdd@# ) || @#.log@#, @#a@# );
utl_file.put_line( fi, @# ****** calling usp_getempbydept begin at @# || to_char( sysdate, @#hh24:mi:ss mm-dd-yyyy@# ) || @# ******@# );
utl_file.put_line( fi, @# input:@# );
utl_file.put_line( fi, @# in_chid => @# || in_chid );
end if;

open curemp for 
select empno,
ename
from scott.emp
where deptno = in_deptno;

if( pkg_const.debug ) then 
utl_file.put_line( fi, @# return:@# );
utl_file.put_line( fi, @# out_curemp: unknown@# );
utl_file.put_line( fi, @# ****** usp_getempbydept end at @# || to_char( sysdate, @#hh24:mi:ss mm-dd-yyyy@# ) || @# ******@# );
utl_file.new_line( fi, 1 );
utl_file.fflush( fi );
utl_file.fclose( fi );
end if;

exception
when others then

if( pkg_const.debug ) then 
if( utl_file.is_open( fi )) then
utl_file.put_line( fi, @# error:@# );
utl_file.put_line( fi, @# sqlcode = @# || sqlcode );
utl_file.put_line( fi, @# sqlerrm = @# || sqlerrm );
utl_file.put_line( fi, @# ****** usp_getempbydept end at @# || to_char( sysdate, @#hh24:mi:ss mm-dd-yyyy@# ) || @# ******@# );
utl_file.new_line( fi, 1 );
utl_file.fflush( fi );
utl_file.fclose( fi );
end if;
end if;

/* raise the exception for caller. */
raise_application_error( -20001, sqlcode || @#|@# || sqlerrm );

end usp_getempbydept;

在上面的代码中,我们又引用了两个新的常量:

debug
log_path

分别定义了调试开关参数和文件路径参数,对此,我们需要修改我们前面定义的程序包:

create or replace package pkg_const as
type ref_cursor is ref cursor;

debug constant boolean := true;
log_path constant varchar2(256) := @#/usr/tmp/db@#;

end pkg_const;

在代码块的起始处,将输入参数的名称与值成对的记入log文件,在代码块的正常退出部分,将输出参数的名称和数值也成对的记录下来,如果程序非正常退出,则在exception 的处理部分,把错误代码及错误信息写入log文件。一般使用这些信息就可以较迅速的找出程序运行中出现的大部分错误。

注意:如果返回参数的类型是cursor,是无法在存储过程内部将返回的结果集一条一条写入log文件的,此时应当结合在调用程序中记录的log信息,下面具体分析一下上述代码:

fopen() 函数使用给定的路径和文件名,新建文件或者打开已有的文件,这取决于最后一个参数, 当使用@#a@#作为参数时,如果给定的文件不存在,则以此文件名新建文件,并以写@#w@#方式打开,返回一个文件句柄。

上面代码以天为单位建立日志文件,并且,不同存储过程之间共享log文件,这种方式的优点是可能通过查看log文件追溯出程序的调用顺序和逻辑。实际应用中,应根据不同的需求,具体分析,可以使用更复杂的log文件生成策略。

put_line() 函数用于写入字符到文件,并在字符串的结尾加入换行符,若不想换行,使用put()函数。

new_line() 函数用于生成指定数目的空行,上面对文件的修改写在一个缓冲区内,执行fflush() 将立即将buffer中的内容写入文件,当你希望在文件还未关闭之前就需要读取已经作出的改变时,调用此函数。

is_open() 函数用于判断一个文件句柄的状态,最后用完一定记得把打开的文件关闭,调用fclose() 函数,并且应把这个语句加入exception的处理中,防止过程非正常退出时留下未关闭的文件句柄。
捕获违例
在plsql中,你可以通过两个内建的函数sqlcode 和sqlerrm 来找出发生了哪类错误并且获得详细的message信息,在内部违例发生时,sqlcode返回从-1至-20000之间的一个错误号,但有一个例外,仅当内部违例no_data_found 发生时,才会返回一个正数 100。当用户自定义的违例发生时,sqlcode返回+1,除非用户使用 pragma exception_init 将自定义违例绑定一个自定义的错误号。当没有任何违例抛出时,sqlcode返回0。

下面是一个简单的捕获违例的例子:

declare
i number(3);
begin
select 100/0 into i from dual;

exception
when zero_divide then
...
end;

在上面的exception 中我们使用others 关键字捕获所有未明确指定的违例,并进行记录log处理,同时我们必须在做完这些处理之后,把违例再次抛出给调用程序,调用函数:
raise_application_error(),此函数向调用程序返回一个用户自定义的错误号码和错误信息,第一个参数指定一个错误号码,由用户自行定义,但必须限定在-20000至-20999之间,避免与oracle内部定义exception的错误号码冲突,第二个参数需要返回一个字符串,这里我们使用它返回我们上面捕获的错误号码和错误描述。

注意:通过raise_application_error()函数抛出的违例已经不是开始在程序块内部捕获的内部违例,而是由用户自己定义的。


芦苇 2007-11-30 10:06
]]>
c3p0连接池详细配置 http://www.blogjava.net/i369/articles/151043.html芦苇芦苇mon, 08 oct 2007 05:55:00 gmthttp://www.blogjava.net/i369/articles/151043.htmlhttp://www.blogjava.net/i369/comments/151043.htmlhttp://www.blogjava.net/i369/articles/151043.html#feedback0http://www.blogjava.net/i369/comments/commentrss/151043.htmlhttp://www.blogjava.net/i369/services/trackbacks/151043.html (转载)




3


30


1000


false


test


false


100





null


false


60


3


60


15


100





3


root


password





select id from test where id=1


300


false


true


root


false

con_test
30000
30
10
30
25
10
0




200

300


原地址:http://msq.javaeye.com/blog/60387



芦苇 2007-10-08 13:55
]]>
sql server系统表详细说明 http://www.blogjava.net/i369/articles/149448.html芦苇芦苇sat, 29 sep 2007 01:41:00 gmthttp://www.blogjava.net/i369/articles/149448.htmlhttp://www.blogjava.net/i369/comments/149448.htmlhttp://www.blogjava.net/i369/articles/149448.html#feedback0http://www.blogjava.net/i369/comments/commentrss/149448.htmlhttp://www.blogjava.net/i369/services/trackbacks/149448.html阅读全文

芦苇 2007-09-29 09:41
]]>
oracle字符集理解http://www.blogjava.net/i369/articles/148004.html芦苇芦苇tue, 25 sep 2007 02:53:00 gmthttp://www.blogjava.net/i369/articles/148004.htmlhttp://www.blogjava.net/i369/comments/148004.htmlhttp://www.blogjava.net/i369/articles/148004.html#feedback0http://www.blogjava.net/i369/comments/commentrss/148004.htmlhttp://www.blogjava.net/i369/services/trackbacks/148004.htmloracle字符集理解:
 
一.引言

    oracle数据库字符集,即oracle全球化支持(globalization support),或即国家语言支持(nls)其作用是用本国语言和格式来存储、处理和检索数据。利用全球化支持,oracle为用户提供自己熟悉的数据库母语环境,诸如日期格式、数字格式和存储序列等。oracle可以支持多种语言及字符集,其中oracle8i支持48种语言、76个国家地域、229种字符集,而oracle9i则支持57种语言、88个国家地域、235种字符集。由于oracle字符集种类多,且在存储、检索、迁移oracle数据时多个环节与字符集的设置密切相关,因此在实际的应用中,数据库开发和管理人员经常会遇到有关oracle字符集方面的问题。本文通过以下几个方面阐述,对oracle字符集做简要分析

二.字符集基本知识

2.1字符集
    实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值编码的集合。oracle数据库最早支持的编码方案是us7ascii。
    oracle的字符集命名遵循以下命名规则:
   
    即:  <语言><比特位数><编码>
    比如: zhs16gbk表示采用gbk编码格式、16位(两个字节)简体中文字符集

2.2字符编码方案
2.2.1 单字节编码
    (1)单字节7位字符集,可以定义128个字符,最常用的字符集为us7ascii
    (2)单字节8位字符集,可以定义256个字符,适合于欧洲大部分国家
    例如:we8iso8859p1(西欧、8位、iso标准8859p1编码)
2.2.2 多字节编码
    (1)变长多字节编码
    某些字符用一个字节表示,其它字符用两个或多个字符表示,变长多字节编码常用于对亚洲语言的支持,   例如日语、汉语、印地语等
    例如:al32utf8(其中al代表all,指适用于所有语言)、zhs16cgb231280
    (2)定长多字节编码
    每一个字符都使用固定长度字节的编码方案,目前oracle唯一支持的定长多字节编码是af16utf16,也是仅用于国家字符集
2.2.3 unicode编码
    unicode是一个涵盖了目前全世界使用的所有已知字符的单一编码方案,也就是说unicode为每一个字符提供唯一的编码。utf-16是unicode的16位编码方式,是一种定长多字节编码,用2个字节表示一个unicode字符,af16utf16是utf-16编码字符集。
    utf-8是unicode的8位编码方式,是一种变长多字节编码,这种编码可以用1、2、3个字节表示一个unicode字符,al32utf8,utf8、utfe是utf-8编码字符集

2.3 字符集超级
    当一种字符集(字符集a)的编码数值包含所有另一种字符集(字符集b)的编码数值,并且两种字符集相同编码数值代表相同的字符时,则字符集a是字符集b的超级,或称字符集b是字符集a的子集。
    oracle8i和oracle9i官方文档资料中备有子集-超级对照表(subset-superset pairs),例如:we8iso8859p1是we8mswin1252的子集。由于us7ascii是最早的oracle数据库编码格式,因此有许多字符集是us7ascii的超集,例如we8iso8859p1、zhs16cgb231280、zhs16gbk都是us7ascii的超集。

2.4 数据库字符集(oracle服务器端字符集)
    数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库时,可以指定字符集(character set)和国家字符集(national character set)。
2.4.1字符集
    (1)用来存储char, varchar2, clob, long等类型数据
    (2)用来标示诸如表名、列名以及pl/sql变量等
    (3)用来存储sql和pl/sql程序单元等
2.4.2国家字符集:
    (1)用以存储nchar, nvarchar2, nclob等类型数据
    (2)国家字符集实质上是为oracle选择的附加字符集,主要作用是为了增强oracle的字符处理能力,因为nchar数据类型可以提供对亚洲使用定长多字节编码的支持,而数据库字符集则不能。国家字符集在oracle9i中进行了重新定义,只能在unicode编码中的af16utf16和utf8中选择,默认值是af16utf16
2.4.3查询字符集参数
    可以查询以下数据字典或视图查看字符集设置情况
    nls_database_parameters、props$、v$nls_parameters
    查询结果中nls_characterset表示字符集,nls_nchar_characterset表示国家字符集
2.4.4修改数据库字符集
    按照上文所说,数据库字符集在创建后原则上不能更改。如果需要修改字符集,通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换,或通过alter database character set语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如utf8是us7ascii的超集,修改数据库字符集可使用alter database character set utf8。

2.5 客户端字符集(nls_lang参数)
2.5.1客户端字符集含义
    客户端字符集定义了客户端字符数据的编码方式,任何发自或发往客户端的字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连接的各种应用,例如sqlplus,exp/imp等。客户端字符集是通过设置nls_lang参数来设定的。
2.5.2 nls_lang参数格式
    nls_lang=_.
    language:显示oracle消息,校验,日期命名
    territory:指定默认日期、数字、货币等格式
    client character set:指定客户端将使用的字符集
    例如:nls_lang=american_america.us7ascii 
    american是语言,america是地区,us7ascii是客户端字符集
2.5.3客户端字符集设置方法
     1)unix环境
         $nls_lang=“simplified chinese”_china.zhs16gbk
         $export nls_lang
         编辑oracle用户的profile文件
    2)windows环境
         编辑注册表
         regedit.exe---hkey_local_machine---software---oracle—home0
2.5.4 nls参数查询
    oracle提供若干nls参数定制数据库和用户机以适应本地格式,例如有nls_language,nls_date_format,nls_calender等,可以通过查询以下数据字典或v$视图查看。
    nls_database_parameters--显示数据库当前nls参数取值,包括数据库字符集取值
    nls_session_parameters--显示由nls_lang 设置的参数,或经过alter session 改变后的参数值(不包括由nls_lang 设置的客户端字符集)
    nls_instance_paramete--显示由参数文件init.ora 定义的参数v$nls_parameters--显示数据库当前nls参数取值
2.5.5修改nls参数
    使用下列方法可以修改nls参数
    (1)修改实例启动时使用的初始化参数文件
    (2)修改环境变量nls_lang
    (3)使用alter session语句,在oracle会话中修改
    (4)使用某些sql函数
    nls作用优先级别:sql function>alter session>环境变量或注册表>参数文件>数据库默认参数

三.导入/导出与字符集转换

3.1 exp/imp
    export 和 import 是一对读写oracle数据的工具。export 将 oracle 数据库中的数据输出到操作系统文件中, import 把这些文件中的数据读到oracle 数据库中,由于使用exp/imp进行数据迁移时,数据从源数据库到目标数据库的过程中有四个环节涉及到字符集,如果这四个环节的字符集不一致,将会发生字符集转换。

exp                       

imp                       

    四个字符集是
   (1)源数据库字符集
   (2)export过程中用户会话字符集(通过nls_lang设定)
   (3)import过程中用户会话字符集(通过nls_lang设定)
   (4)目标数据库字符集

3.2导出的转换过程
    在export过程中,如果源数据库字符集与export用户会话字符集不一致,会发生字符集转换,并在导出文件的头部几个字节中存储export用户会话字符集的id号。在这个转换过程中可能发生数据的丢失。
例:如果源数据库使用zhs16gbk,而export用户会话字符集使用us7ascii,由于zhs16gbk是16位字符集,而us7ascii是7位字符集,这个转换过程中,中文字符在us7ascii中不能够找到对等的字符,所以所有中文字符都会丢失而变成“?? ”形式,这样转换后生成的dmp文件已经发生了数据丢失。
因此如果想正确导出源数据库数据,则export过程中用户会话字符集应等于源数据库字符集或是源数据库字符集的超集

3.3导入的转换过程
    (1)确定导出数据库字符集环境
    通过读取导出文件头,可以获得导出文件的字符集设置
    (2)确定导入session的字符集,即导入session使用的nls_lang环境变量
    (3)imp读取导出文件
    读取导出文件字符集id,和导入进程的nls_lang进行比较
    (4)如果导出文件字符集和导入session字符集相同,那么在这一步骤内就不需要转换,如果不同,就需要把数据转换为导入session使用的字符集。可以看出,导入数据到数据库过程中发生两次字符集转换
    第一次:导入文件字符集与导入session使用的字符集之间的转换,如果这个转换过程不能正确完成,import向目标数据库的导入过程也就不能完成。
    第二次:导入session字符集与数据库字符集之间的转换。
    然而,oracle8i的这种转换只能在单字节字符集之间进行,oracle8i导入session不支持多字节字符集之间的转换,因此为了避免第一次转换,导入session使用的nls_lang与导出文件字符集相同,第二次转换(通过sql*net)支持任何两种字符集。以上情况在oracle9i中略有不同

四.乱码问题

    oracle在数据存储、迁移过程中经常发生字符乱码问题,归根到底是由于字符集使用不当引起。下面以使用客户端sqlplus向数据库插入数据和导入/导出(exp/imp)过程为例,说明乱码产生的原因。

4.1使用客户端sqlplus向数据库存储数据
    这个过程存在3个字符集设置
    (1)客户端应用字符集
    (2)客户端nls_lang参数设置
    (3)服务器端数据库字符集(character set)设置
    客户端应用sqlplus中能够显示什么样的字符取决于客户端操作系统语言环境(客户端应用字符集),但在应用中录入这些字符后,这些字符能否在数据库中正常存储,还与另外两个字符集设置紧密相关,其中客户端nls_lang参数主要用于字符数据传输过程中的转换判断。常见的乱码大致有两种情形:
    (1)汉字变成问号“?”;
当从字符集a 转换成字符集b时,如果转换字符之间不存在对应关系,nls_lang使用替代字符“?”替代无法映射的字符
    (2)汉字变成未知字符(虽然有些是汉字,但与原字符含义不同)
转换存在对应关系,但字符集a 中的字符编码与字符集b 中的字符编码代表不同含义

4.2发生乱码原因 
    乱码产生是由于几个字符集之间转换不匹配造成,分以下几种情况:
    (注:字符集之间如果不存在子集、超集对应关系时的情况不予考虑,因为这种情况下字符集之间转换必产生乱码)   
    1)服务器端数据库字符集与客户端应用字符集相同,与客户端nls_lang参数设置不同
    如果客户端nls_lang字符集是其它两种字符集的子集,转换过程将出现乱码。
    解决方法:将三种字符集设置成同一字符集,或nls_lang字符集是其它两种字符集的超集
    2)服务器端数据库字符集与客户端nls_lang参数设置相同,与客户端应用字符集不同
    如果客户端应用字符集是其它两种字符集的超集时,转换过程将出现乱码,但对于单字节编码存储中文问题,可参看本文第5章节的分析
    3)客户端应用字符集、客户端nls_lang参数设置、服务器端数据库字符集互不相同
    此种情况较为复杂,但三种字符集之间只要有不能转换的字符,则必产生乱码

4.3导入/导出过程出现乱码原因
    这个过程存在4个字符集设置,在3.1章节中已分析
   (1)源数据库字符集
   (2)exp过程中nls_lang参数
   (3)imp过程中nls_lang参数
   (4)目标数据库字符集
    出现乱码原因
    1)当源数据库字符集不等于exp过程中nls_lang参数,且源数据库字符集是exp过程中nls_lang的子集,才能保证导出文件正确,其他情况则导出文件字符乱码
    2)exp过程中nls_lang字符集不等于imp过程中nls_lang字符集,且exp过程中nls_lang字符集是imp过程中nls_lang字符集的子级, 才能保证第一次转换正常,否则第一次转换中出现乱码。
    3)如果第一次转换正常,imp过程中nls_lang字符集是目标数据库字符集的子集或相同,才能保证第二次转换正常,否则则第二次转换中出现乱码

五.单字节编码存储中文问题

    由于历史的原因,早期的oracle没有中文字符集(如oracle6、oracle7、oracle7.1),但有的用户从那时起就使用数据库了,并用us7ascii字符集存储了中文,或是有的用户在创建数据库时,不考虑清楚,随意选择一个默认的字符集,如we8iso8859p1或us7ascii,而这两个字符集都没有汉字编码,虽然有些时候选用这种字符集好象也能正常使用,但用这种字符集存储汉字信息从原则上说就是错误的,它会给数据库的使用与维护带来一系列的麻烦。
    正常情况下,要将汉字存入数据库,数据库字符集必须支持中文,而将数据库字符集设置为us7ascii等单字节字符集是不合适的。us7ascii字符集只定义了128个符号,并不支持汉字。另外,如果在sql*plus中能够输入中文,操作系统缺省应该是支持中文的,但如果在nls_lang中的字符集设置为us7ascii,显然也是不正确的,它没有反映客户端的实际情况。但在实际应用中汉字显示却是正确的,这主要是因为oracle检查数据库与客户端的字符集设置是同样的,那么数据在客户与数据库之间的存取过程中将不发生任何转换,但是这实际上导致了数据库标识的字符集与实际存入的内容是不相符的。而在select的过程中,oracle同样检查发现数据库与客户端的字符集设置是相同的,所以它也将存入的内容原封不动地传送到客户端,而客户端操作系统识别出这是汉字编码所以能够正确显示。
    在这个例子中,数据库与客户端都没有设置成中文字符集,但却能正常显示中文,从应用的角度看好象没问题。然而这里面却存在着极大的隐患,比如在应用length或substr等字符串函数时,就可能得到意外的结果。
    对于早期使用us7ascii字符集数据库的数据迁移到oracle8i/9i中(使用zhs16gbk),由于原始数据已经按照us7ascii格式存储,对于这种情况,可以通过使用oracle8i的导出工具,设置导出字符集为us7ascii,导出后使用ultraedit等工具打开dmp文件,修改第二、三字符,修改 0001 为0354,这样就可以将us7ascii字符集的数据正确导入到zhs16gbk的数据库中。

六.结束语

    为了避免在数据库迁移过程中由于字符集不同导致的数据损失,oracle提供了字符集扫描工具(character set scanner),通过这个工具我们可以测试在数据迁移过程中由于字符集转换可能带来的问题,然后根据测试结果,确定数据迁移过程中最佳字符集凯发天生赢家一触即发官网的解决方案。



芦苇 2007-09-25 10:53
]]>
oracle 字符集问题 http://www.blogjava.net/i369/articles/147165.html芦苇芦苇fri, 21 sep 2007 09:30:00 gmthttp://www.blogjava.net/i369/articles/147165.htmlhttp://www.blogjava.net/i369/comments/147165.htmlhttp://www.blogjava.net/i369/articles/147165.html#feedback0http://www.blogjava.net/i369/comments/commentrss/147165.htmlhttp://www.blogjava.net/i369/services/trackbacks/147165.html
     

1. nls_lang 参数组成
nls_lang参数由以下部分组成:
nls_lang=_.

nls_lang各部分含义如下:
language指定:
-oracle消息使用的语言
-日期中月份和日显示
territory指定
-货币和数字格式
-地区和计算星期及日期的习惯
characterset:
-控制客户端应用程序使用的字符集
通常设置或者等于客户端(如windows)代码页
或者对于unicode应用设置为utf8

在windows上查看当前系统的代码页可以使用chcp命令:
e:\>chcp
 活动的代码页: 936

代码页936也就是中文字符集 gbk,在microsoft的官方站点上,我们可以遭到关于936代码页的具体编码规则,请参考以下链接:


2. 查看 nls_lang 的方法
windows使用:

echo %nls_lang%
如:
e:\>echo %nls_lang%
american_america.zhs16gbk

unix使用:

env|grep nls_lang
如:
/opt/oracle>env|grep nls_lang
nls_lang=american_china.zhs16gbk

windows客户端设置,可以在注册表中更改nls_lang,具体键值位于:
hkey_local_machine\software\oracle\homexx\
xx指存在多个oracle_home时系统编号。


3. 查看数据库当前字符集参数设置
select * from v$nls_parameters;


4. 查看数据库可用字符集参数设置
select * from v$nls_valid_values;


5. 客户端 nls_lang 的设置方法
windows:
# 常用中文字符集
set nls_lang=simplified chinese_china.zhs16gbk
# 常用unicode字符集
set nls_lang=american_america.al32utf8
可以通过修改注册表键值永久设置
hkey_local_machine\software\oracle\homexx\nls_lang

unix:
# 常用unicode字符集
export nls_lang=american_america.al32utf8
# 常用中文字符集
export nls_lang="simplified chinese_china".zhs16gbk
可以编辑 bash_profile 文件进行永久设置
vi .bash_profile
nls_lang="simplified chinese_china".zhs16gbk export nls_lang
# 使 bash_profile 设置生效
source .bash_profile


参考:
 



一.引言

    oracle数据库字符集,即oracle全球化支持(globalization support),或即国家语言支持(nls)其作用是用本国语言和格式来存储、处理和检索数据。利用全球化支持,oracle为用户提供自己熟悉的数据库母语环境,诸如日期格式、数字格式和存储序列等。oracle可以支持多种语言及字符集,其中oracle8i支持48种语言、76个国家地域、229种字符集,而oracle9i则支持57种语言、88个国家地域、235种字符集。由于oracle字符集种类多,且在存储、检索、迁移oracle数据时多个环节与字符集的设置密切相关,因此在实际的应用中,数据库开发和管理人员经常会遇到有关oracle字符集方面的问题。本文通过以下几个方面阐述,对oracle字符集做简要分析

二.字符集基本知识

2.1字符集
    实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值编码的集合。oracle数据库最早支持的编码方案是us7ascii
    oracle
的字符集命名遵循以下命名规则 :
   
    <
语言><比特位数><编码
>
   
比如: zhs16gbk表示采用gbk编码格式、16位(两个字节)简体中文字符集

2.2字符编码方案
2.2.1 单字节编码
   
1)单字节7位字符集,可以定义128个字符,最常用的字符集为 us7ascii
   
2)单字节8位字符集,可以定义256个字符,适合于欧洲大部分国家

   
例如:we8iso8859p1(西欧、8位、iso标准8859p1编码 )
2.2.2
多字节编码

   
1)变长多字节编码
    
某些字符用一个字节表示,其它字符用两个或多个字符表示,变长多字节编码常用于对亚洲语言的支持,   例如日语、汉语、印地语等
   
例如:al32utf8(其中al代表all,指适用于所有语言)、 zhs16cgb231280
   
2)定长多字节编码

   
每一个字符都使用固定长度字节的编码方案,目前oracle唯一支持的定长多字节编码是af16utf16,也是仅用于国家字符集
2.2.3 unicode
编码
    unicode
是一个涵盖了目前全世界使用的所有已知字符的单一编码方案,也就是说unicode为每一个字符提供唯一的编码。utf-16unicode16位编码方式,是一种定长多字节编码,用2个字节表示一个unicode字符,af16utf16utf-16编码字符集。
    utf-8
unicode8位编码方式,是一种变长多字节编码,这种编码可以用123个字节表示一个unicode字符,al32utf8utf8utfeutf-8编码字符集

2.3 字符集超级
    当一种字符集(字符集a)的编码数值包含所有另一种字符集(字符集b)的编码数值,并且两种字符集相同编码数值代表相同的字符时,则字符集a是字符集b的超级,或称字符集b是字符集a的子集。
    oracle8i
oracle9i官方文档资料中备有子集-超级对照表(subset-superset pairs),例如:we8iso8859p1we8mswin1252的子集。由于us7ascii是最早的oracle数据库编码格式,因此有许多字符集是us7ascii的超集,例如we8iso8859p1zhs16cgb231280zhs16gbk都是us7ascii的超集。

2.4 数据库字符集(oracle服务器端字符集)
    数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库时,可以指定字符集(character set)和国家字符集(national character set)
2.4.1
字符集
    (1)
用来存储char, varchar2, clob, long等类型数据
    (2)
用来标示诸如表名、列名以及pl/sql变量等
    (3)
用来存储sqlpl/sql程序单元等
2.4.2
国家字符集:
    (1)
用以存储nchar, nvarchar2, nclob等类型数据
    (2)
国家字符集实质上是为oracle选择的附加字符集,主要作用是为了增强oracle的字符处理能力,因为nchar数据类型可以提供对亚洲使用定长多字节编码的支持,而数据库字符集则不能。国家字符集在oracle9i中进行了重新定义,只能在unicode编码中的af16utf16utf8中选择,默认值是 af16utf16
2.4.3
查询字符集参数

   
可以查询以下数据字典或视图查看字符集设置情况
    nls_database_parameters
props$ v$nls_parameters
   
查询结果中nls_characterset表示字符集,nls_nchar_characterset表示国家字符集

2.4.4
修改数据库字符集
   
按照上文所说,数据库字符集在创建后原则上不能更改。如果需要修改字符集,通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换,或通过alter database character set语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如utf8us7ascii的超集,修改数据库字符集可使用alter database character set utf8

2.5 客户端字符集(nls_lang参数)
2.5.1
客户端字符集含义
   
客户端字符集定义了客户端字符数据的编码方式,任何发自或发往客户端的字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连接的各种应用,例如sqlplus,exp/imp等。客户端字符集是通过设置nls_lang参数来设定的。
2.5.2 nls_lang
参数格式
    nls_lang=_.
    language:
显示oracle消息,校验,日期命名
    territory
:指定默认日期、数字、货币等格式
    client character set
:指定客户端将使用的字符集
   
例如: nls_lang=american_america.us7ascii 
    american
是语言,america是地区,us7ascii是客户端字符集

2.5.3
客户端字符集设置方法
     1)unix
环境
         $nls_lang=“simplified chinese”_china.zhs16gbk
         $export nls_lang
        
编辑oracle用户的profile文件
    2)windows
环境
        
编辑注册表
         regedit.exe---hkey_local_machine---software---oracle—home0
2.5.4 nls
参数查询
    oracle
提供若干nls参数定制数据库和用户机以适应本地格式,例如有nls_language,nls_date_format,nls_calender等,可以通过查询以下数据字典或v$视图查看。
    nls_database_parameters--
显示数据库当前nls参数取值,包括数据库字符集取值
    nls_session_parameters--
显示由nls_lang 设置的参数,或经过alter session 改变后的参数值(不包括由nls_lang 设置的客户端字符集)
    nls_instance_paramete--
显示由参数文件init.ora 定义的参数v$nls_parameters--显示数据库当前nls参数取值
2.5.5
修改nls参数
   
使用下列方法可以修改nls参数
   
1)修改实例启动时使用的初始化参数文件
   
2)修改环境变量 nls_lang
   
3)使用alter session语句,在oracle会话中修改

   
4)使用某些sql函数
    nls
作用优先级别:sql function>alter session>环境变量或注册表>参数文件>数据库默认参数

三.导入/导出与字符集转换

3.1 exp/imp
    export import 是一对读写oracle数据的工具。export oracle 数据库中的数据输出到操作系统文件中, import 把这些文件中的数据读到oracle 数据库中,由于使用exp/imp进行数据迁移时,数据从源数据库到目标数据库的过程中有四个环节涉及到字符集,如果这四个环节的字符集不一致,将会发生字符集转换。

exp
     ____________   _________________  _____________
     |imp导入文件|<-><->
     ------------   -----------------  -------------

imp 
     ____________   _________________  _____________
     |imp导入文件|->|环境变量nls_lang|->|数据库字符集|
     ------------   -----------------  -------------

    四个字符集是
  
1)源数据库字符集
  
2export过程中用户会话字符集(通过nls_lang设定)
  
3import过程中用户会话字符集(通过nls_lang设定)
  
4)目标数据库字符集

3.2导出的转换过程
    export过程中,如果源数据库字符集与export用户会话字符集不一致,会发生字符集转换,并在导出文件的头部几个字节中存储export用户会话字符集的id号。在这个转换过程中可能发生数据的丢失。
:如果源数据库使用zhs16gbk,而export用户会话字符集使用us7ascii,由于zhs16gbk16位字符集,us7ascii7位字符集,这个转换过程中,中文字符在us7ascii中不能够找到对等的字符,所以所有中文字符都会丢失而变成“?? ”形式,这样转换后生成的dmp文件已经发生了数据丢失。
因此如果想正确导出源数据库数据,则export过程中用户会话字符集应等于源数据库字符集或是源数据库字符集的超集

3.3导入的转换过程
   
1)确定导出数据库字符集环境
   
通过读取导出文件头,可以获得导出文件的字符集设置
   
2)确定导入session的字符集,即导入session使用的nls_lang环境变量
   
3imp读取导出文件
   
读取导出文件字符集id,和导入进程的nls_lang进行比较
   
4)如果导出文件字符集和导入session字符集相同,那么在这一步骤内就不需要转换,如果不同,就需要把数据转换为导入session使用的字符集。可以看出,导入数据到数据库过程中发生两次字符集转换
   
第一次:导入文件字符集与导入session使用的字符集之间的转换,如果这个转换过程不能正确完成,import向目标数据库的导入过程也就不能完成。
   
第二次:导入session字符集与数据库字符集之间的转换。
   
然而,oracle8i的这种转换只能在单字节字符集之间进行,oracle8i导入session不支持多字节字符集之间的转换,因此为了避免第一次转换,导入session使用的nls_lang与导出文件字符集相同,第二次转换(通过sql*net)支持任何两种字符集。以上情况在oracle9i中略有不同

四.乱码问题

    oracle在数据存储、迁移过程中经常发生字符乱码问题,归根到底是由于字符集使用不当引起。下面以使用客户端sqlplus向数据库插入数据和导入/导出(exp/imp)过程为例,说明乱码产生的原因。

4.1使用客户端sqlplus向数据库存储数据
   
这个过程存在3个字符集设置
   
1)客户端应用字符集
   
2)客户端nls_lang参数设置
   
3)服务器端数据库字符集(character set)设置
   
客户端应用sqlplus中能够显示什么样的字符取决于客户端操作系统语言环境(客户端应用字符集),但在应用中录入这些字符后,这些字符能否在数据库中正常存储,还与另外两个字符集设置紧密相关,其中客户端nls_lang参数主要用于字符数据传输过程中的转换判断。常见的乱码大致有两种情形:
   
1)汉字变成问号
当从字符集a 转换成字符集b时,如果转换字符之间不存在对应关系,nls_lang使用替代字符替代无法映射的字符
   
2)汉字变成未知字符(虽然有些是汉字,但与原字符含义不同)
转换存在对应关系,但字符集a 中的字符编码与字符集b 中的字符编码代表不同含义

4.2发生乱码原因  
    
乱码产生是由于几个字符集之间转换不匹配造成,分以下几种情况:

   
(注:字符集之间如果不存在子集、超集对应关系时的情况不予考虑,因为这种情况下字符集之间转换必产生乱码)    
    1
)服务器端数据库字符集与客户端应用字符集相同,与客户端nls_lang参数设置不同

   
如果客户端nls_lang字符集是其它两种字符集的子集,转换过程将出现乱码。
   
解决方法:将三种字符集设置成同一字符集,或nls_lang字符集是其它两种字符集的超集
    2
)服务器端数据库字符集与客户端nls_lang参数设置相同,与客户端应用字符集不同
   
如果客户端应用字符集是其它两种字符集的超集时,转换过程将出现乱码,但对于单字节编码存储中文问题,可参看本文第5章节的分析
    3
)客户端应用字符集、客户端nls_lang参数设置、服务器端数据库字符集互不相同
    
此种情况较为复杂,但三种字符集之间只要有不能转换的字符,则必产生乱码

4.3导入/导出过程出现乱码原因
   
这个过程存在4个字符集设置,在3.1章节中已分析
  
1)源数据库字符集
  
2exp过程中nls_lang参数
  
3imp过程中nls_lang参数
  
4)目标数据库字符集
   
出现乱码原因
    1
)当源数据库字符集不等于exp过程中nls_lang参数,且源数据库字符集是exp过程中nls_lang的子集,才能保证导出文件正确,其他情况则导出文件字符乱码
    2
exp过程中nls_lang字符集不等于imp过程中nls_lang字符集,且exp过程中nls_lang字符集是imp过程中nls_lang字符集的子级, 才能保证第一次转换正常,否则第一次转换中出现乱码。
    3
)如果第一次转换正常,imp过程中nls_lang字符集是目标数据库字符集的子集或相同,才能保证第二次转换正常,否则则第二次转换中出现乱码

五.单字节编码存储中文问题

    由于历史的原因,早期的oracle没有中文字符集(如oracle6oracle7oracle7.1,但有的用户从那时起就使用数据库了,并用us7ascii字符集存储了中文,或是有的用户在创建数据库时,不考虑清楚,随意选择一个默认的字符集,如we8iso8859p1us7ascii,而这两个字符集都没有汉字编码,虽然有些时候选用这种字符集好象也能正常使用,但用这种字符集存储汉字信息从原则上说就是错误的,它会给数据库的使用与维护带来一系列的麻烦。
   
正常情况下,要将汉字存入数据库,数据库字符集必须支持中文,而将数据库字符集设置为us7ascii等单字节字符集是不合适的。us7ascii字符集只定义了128个符号,并不支持汉字。另外,如果在sql*plus中能够输入中文,操作系统缺省应该是支持中文的,但如果在nls_lang中的字符集设置为us7ascii,显然也是不正确的,它没有反映客户端的实际情况。但在实际应用中汉字显示却是正确的,这主要是因为oracle检查数据库与客户端的字符集设置是同样的,那么数据在客户与数据库之间的存取过程中将不发生任何转换,但是这实际上导致了数据库标识的字符集与实际存入的内容是不相符的。而在select的过程中,oracle同样检查发现数据库与客户端的字符集设置是相同的,所以它也将存入的内容原封不动地传送到客户端,而客户端操作系统识别出这是汉字编码所以能够正确显示。
   
在这个例子中,数据库与客户端都没有设置成中文字符集,但却能正常显示中文,从应用的角度看好象没问题。然而这里面却存在着极大的隐患,比如在应用lengthsubstr等字符串函数时,就可能得到意外的结果。
   
对于早期使用us7ascii字符集数据库的数据迁移到oracle8i/9i中(使用zhs16gbk),由于原始数据已经按照us7ascii格式存储,对于这种情况,可以通过使用oracle8i的导出工具,设置导出字符集为us7ascii,导出后使用ultraedit等工具打开dmp文件,修改第二、三字符,修改 0001 0354,这样就可以将us7ascii字符集的数据正确导入到zhs16gbk的数据库中。

六.结束语

    为了避免在数据库迁移过程中由于字符集不同导致的数据损失,oracle提供了字符集扫描工具(character set scanner),通过这个工具我们可以测试在数据迁移过程中由于字符集转换可能带来的问题,然后根据测试结果,确定数据迁移过程中最佳字符集凯发天生赢家一触即发官网的解决方案。

 

芦苇 2007-09-21 17:30
]]>
db2使用经验备忘http://www.blogjava.net/i369/articles/132086.html芦苇芦苇tue, 24 jul 2007 08:48:00 gmthttp://www.blogjava.net/i369/articles/132086.htmlhttp://www.blogjava.net/i369/comments/132086.htmlhttp://www.blogjava.net/i369/articles/132086.html#feedback0http://www.blogjava.net/i369/comments/commentrss/132086.htmlhttp://www.blogjava.net/i369/services/trackbacks/132086.html  2.控制中心中无法增删改数据,只能编写sql语句来实现而quest提供的工具虽然能增加数据,但居然无法用复制、粘贴和tab键,必须逐个输入,然后用点击切换现存数据看来可以在单元格中编辑修改,但实际却无法commit,呵呵,还是老老实实写ute语句,至于删除数据,更是非写delete语句不可。不过可以用pb以单元格方式编辑数据,相应的一个缺点是编辑数据的按钮和删除表的按钮太近,万一点错了删除表的按钮,pb可是不作提示就把表给删了的,faint

  3.db2的视图里不能直接用order by语句,必须这样写 select × from(select a,b,c from table1 order by a)as tab

  这种写法的前提是你已经打过补丁了

  4.过程的问题:

  db2提供ltrim函数和rtrim函数,但偏偏不提供trim函数,如果你希望去除字符两端的空格,对不起,必须用ltrim(rtrim()) 的方式调用insert 语句里面居然不能用表达式赋值,必须把值先赋给一个变量调用其他存储过程时竟然不能用常量做参数,必须把这个常量的值赋给一个变量,再以这个变量为参数

  select * from table fetch first n rows only 语句居然在存储过程里不可用

  5.存储过程里可以使用动态sql,但函数里却不可以使用,kao

  6. 遇到commit或rollback时自动关闭游标,所以需要慎重使用单独提交。

  proc builder老是在调试中不足,屏幕花掉。而如果断点调试时暂停不进行下去的时间稍微长一点就会提示超时,受不了。

  7.开发中遇到的一个问题

  在使用 日期变量 1 months or 日期变量-1 months 的方式取日期时,比如日期变量值为 2004-02-29时,存储过程里将日期变量 1 months 赋值给另一

  日期变量时会出错。相应sqlstate为01506(db2 ? 01506): 对 date 或timestamp值进行了调整,以校正算术运算得出的无效日期。

  如果要获取的只是下一月份,可采用的替代方法是获取当前日期所在月份的第一天作为基准后 1 months or -1 months

  8.哈哈,今天帮别人弄存储过程的经验@04.08.05

  搞了半天搞不定,一查原来的文档才了,原来tmd该死的db2的存储过程,是转换为c后,进行编译的。因此在数据库服务器上要安装一个c编译器才能完成存储过程的编译。并且需要使用db2set命令,设置db2_sqlroutine_compiler_path指向c编译器的安装路径。如:db2set

  db2_sqlroutine_compiler_path=e:\programfiles\microsoftvisualstudio\vc98\bin\vcvars32.bat

  9.对变量的赋值不能用select ..into ..方式而要用set v=(select ..)的方式,代码示例如下。

drop function sxfm.isordersubmitdate;
create function sxfm.isordersubmitdate(in_row_id decimal(16,0))
  returns date
  language sql
begin atomic
declare v_submit_date date;
declare v_sell_id decimal(16, 0);
declare v_buy_id decimal(16, 0);

set v_sell_id = (select coalesce(receive_id,-1) from is_order where row_id=in_row_id);
set v_buy_id = (select coalesce(pay_id,-1) from is_order where row_id=in_row_id);
set v_submit_date = (select date(max(a.submit_date)) from am_audit_queue a,sm_user b,sm_user c
where a.table_code='is_order' and a.table_row_id=in_row_id
and a.audit_emp_id=c.row_id and c.branch_id=v_buy_id   --审核方为付款方
and a.submit_emp_id=b.row_id and b.branch_id=v_sell_id); --提交方为收款方

return v_submit_date;
end;
#sync 10;

  10.db2的游标打开后遇到commit和rollback默认是会关闭的。保持游标打开的方法是在定义游标时加上with hold选项

  11.f:导出某张表的数据,且该表包含long varchar型数据,该如何操作q:export:db2 cont to [dbname] user [user] using [password]db2move [dbname] export -tn [tablename] -u [user] -p[password] (单表)db2move [dbname] export -tn [tablename1,tablename2,...] -u [user] -p [password] (多表)import:db2move [dbname] import

 

=============================================================================

db2上机操作指令指南


1. 启动实例(db2inst1):

  db2start

  2. 停止实例(db2inst1):

  db2stop

  3. 列出所有实例(db2inst1)

  db2ilist

  5.列出当前实例:

  db2 get instance

  4. 察看示例配置文件:

  db2 get dbm cfg|more

  5. 更新数据库管理器参数信息:

  db2 ute dbm cfg using para_name para_value

  6. 创建数据库:

  db2 create db test

  7. 察看数据库配置参数信息

  db2 get db cfg for test|more

  8. 更新数据库参数配置信息

  db2 update db cfg for test using para_name para_value

  10.删除数据库:

  db2 drop db test

  11.连接数据库

  db2 cont to test

  11.列出所有表空间的详细信息。

  db2 list tablespaces show detail

  12.列出容器的信息

  db2 list tablespace containers for tbs_id show detail

  13.创建表:

  db2 ceate table tb1(id integer not null,name char(10))

  14.列出所有表

  db2 list tables

  12.插入数据:

  db2 insert into tb1 values(1,’sam’);

  db2 insert into tb2 values(2,’smitty’);

  13.查询数据:

  db2 select * from tb1

  14.数据:

  db2 delete from tb1 where id=1

  15.创建索引:

  db2 create index idx1 on tb1(id);

  16.创建视图:

  db2 create view view1 as select id from tb1

  17.查询视图:

  db2 select * from view1

  18.节点编目

  db2 catalog tcp node node_name remote server_ip server server_port

  19.察看端口号

  db2 get dbm cfg|grep svcename

  20.测试节点的附接

  db2 attach to node_name

  21.察看本地节点

  db2 list node directory

  22.节点反编目

  db2 uncatalog node node_name

  23.数据库编目

  db2 catalog db db_name as db_alias at node node_name

  24.察看数据库的编目

  db2 list db directory

  25.连接数据库

  db2 connect to db_alias user user_name using user_password

  26.数据库反编目

  db2 uncatalog db db_alias

  27.导出数据

  db2 export to myfile of ixf messages msg select * from tb1

  28.导入数据

  db2 import from myfile of ixf messages msg replace into tb1

  29.导出数据库的所有表数据

  db2move test export

  30.生成数据库的定义

  db2look -d db_alias -a -e -m -l -x -f -o db2look.sql

  31.创建数据库

  db2 create db test1

  32.生成定义

  db2 -tvf db2look.sql

  33.导入数据库所有的数据

  db2move db_alias import

  34.重组检查

  db2 reorgchk

  35.重组表tb1

  db2 reorg table tb1

  36.更新统计信息

  db2 runstats on table tb1

  37.备份数据库test

  db2 backup db test

  38.恢复数据库test

  db2 restore db test



芦苇 2007-07-24 16:48
]]>
在db2中创建第一个触发器http://www.blogjava.net/i369/articles/132069.html芦苇芦苇tue, 24 jul 2007 07:47:00 gmthttp://www.blogjava.net/i369/articles/132069.htmlhttp://www.blogjava.net/i369/comments/132069.htmlhttp://www.blogjava.net/i369/articles/132069.html#feedback2http://www.blogjava.net/i369/comments/commentrss/132069.htmlhttp://www.blogjava.net/i369/services/trackbacks/132069.html

当特定事件在 ibm® ® universal database™ 数据库中发生时,您就可以激活 触发器来执行其他一些操作。在本文中,您将在触发器的世界里遨游,看看如何通过触发器来增强数据库中的业务规则。您还将学习如何使用 udb version 8.1 的控制中心来帮助您创建一个应用于简单业务场景的简单触发器。



当一个指定的 sql 操作(如 delete,insert,或者是 update 操作)作用于某张表时,一个定义了一组操作的触发器就可以被激活。触发器并不像参照完整性约束和检查约束那样,我们甚至可以使用对其他表来进行更新。



将一项技术应用于真实世界的一个场景总是有益的。出于教学的目的,让我们在一个银行相关环境中研究触发器,在该模拟环境中,我们仅仅建立了一张表。再次强调,这是被简化了的!我们将要做的是,运用触发器来促进银行提供的透支保护。例如,一个银行客户有一个支票帐户(checking account)和一个储蓄帐户(saving account)。当从支票帐户中取款的金额超过了该帐户的余额时,就会发生一次自动的转帐(叫做透支保护),即自动从客户的储蓄帐户转帐过来。当然,这必须符合一定的条件,即储蓄帐户中必须有足够多的钱来补偿透支的金额。



像上面所提及的,我们的银行仅仅包含一张表。在这张表中,我们将存入客户的支票帐户和储蓄帐户的余额等信息。每个客户通过其社会保险号码来标识。下面是对该表的描述:

表 1. 对 accttable 的描述

column name column type nullable?
ssn* varchar(11) no
lastname varchar(30) no
firstname varchar(30) no
savingbalance decimal (precision: 7, scale: 2) no
checkingbalance decimal (precision: 7, scale: 2) no
* 表示主键

请使用 命令行处理器为上面的表创建一个数据库。将数据库命名为 bnkdb。

db2 => create database bnkdb

接下来,连接到该数据库。我假设您已经在您的机器上有了一个用户名为 db2admin 密码为 db2admin 的帐号。

db2 => connect to bnkdb user db2admin using db2admin

现在,创建 accttable 表:

db2 => create table accttable(ssn varchar(30) not null primary key,
            lastname varchar(30) not null, firstname varchar(30) not null,
            savingbalance decimal(7,2) not null, checkingbalance decimal(7,2) not null)
            

现在向所创建的表中加入两条记录:

db2 => insert into accttable values
            ('111-11-1111','bhogal','kulvir',1500.00,1000)
            
db2 => insert into accttable values
            ('222-22-2222','guy','someother',2000.00,4000)
            

触发器可以在对表的一次 insert、 delete 或者 update 操作 之前之后启动。在我们的例子中,您将创建一个在对accttable 表执行 update 操作之前启动的触发器。在触发器术语中,insert、 delete 或者 update 这些使得触发器启动的事件被称作 触发事件。触发器的启动是在触发事件之前还是之后则称为触发器的 激活时间



打开 control center 开始创建触发器,展开您创建的数据库(即 bnkdb),鼠标右键点击 triggers 选项并且选择 create.....



create trigger 屏幕中,可以指定触发器所在的模式。请选择 admin 模式。记住,触发器是与表相关的,所以我们需要选择相关表的模式。然后请再次选择 admin 模式:



在同一个屏幕中, 需要指定一个触发器的名字。将触发器命名为 overdraft。而且,需要指定与该触发器相关的表的名字。这里选择您创建的 accttable



time to trigger action区域中,选择 before



operation that causes the trigger to be executed区域中选择 update of columns 操作并且指定被操作列为 checkingbalance



点击 triggered action标签页来创建该触发器:





udb 能够跟踪在启动触发器的那条语句之前和之后的一行的状态。请在 correlation name for the old rows 一栏中填入 oldrow,correlation name for the new rows 一栏中填入 newrow



注意,您也许无法指定其中的一个 correlation name,因为它依赖于引起触发器启动的特定操作和激活时间的组合。例如,假设您的触发器选择的 time to trigger actionbefore,触发事件是 delete 语句。在这种情况下,我们就无法指定一个 "correlation name for the new rows"。为什么呢?因为在执行了一个删除操作以后,新行是不存在的。

因为您创建的触发器是在 update 之前被激活,所以不能编辑 temporary table for the old rowstemporary table for the new rows选项。

您将注意到,在这种情况下(一个在 update 之前被激活的触发器),您只能指定触发器针对 而不是针对每个 语句触发。



引起触发事件的语句可能会同时影响数据库中的多行。"for each row" 选项意味着触发器将在每一行被修改时激活。另一方面,"for each statement" 选项("before" 型触发器是不允许的)则意味着触发器定义的操作只在调用一次 sql 语句后执行一次。

可以点击 show sql按钮来看看底层的 sql 语句到目前为止是什么样子:





现在该创建触发动作了。我们的业务规则是支票帐户的余额必须低于 0 才能激活该触发器。也就是说,我们需要指定 search-condition 为 newrow.checkingbalance<0 。我们之所以指定 newrow.checkingbalance 是因为需要分析在 update 操作之后支票帐户的余额将会是多少。



现在我们将要在 triggered action 文本区域中替换 triggered-sql-statement (参见下面)。



用来替换的代码如下:

declare overage decimal (7,2);
            set overage = (newrow.checkingbalance*-1);
            if overage>oldrow.savingbalance then signal sqlstate '70001'
            ('overdraft protection unsuccessful');
            else set newrow.savingbalance =
            oldrow.savingbalance-overage, newrow.checkingbalance = 0;
            end if;
            

让我们一句一句地仔细研究一下这段代码。在触发器主体中,可以声明将要在主体中使用的变量。我们使用下面这行代码来声明变量: decimal(7,2)declare overage decimal (7,2) ; 这样就定义了一个类型为 decimal(7,2) 名为 overage 的变量。

下一步我们将 overage 变量的值设置为 (newrow.checkingbalance*-1) ;

我们将使用该算式计算出我们想要从支票帐户取出的超额(overage)的数目。指定 newrow.checkingbalance 是因为我们需要分析支票帐户的余额在 update 操作发生后是多少。

set overage = (newrow.checkingbalance*-1);



如果违反了您在触发器中定义的业务规则,就可以使用 signal 语句来抛出一个错误条件信号。在我们的例子中,不允许有人拥有的支票帐户余额为负数。如果有人想要将支票帐户的余额列更新为一个负数,我们就可以试着看看在储蓄帐户中是否有足够多的钱来补偿这个负数。如果没有,那么就可以发出一条 sql 状态为 '70001' 的信息 "'overdraft protection unsuccessful"。

认识到包含 signal 语句的效果是很重要的。signal 语句回滚由触发语句(也就是我们的 update 语句)尝试的更改。signal 语句也将回滚在触发器内发生的更改。此外,假设我们是使用 java™ 应用程序来与数据库进行交互的,并且试图执行一次会触发我们的触发器并违反业务规则的 update 操作。java 应用程序将接受我们所指定的 sqlstate 以及值为 -438 的 sqlcode。在这行中我们使用 signal sqlstate 属性:

if overage>oldrow.savingbalance then signal sqlstate '70001'
            ('overdraft protection unsuccessful');
            

该行说明,如果我们的 overage 比储蓄帐户的余额数目还要大,那么就需要抛出一个危险信号。



如果储蓄帐户的余额数目足够补偿超出的数目,这时就会发生转帐。如果满足这种条件,我们将对新行作两处修改:

  1. 修改 "new row" 的 savingbalance 列,将其减去 overage 以促成透支转帐。
  2. 将支票帐户的余额设置为 0。我们使用下面的代码来完成:

            else set newrow.savingbalance = oldrow.savingbalance-overage,
            newrow.checkingbalance = 0; end if;
            



可以再次通过 show sql按钮来看看最后的结果:



在点击 close之后,您将看到 overdraft 触发器已经创建好了:





可以通过一个 update 语句来进行测试。打开命令行编写下面的语句:

db2=> update accttable set checkingbalance = -500 where ssn='111-11-1111'
            

根据我们创建的业务逻辑,这个 update 操作将启动该触发器,由于支票帐户透支,该触发器将从 savingbalance 列取出 500.00 到支票帐户。因此,ssn 为 111-11-1111 的帐户的 checkingbalance 会变成 0.00 而 savingbalance 将变成 1000.00(原来的余额 1500 - 透支的 500)。下面的查询验证了该结果:





您已经在一个假想的业务场景中创建了一个 触发器。触发器是 数据库的一个非常强大的特性,您可以使用它将业务逻辑分化到关系数据库这边。如果考虑到有多个应用程序都将与同一个数据库进行交互,您就会发现这种分化是非常强大的。在一个大型企业中,您可能多次遇到过这样的情况,即不知道要创建的是怎样一个将与数据库交互的应用程序。与其只是希望这些应用程序遵守被认为是您的组织机构的戒律的业务规则,还不如使用触发器作为您工具箱中的一种工具,以确保现在和将来与数据库进行交互的所有的应用程序强制遵守这些业务规则。一个触发器只能关联一个表,而不能关联一个视图。您也许可以考虑使用 instead of 触发器来与视图交互。




芦苇 2007-07-24 15:47
]]>
用java实现ldap的访问http://www.blogjava.net/i369/articles/130019.html芦苇芦苇fri, 13 jul 2007 03:00:00 gmthttp://www.blogjava.net/i369/articles/130019.htmlhttp://www.blogjava.net/i369/comments/130019.htmlhttp://www.blogjava.net/i369/articles/130019.html#feedback0http://www.blogjava.net/i369/comments/commentrss/130019.htmlhttp://www.blogjava.net/i369/services/trackbacks/130019.html用java实现ldap的访问(一)
关键字:   用java实现ldap的访问(一)    
 ldap现在用的越来越多,所谓ldap既lightweight directory access protocol。关于它的一些基本知识,我在这里就不做系统的介绍了,网上有很多的资料。我主要说一下在java的语言环境中,怎样来操作ldap。
    在这里,我推荐两个工具:ldaptemplate和jldap。
    网上的资料比较少,而且不少都是e文的,可能英语不太好的朋友,就很难入门了。在这我把我的经验总结一下,和大家分享。
    ldaptemplate是基于spring1.2.7来开发的,其用法和spring的jdbctemplate差不多。最初,我是用这个开源的框架来对ldap进行操作的,但是后来由于开发工具的转变,由eclipse转到了rad上,而rad所用的jdk却不支持spring1.2.7(看来网上的谣传没错,ibm总在某个阴暗的角落在和sun作对),没办法,只好另辟蹊径。后来发现了jldap,经过一番研究,发现它用起来并不比ldaptemplate复杂,但在对象持久化方面需要自己去做,而ldaptemplate通过attributemappers就可以把查询到的结果转换成pojo了。

用java实现ldap的访问(二)
关键字:   用java实现ldap的访问(二)    
 下面来具体的说一下怎么用jldap。首先要去下载一下jldap,具体下载的地址可以上网去搜。下载下来以后,lib里面的是开发所要用到的包,doc里面是帮助文档api和示例程序。
    先说说怎么查询,其实查询非常的简单,如果用过jdbc连数据库的话,那么连ldap相比起来更加的简单。
    首先建立一个ldapconnection对象。这个对象也可以通过连接池poolmanager来获得。ldapconnection con = new ldapconnection();然后运行connect方法和bind方法。连接上ldap以后,就可以通过search方法来查找数据了。示例程序如下:
java 代码
ldapconnection lc = new ldapconnection();   
       try {   
           lc.connect("6.1.19.154",389);   
           lc.bind(ldapconnection.ldap_v3,"cn=xxx","xxxxxx");   
           ldapsearchresults rs = lc.search("dc=excel,dc=com,dc=cn",ldapconnection.scope_sub,"objectclass=*",null,false);   
           int count = 0;   
           while(rs.hasmore()){   
               ldapentry entry = rs.next();   
               system.out.println(entry.getdn());   
               count ;   
           }   
           system.out.println("共有" count "条记录。");   
       } catch (ldapexception e) {   
             
           system.err.print("连接异常!   ");   
           e.printstacktrace();   
       }  
 

10:33  |   永久链接  |   浏览 (1717)  |   评论 (5)  |    收藏  |   ldap  |   进入论坛  |    

永久链接
 

评论    共 5 条  发表评论 

dustbin     2007-03-30 16:39
这样的程序会导致ldap服务器死机地,需要关闭ldap连接
 

hejrcc     2007-06-14 21:05
呵呵, 就是。。。
 

hejrcc     2007-06-14 21:10
看不出用jldap有什么优势, 我也刚刚开始学。
我写了个测试例子,请指点:


代码
public void testldap() {  
    try {  
        dircontext context = getcontext();  
        addentry(context, "uid=oracle,ou=people,dc=mycompany,dc=com");  
        printentry(context, "uid=oracle,ou=people,dc=mycompany,dc=com");  
        context.close();  
    } catch (authenticationexception e) {  
        e.printstacktrace();  
    } catch (namingexception e) {  
        e.printstacktrace();  
    }  
}  
 
public dircontext getcontext() throws namingexception {  
    hashtable env = new hashtable();  
    env.put(context.security_principal, "cn=manager,dc=mycompany,dc=com");  
    env.put(context.security_credentials, "secret");  
    env.put(context.security_authentication, "simple"); //"none", "simple", "strong"  
 
    dircontext initial = new initialdircontext(env);  
    dircontext context = (dircontext) initial.lookup("");  
    return context;  
}  
 
public void addentry(dircontext context, string dn) throws namingexception {  
    attributes attrs = new basicattributes();  
    attrs.put("uid", "oracle");  
    attrs.put("sn", "lee");  
    attrs.put("cn", "amy lee");  
    attrs.put("telephonenumber", " 1 408 555 0033");  
    attrs.put("userpassword", "redqueen".getbytes());  
    //the following attribute has two values  
    attribute objclass = new basicattribute("objectclass");  
    objclass.add("uidobject");  
    objclass.add("person");  
    attrs.put(objclass);  
 
    context.createsubcontext(dn, attrs);  

 

hejrcc     2007-06-14 21:13
看见还有一种写法用来获取 dircontext, 下面的写法指定了 initial_context_factory属性,我想知道我前面一种写法里面, env.put(context.initial_context_factory, ?);
这个initial_context_factory 我没有设置, 不知道默认是什么?


代码
hashtable env = new hashtable();  
env.put(context.initial_context_factory, "com.sun.jndi.ldap.ldapctxfactory");  
env.put(context.provider_url, "");  
env.put(context.security_principal, "cn=manager,dc=mycompany,dc=com");  
env.put(context.security_credentials, "secret");  
//env.put(context.security_authentication, "simple"); //"none", "simple", "strong"           
dircontext context = new initialdircontext(env); 
 

用java实现ldap的访问(三)
关键字:   用java实现ldap的访问(三)    
  虽然ldap主要是用来进行读操作的,但不可避免的,我们也要向其中添加一些新的数据。用jldap向ldap服务器添加数据的操作也是非常简单的。
   为什么说非常简单呢,因为大体上也就是分三步。第一步,连接ldap服务器。第二步,建立一个要添加的新的实体ldapentry,并添加相应的属性。第三步,通过add方法向ldap中添加实体。
   首先说连接服务器。还是非常简单的三步:
java 代码
ldapconnection con = new ldapconnection();   
 con.connect("hostname",hostport);   
 con.bind("version","dn","password");  

连接后,可以建实体了,也就相当与为数据库添加一条新的记录。这里用到了几个类:ldapentry、ldapattribute和ldapattributeset。首先建立一个ldapattributeset,然后建立各种的ldapattribute,把他们add到ldapattributeset中。然后建立一个ldapentry。其构造函数有两个参数,一个是这个ldapentry的dn,一个是他的属性集合,也就是ldapattributeset。
   最后,调用ldapconnection实例化对象的add方法,把实体添加到服务器中。然后别忘了断开连接喔。整体的示例代码如下:
java 代码
ldapattributeset attributeset = new ldapattributeset();   
       attributeset.add(new ldapattribute("objectclass", new string(   
               "inetorgperson")));   
       attributeset.add(new ldapattribute("cn", new string[] { "李",   
               "jim smith", "jimmy smith" }));   
       attributeset.add(new ldapattribute("givenname", new string[] { "测试",   
               "jim", "jimmy" }));   
       attributeset.add(new ldapattribute("sn", new string("smith")));   
       attributeset.add(new ldapattribute("telephonenumber", new string(   
               "1 801 555 1212")));   
       attributeset.add(new ldapattribute("mail",   
               new string("")));   
       attributeset.add(new ldapattribute("userpassword", new string(   
               "newpassword")));   
       ldapentry entry = new ldapentry("cn=李,cn=lizl,dc=excel,dc=com,dc=cn",   
               attributeset);   
       ldapconnection con = new ldapconnection();   
       con.connect("6.1.19.154", 389);   
       con.bind(ldapconnection.ldap_v3, "cn=xxx", "xxxxxx");   
       con.add(entry);   
       system.out.println("成功的添加了一条记录!");   
       con.disconnect();  
 

10:27  |   永久链接  |   浏览 (1217)  |   评论 (3)  |    收藏  |   ldap  |   进入论坛  |    

永久链接
 

评论    共 3 条  发表评论 

hejrcc     2007-06-14 21:20
我觉得楼主的代码很不好看啊,不要这么短就换行嘛。。。
还有, indentation size = 4 就好了, 干嘛搞成8个字符这么宽啊,你这个代码, 第2行好像不用空字符吧?


代码
ldapattributeset attributeset = new ldapattributeset();  
attributeset.add(new ldapattribute("objectclass", new string("inetorgperson")));  
attributeset.add(new ldapattribute("cn", new string[] { "李", "jim smith", "jimmy smith" }));  
attributeset.add(new ldapattribute("givenname", new string[] { "测试", "jim", "jimmy" }));  
attributeset.add(new ldapattribute("sn", new string("smith")));  
attributeset.add(new ldapattribute("telephonenumber", new string("1 801 555 1212")));  
attributeset.add(new ldapattribute("mail", new string("")));  
attributeset.add(new ldapattribute("userpassword", new string("newpassword")));  
ldapentry entry = new ldapentry("cn=李,cn=lizl,dc=excel,dc=com,dc=cn", attributeset);  
ldapconnection con = new ldapconnection();  
con.connect("6.1.19.154", 389);  
con.bind(ldapconnection.ldap_v3, "cn=xxx", "xxxxxx");  
con.add(entry);  
system.out.println("成功的添加了一条记录!");  
con.disconnect(); 
 

用java实现ldap的访问(四)
关键字:   用java实现ldap的访问(四)    
这里来说一说怎么从ldap中删除一个实体。
首先,连接ldap服务器,然后通过dn来删除一个实体。
示例代码如下:
java 代码
ldapconnection con = new ldapconnection();   
con.connect("6.1.19.154",389);   
con.bind(ldapconnection.ldap_v3,"cn=xxxx","xxxxxx");   
con.delete("cn=jsmith,dc=excel,dc=com,dc=cn");   
system.out.println("成功删除一条记录!");   

itds的infocenter的地址
关键字:   itds的infocenter的地址    
itds的infocenter的地址:

 
可以通过itds的web管理工具对ldap进行管理,包括条目管理和objectclass以及
attributes的管理。
启动itds的web控制台的方法是打开cmd,
在d:\program files\ibm\ldap\appsrv\bin文件夹下面(并不一定是这个路径,看安装时的位置,但\ibm\ldap\appsrv\bin一般情况下不会变。)
输入startserver server1。
 
访问web控制台的url是:

ldap 的 schema 中 的 objectclass 和 attributes 详解
关键字:   ldap 的 schema 中 的 objectclass 和 attributes 详解    
地址是:



芦苇 2007-07-13 11:00
]]>
分页存储过程http://www.blogjava.net/i369/articles/126570.html芦苇芦苇wed, 27 jun 2007 05:15:00 gmthttp://www.blogjava.net/i369/articles/126570.htmlhttp://www.blogjava.net/i369/comments/126570.htmlhttp://www.blogjava.net/i369/articles/126570.html#feedback0http://www.blogjava.net/i369/comments/commentrss/126570.htmlhttp://www.blogjava.net/i369/services/trackbacks/126570.html@querystr nvarchar(4000), --表名、视图名、查询语句 
@pagesize int=10,   --每页的大小(行数) 
@pagecurrent int=1,   --要显示的页 
@fdshow nvarchar (4000)='', --要显示的字段列表,如果查询结果有标识字段,需要指定此值,且不包含标识字段 
@fdorder nvarchar (1000)='' --排序字段列表 
as 
declare @fdname nvarchar(250) --表中的主键或表、临时表中的标识列名 
 ,@id1 varchar(20),@id2 varchar(20) --开始和结束的记录号 
 ,@obj_id int    --对象id 
--表中有复合主键的处理 
declare @strfd nvarchar(2000) --复合主键列表 
 ,@strjoin nvarchar(4000) --连接字段 
 ,@strwhere nvarchar(2000) --查询条件 
 
 
select @obj_id=object_id(@querystr) 
 ,@fdshow=case isnull(@fdshow,'') when '' then ' *' else ' end 
 ,@fdorder=case isnull(@fdorder,'') when '' then '' else ' order by end 
 ,@querystr=case when @obj_id is not null then ' else ' () a' end 
 
--如果显示第一页,可以直接用top来完成 
if @pagecurrent=1  
begin 
 select @id1=cast(@pagesize as varchar(20)) 
 exec('select top from ) 
 return 
end 
 
--如果是表,则检查表中是否有标识更或主键 
if @obj_id is not null and objectproperty(@obj_id,'istable')=1 
begin 
 select @id1=cast(@pagesize as varchar(20)) 
  ,@id2=cast((@pagecurrent-1)*@pagesize as varchar(20)) 
 
 select @fdname=name from syscolumns where and status=0x80 
 if @@rowcount=0   --如果表中无标识列,则检查表中是否有主键 
 begin 
  if not exists(select 1 from sysobjects where and xtype='pk') 
   goto lbusetemp  --如果表中无主键,则用临时表处理 
 
  select @fdname=name from syscolumns where and colid in( 
   select colid from sysindexkeys where @obj_id=id and indid in( 
    select indid from sysindexes where @obj_id=id and name in( 
     select name from sysobjects where xtype='pk' and  
   ))) 
  if @@rowcount>1  --检查表中的主键是否为复合主键 
  begin 
   select @strfd='',@strjoin='',@strwhere='' 
   select @strfd=@strfd ',[' name ']' 
    ,@strjoin=@strjoin ' and a.[' name ']=b.[' name ']' 
    ,@strwhere=@strwhere ' and b.[' name '] is null' 
    from syscolumns where and colid in( 
    select colid from sysindexkeys where @obj_id=id and indid in( 
     select indid from sysindexes where @obj_id=id and name in( 
      select name from sysobjects where xtype='pk' and  
    ))) 
   select @strfd=substring(@strfd,2,2000) 
    ,@strjoin=substring(@strjoin,5,4000) 
    ,@strwhere=substring(@strwhere,5,4000) 
   goto lbusepk 
  end 
 end 
end 
else 
 goto lbusetemp 
 
/*--使用标识列或主键为单一字段的处理方法--*/ 
lbuseidentity:  
 exec('select top from  
  ' where not in(select top ' 
  from  
  ')' @fdorder 
  ) 
 return 
 
/*--表中有复合主键的处理方法--*/ 
lbusepk:   
 exec('select from(select top a.* from 
  (select top 100 percent * from ) a 
  left join (select top   
  from ) b on  
  where ) a' 
  ) 
 return 
 
/*--用临时表处理的方法--*/ 
lbusetemp:   
select @fdname='[id_' cast(newid() as varchar(40)) ']' 
 ,@id1=cast(@pagesize*(@pagecurrent-1) as varchar(20)) 
 ,@id2=cast(@pagesize*@pagecurrent-1 as varchar(20)) 
 
exec('select  
  into #tb  
 select from #tb where between ' 
  and  
 ) 



芦苇 2007-06-27 13:15
]]>
db2 sql存储过程语法官方权威指南(翻译) http://www.blogjava.net/i369/articles/126569.html芦苇芦苇wed, 27 jun 2007 05:12:00 gmthttp://www.blogjava.net/i369/articles/126569.htmlhttp://www.blogjava.net/i369/comments/126569.htmlhttp://www.blogjava.net/i369/articles/126569.html#feedback0http://www.blogjava.net/i369/comments/commentrss/126569.htmlhttp://www.blogjava.net/i369/services/trackbacks/126569.html创建sql存储过程(create procedure (sql) statement )

语法格式如下:

>>-create procedure--procedure-name----------------------------->
>-- ---------------------------------------------------- --*---->
   '-(-- ------------------------------------------ --)-'
        | .-,------------------------------------. |
        | v .-in----.                            | |
        '--- ------- --parameter-name--data-type- -'
            -out---
            '-inout-'

>-- ------------------------- --*------------------------------->
   '-specific--specific-name-'

   .-dynamic result sets 0--------.     .-modifies sql data-.
>-- ------------------------------ --*-- ------------------- --->
   '-dynamic result sets--integer-'     -contains sql------
                                        '-reads sql data----'
      .-not deterministic-.     .-called on null input-.
>--*-- ------------------- --*-- ---------------------- --*----->
      '-deterministic-----'

   .-inherit special registers-.     .-7 old savepoint level-.
>-- --------------------------- --*-- --------------------- ---->
                                     '-7 new savepoint level-'
      .-language sql-.     .-7 external action----.
>--7 *-- -------------- --*-- -------------------- --*------------>
                           '-7 no external action-'

>-- ------------------------------ --3 *-------------------------->
   '-3 parameter ccsid-- -3 ascii--- -'
                      '-3 unicode-'

>--| sql-procedure-body |--------------------------------------><
sql-procedure-body:
|--sql-procedure-statement--------------------------------------|

语法说明
1、procedure-name: 存储过程的名字,在同一个数据库的同一模式下,不能存在存储过程名相同参数数目相同的存储过程,即使参数的类型不

同也不行。leizhimin 51cto技术博客

2、(in | out | inout parameter-name data-type,...) :传入参数
    in:输入参数
 out:输出参数
 inout:作为输入输出参数
 parameter-name:参数名字,在此存储过程中唯一的标识符。
 data-type:参数类型,可以接收sql类型和创建的表。不支持long varchar, long vargraphic, datalink, reference和用户自定义类型。


3、specific specific-name:唯一的特定名称(别名),可以用存储过程名代替,这个特定名称用于dorp存储过程,或者给存储过程添加注视

  用,但不能调用存储过程。如果不指定,则数据库会自动生成一个yymmddhhmmsshhn时间戳的名字。推荐给出别名。

4、dynamic result sets integer:指定存储过程返回结果的最大数量。存储过程中虽然没有return语句,但是却能返回结果集。

5、contains sql, reads sql data, modifies sql data: 指定存储过程中的sql访问级别
    contains sql: 表示存储过程可以执行中,既不可读取 sql 数据,也不可修改 sql 数据。
    reads sql data: 表示存储过程可以执行中,可读取sql,但不可修改 sql 数据。
    modifies sql data: 表示存储过程可以执行任何 sql 语句。可以对数据库中的数据进行增加、删除和修改。

6、deterministic or not deterministic:表示存储过程是动态或者非动态的。动态的返回的值是不确定的。非动态的存储过程每次执行返回

的值是相同的。

7、called on null input:表示可以调用存储过程而不管任何的输入参数是否为null,并且,任何的out或者inout参数可以返回一个null或者

非空值。检验参数是否为null是在过程中进行的。

8、inherit special registers:表示继承专用寄存器。

9、old savepoint level or new savepoint level:建立存储点。old savepoint level是默认的存储点。

10、language sql:指定程序的主体用的是sql语言。

11、external action or no external action:表示存储过程是否执行一些改变理数据库状态的活动,而不通过数据库管理器管。默认是

external action。如果指定为no external action ,则数据库会确定最最佳优化方案。

12、parameter ccsid:指定所有输出字符串数据的编码,默认为unicode编码数据库为parameter ccsid unicode

,其他的数据库默认为parameter ccsid 3 ascii。

13、sql-procedure-body:存储过程的主体

例子1:产生一个sql存储过程,返回员工的平均薪水. 返回所有员工超过平均薪水的数额,结果集包括name, position, and salary字段(参

考数据库为db2的示例数据库sample)。

   create procedure median_result_set (out mediansalary double)
     result sets 1
     language sql
   begin
     declare v_numrecords int default 1;
     declare v_counter int default 0;
     declare c1 cursor for
       select cast(salary as double)
         from staff
         order by salary;
     declare c2 cursor with return for
       select name, job, cast(salary as integer)
         from staff
         where salary > mediansalary
         order by salary;
     declare exit handler for not found
       set mediansalary = 6666;
     set mediansalary = 0;
     select count(*) into v_numrecords
       from staff;
     open c1;
     while v_counter < (v_numrecords / 2 1)
     do
       fetch c1 into mediansalary;
       set v_counter = v_counter 1;
     end while;
     close c1;
     open c2;
   end

--------------------
 



芦苇 2007-06-27 13:12
]]>
db2 存储过程开发最佳实践 http://www.blogjava.net/i369/articles/126568.html芦苇芦苇wed, 27 jun 2007 05:11:00 gmthttp://www.blogjava.net/i369/articles/126568.htmlhttp://www.blogjava.net/i369/comments/126568.htmlhttp://www.blogjava.net/i369/articles/126568.html#feedback0http://www.blogjava.net/i369/comments/commentrss/126568.htmlhttp://www.blogjava.net/i369/services/trackbacks/126568.html阅读全文

芦苇 2007-06-27 13:11
]]>
db2 远程 q 复制实践http://www.blogjava.net/i369/articles/116670.html芦苇芦苇fri, 11 may 2007 02:06:00 gmthttp://www.blogjava.net/i369/articles/116670.htmlhttp://www.blogjava.net/i369/comments/116670.htmlhttp://www.blogjava.net/i369/articles/116670.html#feedback0http://www.blogjava.net/i369/comments/commentrss/116670.htmlhttp://www.blogjava.net/i369/services/trackbacks/116670.htmlq复制是db2复制技术中较新的一种技术,通过将websphere mq引进到复制体系结构中,可以使得复制更加可靠、稳定和快速。本文将通过一个完整的例子来说明如何搭建基本环境,以及如何进行操作,从而实现远程q复制。

简介

本文将大概讲述sql replication,然后引出q replication的意义。本文档通过位于两台不同主机上的数据库间的单向复制来展现远程q复制的使用。除了说明操作步骤以外,本文档同时也对相关的关键概念,一些常见的错误以及相关的信息做出了相应解释。

在实际操作之前,读者应该具有db2数据库的相关管理操作的基本概念和基础知识,同样也应该对websphere information integrator和websphere mq有相关了解。如果读者原来在一个机器上做过db2复制相关的练习,例如ibm提供的t3练习,将对本文的学习很有帮助。

本文档主要分为三个大部分:第一个部分是配置和编目远程数据库,第二个部分是配置websphere mq的相关对象,第三个部分是通过replication center来建立起最终的复制环境。对于每一个部分,都包括操作步骤,相关问题和解决办法,以及一些相关的提示信息。





回页首


前提条件

1. 平台的选择

考虑到大部分读者可能更容易获得windows操作系统环境,所以,本文档的实现,源数据库和目标数据库是分别在两个windows操作系统上。但是,实际上如果换成其他操作系统平台,如unix/linux,所有的操作步骤将是大同小异。

2. 软件的安装

读者需要安装好db2,websphere mq。依据相关安装文档执行即可。

3. 本文的相关约定

为了便于读者学习和实践本文,下面给出了笔者在实际操作过程中所建立起来的环境的具体信息,读者当然也可以对自己的相关机器和对象指定其他的名称。在本文中,所使用的对象信息即如下所述(主要包括主机的设置,db2的设置,以及websphere mq的设置)。

4. 主机和db2的相关设置信息



注意: 在使用复制功能之前,数据库itarget和sample都应该将日志模式设置为archive logging模式(归档日志模式)。

5. websphere mq的相关配置信息



6. q复制的配置信息



注意: 1. 上面的replication q map name可以由用户自行定义,一般可以按照复制的功能特点来进行命名。

2. 对于本文中所使用到的相关的mq的完整定义,可以在east_queue_define.txt文件和west_queue_define.txt文件中找到。读者也可以使用上述脚本来生成所需要的mq对象。





回页首


操作步骤、出错分析及解决

第一部分 配置远程数据库连接

操作步骤

本文中,sample数据库是源数据库,源表即在这个数据库中。而数据库itarget为目标数据库。而对于要创建的mq对象来说,名字中的east和west也将用来区分两个主机,east相关的mq对象和itarget数据库在同一个主机上,而west相关的mq对象和sample数据库在同一个主机上。所以,数据将是从sample(west)复制到itarget (east),其间通过定义好的相关队列来实现数据的中间传递作用。

在east端(即apply server端,也就是itarget目标数据库端),通过下面的操作步骤来编目位于另外一个主机上的sample源数据库。

1.打开clp,输入下面的命令来实现对远程sample数据库的编目:


db2 catalog tcpip node west remote 9.181.135.61 server 50000
            db2 catalog database sample at node west
            db2 terminate;
            

2.在clp中输入下面的命令来测试从east到west的连接是否有效:


db2 connect to sample user administrator using ***
            db2 terminate;
            

在上述步骤中,可能会遇到一些错误,笔者将其总结在下面的部分,你也可以通过本文后面的参考信息获得更多帮助。这样,一个远程数据库的编目操作就完成了,用户便可以通过clp命令行方式或者db2的控制中心图形界面方式来实现对远程数据库的操作。

对于q复制中的单向复制来说,上述编目步骤即可。如果想实现q复制中的双向复制或者p2p复制,那么需要在另外一端完成类似上述的步骤,操作方式如下。

在west节点(即sample数据库所在的主机)上,执行如下的操作:

1.打开clp,输入下面的命令来实现对远程itarget数据库中的编目:


db2 catalog tcpip node east remote 9.181.135.238 server 50000
            db2 catalog database itarget at node east
            db2 terminate;
            

2.在clp中输入下面的命令来测试从east到west的连接是否有效:


db2 connect to itarget user administrator using xxx
            db2 terminate;
            

步骤注解

在本部分过程中,我们会经常用到如下一些有用的命令,写在这里,仅供参考: (用户可以修改粗体部分以符合自身需要)

1) db2 list node directory
2) db2 list node directory show detail
3) db2 catalog tcpip node wsii remote 9.181.139.155 server 50000
4) db2 catalog database source at node wsii
5) db2 terminate
6) db2 list database directory
7) db2 create database database_name
8) db2 drop database database_name
9) db2sampl -k (该命令用来创建db2缺省的sample数据库,参数k表示建立带有主键的表,如果没有该参数,所有表将没有主键和索引)
10) db2ilist (list instance)
11) db2 uncatalog database database_name
12) db2 uncatalog node node_name

注意: 远程数据库可以被编目,被编目的数据库也可以删除这种编目关系,但是数据库不能在远端被创建和删除。

一些重要的概念:

db2c_db2

在命令"db2 catalog tcpip node wsii remote 9.181.139.155 server 50000"中,其中的参数50000,不仅可以用这种端口的数字形式,也可以用一个叫做db2c_db2的服务名称。

db2c_db2主要实现db2的网络服务功能。db2c_db2和数字端口之间的关系实际上可以在dbm cfg文件中找到。

使用"db2 get dbm cfg"命令并查看如下部分:


tcp/ip service name (svcename) = db2c_db2
            

因为dbm在db2实例级别对相关参数进行设定,所以,上述的svcename即是一个定义tcp/ip服务端口的实例级别的参数,其缺省值为50000。

另外,如果是在类unix系统中,在etc/service目录下,在services文件中包含了当前db2所使用到的相关端口信息,可以通过修改这个文件来进行相关修改和设定。下面即是相关内容的截取。


db2_db2         60000/tcp
            db2_db2_1       60001/tcp
            db2_db2_2       60002/tcp
            db2_db2_end    60003/tcp  // these ports reserved for
            db2 fast communications manager
            db2c_db2	      50000/tcp  // this is the connection port for instance db2
            

codepage:

因为笔者在操作的过程中,曾经试验过一个是中文操作系统,另外一个是英文操作系统的情况。在上述情况下,会发生所谓的codepage不兼容的问题(这个问题在下面的"出错分析及解决"有进一步说明)。codepage就是指db2的语言的版本。一般来说,如果操作系统是中文的话,那么db2自动安装成为中文版本,如果操作系统是英文的话,那么db2自动安装成为英文版本。尽管如果源数据库和目标数据库的codepage不一样,用户仍然可以成功地从源数据库连接到目标数据库(即connect命令仍然可以成功运行),但是如果没有定义恰当的转换表(用来转换两个不同数据库之间的codepage的表),在复制的时候错误将不可避免。为了简单起见,在本操作实践过程中,两个数据库都是使用的同样的codepage。需要提及的是,codepage可以在创建该数据库的时候为其指定。

关于codepage和数据库链接方面的进一步信息,请参考如下网址:

http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0506chong/
http://chinaunix.net/jh/22/16779.html

出错分析及解决

问题1描述:

sql30081n 检测到通信错误。正在使用的通信协议:"tcp/ip"。正在使用的通信api: "sockets"。检测到错误的位置:"9.181.139.155"。检测到错误的通信函数:"connect"。协议特定的错误代码:"10060"、"*"、"*"。 sqlstate=08001

分析:

这个错误的原因通常是网络连接不稳定造成的。

解决:

检查并确保源数据库所在的主机和目标数据库所在的主机之间的网络连接可用,并且端口正确。在很多情况下,网络病毒导致网络不可用是需要首先检查的方面。

问题2描述:

sql0332n 没有从源代码页 "1252" 至目标代码页 "1386" 的转换。原因码为 "1"。

sqlstate=57017

分析:

这个问题主要是由于本地数据库和远程数据库的代码页(codepage)不一致造成的。比如本地数据库是代码页为1386的中文版本,而远程数据库是代码页为1252的英文版本,这样可能会产生一些意外的错误。

解决:

通过如下命令来检查代码页的相关设置:(红色字体可以由用户指定)
db2 get db cfg for clientdb (检查clientdb所使用的代码页)
db2 get db cfg for serverdb (检查serverdb所使用的代码页)
db2set (检查当前数据库系统所使用的代码页)

通过如下命令来改变本地db2数据库系统的代码页:


db2set db2codepage=serverdb codepage (e.g. "1252")
            db2 terminate
            

可以通过如下简单的命令来核对上述修改是否成功:


db2 connect to source user administrator using passw0rd  // source是
            远程数据库服务器
            

如果source数据库和target数据库可兼容,那么该命令可以成功返回。

第二部分 配置mq对象

操作步骤

1. 本文附件提供了一些脚本来创建相关的mq对象,用户可以通过修改或者直接使用它们来创建出必要的mq对象。east_queue_define.txt文件是用来创建qm_east相关的消息对象,west_queue_define.txt文件是用来创建qm_west相关的消息对象。上述两个脚本,里面都定义了queues、channels,以及queue managers等对象。请注意,上述文件定义的对象,实际上是用来做bidirectional的q复制,对于本文的单向复制而言,只需要用到其中的一部分即可。

2. 在server a上,定义名叫qm_east 的mq manager。

如果qm_east已经存在,按照如下步骤删除旧的qm_east:

(1) endmqm qm_east
(2) endmqlsr (停止queue manager 的listener,也可以通过mq services的start/stop 完成。)
(3) dltmqm qm_east

然后通过下面的步骤来创建之:

(1) crtmqm -q qm_east
(2) strmqm
(3) runmqlsr -t tcp -p 1451
(4) runmqsc qm_easteast_queue_define.txt在附件中可以找到。

3. 在server b上,定义名叫qm_west的mq manager。步骤和2类似。
如果qm_west已经存在,按照如下步骤先删除之:
(1) endmqm qm_west
(2) endmqlsr
(3) dltmqm qm_west

然后再创建之:
(1) crtmqm -q qm_west
(2) strmqm
(3) 在mq services的控制面板中,选择qm_west,右键单击,然后选择new->new listener, 然后添加一个listener(tcp,端口1451),并确保该listener运行正常。
(4) runmqsc qm_westeast_queue_define.txt在附件中可以找到。

注意:qm_east和qm_west 的listener端口可以任意指定可用的端口,它们可以相同,也可以不相同。这里,我们将qm_east和qm_west 的端口分别指定为1450和1451,以示区别。

上面讲述了创建相关mq对象的步骤,下文将对如何测试mq对象(如mq channels和queues等)是否正常工作进行详细讲解。

测试wsmq对象的连接性

在定义好wsmq对象之后,用户可以先对其连通性进行测试,以确保后面的步骤可以正确进行。主要可以从如下方面进行测试:

1. 通过mq explorer来检查channels连接的有效性.

(1) 在qm_east所在的主机上,打开mq explorer,启动qm_east,那么在"channels"->"advanced"里面,将可以看见east_to_west和west_to_east两个channel。

(2) 用户可以右键点击east_to_west并选择start启动之,然后可以选择status选项来查看其是否正常运行。

(3) 如果status是"running",表明channel运作正常。

(4) 如果status是"binding",表明channel正在绑定监听端口,稍后将有可能开始处于正常运作状态。这种情况下,稍等片刻并再次检查其状态,如果仍然是处于"binding"的状态,那么停止并重新启动。

(5) 如果status是"retrying",表明当前channel不能正常运作,这个通常是由于网络原因造成的。检查网络状况,例如通过ping程序来检查网络是否有问题,防火墙有时也可能导致mq channel的retrying状态;检查远端的queue manager (这里是指qm_west)是否已经启动,其listener是否运作正常,并且检查ccsid是否一致。如果远端的qm_west没有启动,那么status很有可能就是retrying的状态。所以应该检查qm_west,保证其处于正常状态,然后在qm_east中停止east_to_west 这个channel并重新启动之。这些步骤之后,应该能解决上述问题。

对于west_to_east这个channel,在qm_east,用户可以检查其状态但是不能启动或者停止它,它只能被发送方启动或者停止。用户应该在qm_west端启动或者停止它。

2. 通过clp方式来检查channels的连接性并获取更多相关信息有时候,通过命令行方式可以高效快捷地检查一些相关的信息,这种方式可以脚本化,当我们要检查的channel很多时,或者相关操作重复性比较大时,应该考虑命令行方式来做。另外,命令行方式能够获取更多的出错方面的详细信息。

(1). 在east上运行如下命令:


runmqchl -c east_to_west -m qm_east
            

如果没有错误信息显示,表明该channel成功运行。之后打开另外一个命令行窗口,并输入如下的命令:


runmqchl -c west_to_east -m qm_west
            

如果此时返回相关错误码,那么对其进行分析并根据错误提示去采取相应的解决办法。

(2). 测试本地的queues 在east上,执行如下命令将一个消息放到队列上:


/usr/mqm/samp/bin/amqsput east_restartq qm_east
            sample amqsput0 start
            target queue is east_restartq
            this is a test message to a local queue
            sample amqsput0 end
            

然后通过执行下面的命令来从queue中获取信息。这个时候应该会显示出上面输入的消息文本。


/usr/mqm/samp/bin/amqsget east_restartq qm_east
            sample amqsget0 start
            message 
            no more messages
            sample amqsget0 end
            

在west端,执行如下命令来将一个消息放到队列里面:


/usr/mqm/samp/bin/amqsput west_restartq qm_west
            sample amqsput0 start
            target queue is west_restartq
            this is a test message to a local queue
            sample amqsput0 end
            

同样的,执行如下命令来从queue中获取信息。这个时候应该也会显示出上面输入的相关消息文本。


/usr/mqm/samp/bin/amqsget west_restartq qm_west
            sample amqsget0 start
            message 
            no more messages
            sample amqsget0 end
            

(3). 测试远程的queues 测试从远端的queue上面放入和取出消息。

在east上执行如下命令来将消息放入到west_adminq这个队列中。


/usr/mqm/samp/bin/amqsput west_adminq qm_east
            sample amqsput0 start
            target queue is west_admintq
            this is a test message to a remote queue
            sample amqsput0 end
            

在west中执行如下命令获取来自west_adminq 队列上的消息。


/usr/mqm/samp/bin/amqsget west_adminq qm_west
            sample amqsget0 start
            message 
            no more messages
            sample amqsget0 end
            

步骤注解

remote queues:

remote queues是一个相对的概念,是用来在另外一个queue manager上定义local queue。在本文中,每个queue manager分别定义了两个remote queue。在qm_east上,west_adminq和east_to_west_q被定义成为remote queue。在qm_west上,east_adminq和west_to_east_q被定义成为remote queue。

wsmq objects:

关于mq对象的更多信息,请参考《fast track implementation scenarios》的附录a。该资料在附件中已给出。

出错分析及解决

问题1描述:

c:\documents and settings\administrator>runmqchl -c east_to_west -m qm_east 5724-b41 (c) 凯发天生赢家一触即发官网 copyright ibm corp. 1994, 2002. all rights reserved.
2005-09-25 17:46:56 通道程序已启动。
2005-09-25 17:47:04 amq6047: 不支持转换。
2005-09-25 17:47:04 amq9999: 通道程序异常终止。

分析:

在mq消息手册中查找关于amq6047的相关信息,如下:

amq6047 conversion not supported.
explanation: websphere mq is unable to convert string data tagged in ccsid &1 to data in ccsid &2.
user response: check the websphere mq application programming reference appendix and the appropriate national language support publications to see if the ccsids are supported by your system.

这个错误的原因是由于两个queue manager的ccsid 的设置不兼容造成的。而这种不兼容的最根本原因是由于本地的locale和远程主机的locale不一致造成的(从而websphere mq的安装语言版本不一样)。这点和db2的code page问题很类似。

解决:

(1) 在mq explorer中找到ccsid及相关属性。在笔者的环境中,如果安装的是中文版的mq,那么ccsid的缺省值是1381,而英文版的则相应为437。在这两者之间,它们并没有直接的转换方式来进行兼容性处理。

(2) 由于(1),我们必须在本地对ccsid进行转换。在east(ccsid=1381)端通过如下命令来实现其转换:


strmqm
            runmqsc
            display qmgr       // 检查当前queue manager的ccsid值
            alter qmgr ccsid(437)
            end
            

第三部分 通过replication center图形界面建立远程q复制

操作步骤

这部分主要通过gui图形界面(即replication center)来完成。同时,为了方便起见,其中也会用到clp命令行方式。对于本文的单向复制而言,这里主要通过配置east端来说明相关使用方法。

在开始配置capture和apply之前,首先应该对密码和连接性进行测试。在replication center中,选择manage password and connectivity,然后选择systems,在其中添加两行信息,即本地east和远程west的相关密码和连接信息。

对于远程q replication图形界面方面的基本操作,大体和完全在一个机器上的q replication类似,主要的区别在于对mq相关对象的操作上有所不同。所以下面的操作部分重点在于mq的详细介绍。

1.建立q capture相关的控制表

通过前面的步骤,这里至少可以有两个db2 server可用,一个是server a,一个是server b。可以使用如下命令来获取相关信息:db2 list db directory
具体操作步骤如下:

  • 选择sample作为capture server。
  • 将q capture的schema指定为asn。
  • q manager选择为qm_west,然而admin queue应该为west_adminq并且restart queue为st_restartq。
  • 在完成上述配置后,sample这个capture server应该能够用来进行复制了。

2.建立q apply相关的控制表

  • 选择itarget作为apply server。
  • 将q apply的schema指定为asn。
  • q manager应该为qm_east。

3.建立replication queue maps

  • 在sample节点下,选择"create replication queue maps"。
  • 选择apply server为itarget。
  • 因为前面我们选定了west_adminq作为sample这个capture server的adminq,所以,apply server的admin queue也应该同样指定为west_adminq。同时,应该指定send queue和receive queue为west_to_east_q。
  • 为 queue map指定一个名称。

4.建立复制预订集

  • 从sample节点,选择"create replication subscriptions"。
  • 选择"unidirectional replication"。
  • 选择itarget作为目标服务器,并且使用前面所建立的queue map。
  • 从capture server中选择恰当的源表。
  • 对于目标表等其他方面的设置,使用缺省值。
  • 完成预定集的建立。

5.建立apply所需要的password文件

  • 在目标系统中将当前路径转到apply_path上。
  • 输入命令"asnpwd init"。
  • 输入命令"asnpwd add alias sample id administrator password ***"。这样就会生成一个相应的password文件。

6.启动q capture程序

设定相关参数,启动q capture。

7.启动q apply程序

设定相关参数,启动q apply。

步骤注解

1. 当在replication center中配置password和connectivity的时候,它会要求指定directory ,这应该是db2安装目录下的bin目录所在的路径,如"c:\sqllib\bin"。

2. 当在replication center中配置password和connectivity的时候,远程主机名字应该正确指定。实际上,在这里ip地址也可以和远程主机名字同样被使用。

3. 在设置复制环境的时候,记得将capture server所在的数据库设置为archive logging模式。

4. password文件在如下情况下是必须的:

a. 当q apply需要使用export来导出数据时

b. 当q capture需要连接到多个数据库分区时

c. 当需要建立相应的alert monitor时

d. 当需要运行q analyzer(该程序需要连接到被分析的q capture和q apply)时

e. 当需要用到tdiff工具时

5. 关于dead letter queue,可以参考《fast track implementation scenarios》中的appendix c. dead letter queues in a q replication environment

出错分析及解决

问题1描述:

capture可以正常启动,但是apply不能正常启动,处于presume stopped的状态。receive queue正常运作,subscription处于"inactive"的状态,mq channels正常运作。

分析:

这个问题很有可能是网络原因造成的,例如ip设置错误等等。

解决:

保证网络正常连接,设定正确的ip地址等等。

问题2描述:

在apply日志中,有如下信息:

2005-10-14 12:12:49.578000 error asn7551e "q apply" : "asn" : "br00000" : the q apply program detected a gap in message numbers on receive queue "west_to_east_q", replication queue map "sample_asn_to_itarget_asn". it read message id "51524550434d6ab0000000000000000000000000000003f0", but expected to find message id "51524550434d6ab000000000000000000000000000000001". the q apply program cannot process any messages until if finds the expected message.

分析:

q apply程序检查从q capture程序发送过来的消息,这些消息都具有一个依次递增的号码,递增增幅为1。当q apply发现消息之间的号码不是依次递增时,apply程序将停止处理并且将相关信息写入apply log中。可以通过命令"db2 ? asn7551e"来获取更多信息。下面即是截取的一部分:

用户响应(asn7551e):

在用来在 q capture 和 q apply 程序之间传输消息的所有websphere mq 队列管理器的所有"死信队列"上查找具有期望消息标识的消息。如果恢复消息,则将它放置在接收队列上,并保留websphere mq 消息头信息(尤其是消息标识)。如果不能恢复消息,则遵循下列步骤:

1. 使用 stopq 命令来停止 q apply 程序从接收队列中进行读取。

2. 取消激活此复制队列图的所有 q 预订。

3. 清空发送队列和接收队列。

4. 使用 startq 命令,以便 q apply 程序继续从接收队列中进行读取。

5. 激活此复制队列图的所有 q 预订。

解决:

通过如下步骤,可以解决这个问题:

1. asnqacmd apply_server=itagget apply_schema=asn stoptq=west_to_east_q

2. 在rc中将该q subscriptions设置成为"deactivate"的状态。

3. 通过rc将west_to_east_q清空。

4. asnqacmd apply_server=itarget apply_schema=asn startq=west_to_east_q

5. 再次将q subscriptions设置成为"active"的状态。

对于该错误一个较好的方法就是:在启动q capture或者q apply之前,将qm_east和qm_west 上的admin、restart、和send_receive queueus 清空。

问题3描述:

2005-10-16 15:48:16.171000 error asn0005e capture "asn" : "workerthread". the capture program encountered an error when reading the db2 log. the log sequence number is "0000:0000:0000:0697:a8bd", the sqlcode is "-2650", and the reason code is "pistartlsndb2readlog2".

分析:

这个错误主要可能是由于db2的内部错误引起的。

解决:

完全重新安装db2来解决这个问题。

问题4描述:

2005-10-16-19.40.47.328000 asn0552e "q apply" : "asn" : "br00000sp001" : the program encountered an sql error. the server name is "sample". the sql request is "connect". the table name is "n/a". the sqlcode is "-30082". the sqlstate is "08001". the sqlerrmc is "3password missing". the sqlerrp is "sqlexsmc".

分析:

这个错误主要是由于缺少password文件而导致的。

解决:

安装本文上述相关内容生成password文件即可。





回页首


结束语

本文主要介绍了远程q复制的相关操作,以及一些相关的核心概念。对于操作过程中常见的问题和错误进行了分析并给出了一般的解决方法。






回页首


下载

名字 大小 下载方法
attachment.zip 4kb http


芦苇 2007-05-11 10:06
]]>
db2数据库自动备份脚本http://www.blogjava.net/i369/articles/110347.html芦苇芦苇fri, 13 apr 2007 01:19:00 gmthttp://www.blogjava.net/i369/articles/110347.htmlhttp://www.blogjava.net/i369/comments/110347.htmlhttp://www.blogjava.net/i369/articles/110347.html#feedback0http://www.blogjava.net/i369/comments/commentrss/110347.htmlhttp://www.blogjava.net/i369/services/trackbacks/110347.html主题:db2数据库自动备份脚本
所属分类:db2 数据库管理
----------------------------------------------------------------------

db2数据库自动备份脚本,比如做 一个bat文件。点击自动执行备份到指定的目录。我知道oracle是可以的。不知道db2可以吗?

----------------------------------------------------------------------

两种方式..离线方式和在线方式备份..
离线方式脚本,可以在计划任务里做
db2stop force;
db2start;
db2 connect to 库名 user db2admin using pass
db2 backup db 库名 on 路径
------------
资料很多!
db2离线和在线全备、增量备份及恢复的操作步骤 

1、离线全备份 

1)、首先确保没有用户使用db2: 

$db2 list applications for db sample 

2)、停掉数据库并重新启动,以便断掉所有连接: 

db2stop force   

db2start 

3)、执行备份命令:(使用tsm作为备份的介质) 

db2 backup db sample use tsm 

备份成功,将会返回一个时间戳。 

4)、检查备份成功: 

db2 list history backup all for sample ,可以看到多了这个备份的纪录。 

db2adutl query命令也可以看到返回值。 

5)、备注: 

首先对主节点(catalog表空间在的节点)执行备份命令,再对另外的节点也做这个操作。 

2、 在线备份: 

1)、首先打开一下支持在线备份的数据库配置参数: 

db2 update db cfg for sample using userexit on    启用用户出口 

db2 update db cfg for sample using logretain on    启用归档日志 

db2 update db cfg for sample using trackmod on   启用增量备份功能 

(需要各个node都分别做设置) 

开启这些参数后,数据库处于backup pending状态,要求做数据库的离线全备份。做一下离线全备份,参考上面的命令。 

2)、在线备份命令如下: 

db2 backup db sample online use tsm 

备份成功,返回一个时间戳。 

3)、同样可以用db2adutl 和db2 list history察看备份纪录。 

4)、备注: 

同样,对每个节点都做这个操作。 

3、 在线增量备份 

1)、在开启了必须的三个参数的情况下,做增量备份: 

db2 backup db sample online incremental use tsm 

备份成功,返回一个时间戳。 

2)、同样可以用db2adutl 和db2 list history察看备份纪录。 

3)、还有一种delta的备份: 

db2 backup db sample online incremental delta use tsm 

这两种备份的区别,类似oracle exports的incremental和cumulative方式,db2的incremental对应oracle的cumulative方式,而db2的delta方式则对应oracle的incremental方式。 

4)、备注:同样,对每个节点都做这个操作。 

4、 恢复数据库 

1)、手工drop数据库,模拟灾难恢复的情况,执行如下操作: 

db2 drop db sample 

2)、恢复备份历史纪录(每次backup,不论类型,都会备份历史纪录文件)。这里的时间戳应该是最新的: 

db2 restore db sample history file use tsm taken at 20030102223107 buffer 100 

3)、使用db2的恢复帮助工具: 

db2ckrst -d sample -t 20030101224424 -r database 

命令返回建议的必需的恢复操作命令。 

4)、按照帮助工具的提示,先做版本恢复,恢复命令如下: 

db2 restore db sample incremental use tsm taken at 20030101224424 buffer 100 

同样先做主节点的恢复,再做其他节点的恢复操作。 

5)、这时数据库处于rollforward-pending state的状态,需要做roll forward 操作: 

db2 rollforward db sample to 2003-01-12-13.27.25.000000 on all nodes and stop 

前滚到同一个时间点。这个操作要在主节点来做。 

5、有关说明: 

1)、恢复操作也有online和offline的,区别如同backup的操作。 

2)、按照表空间的备份和恢复类似,加子句tablespace ( tablespace-name 即可。表空间级别的备份/恢复操作要求数据库处于归档日志和启用增量备份模式下。 

3)、恢复的例子中只做了版本恢复。若还有更新的全备份和增量备份的image,可以依次做恢复(注意使用db2ckrst的建议恢复次序和次数)后,再做roll forward. (完)


--------------------------------------------------------

现在我需要一个.bat的命令,可以在windows的任务中可以设置时间表后自动执行,这该怎么做啊?谢谢!

--------------------------------------------------------



芦苇 2007-04-13 09:19
]]>
db2备份与恢复 http://www.blogjava.net/i369/articles/110213.html芦苇芦苇thu, 12 apr 2007 08:49:00 gmthttp://www.blogjava.net/i369/articles/110213.htmlhttp://www.blogjava.net/i369/comments/110213.htmlhttp://www.blogjava.net/i369/articles/110213.html#feedback0http://www.blogjava.net/i369/comments/commentrss/110213.htmlhttp://www.blogjava.net/i369/services/trackbacks/110213.htmldb2 restore db huaxing from c:\temp into huaxinga
因为你现在已经catalog了一个叫huaxing的数据库,可以先uncatalog db huaxing,再db2 restore db huaxing from c:\temp
db2 update db cfg using stmtheap 6000  将数据库有关语句堆的一个参数改大的了


芦苇 2007-04-12 16:49
]]>
sqlstate 消息http://www.blogjava.net/i369/articles/110194.html芦苇芦苇thu, 12 apr 2007 07:57:00 gmthttp://www.blogjava.net/i369/articles/110194.htmlhttp://www.blogjava.net/i369/comments/110194.htmlhttp://www.blogjava.net/i369/articles/110194.html#feedback0http://www.blogjava.net/i369/comments/commentrss/110194.htmlhttp://www.blogjava.net/i369/services/trackbacks/110194.htmlsqlstate 消息
本节列示 sqlstate 及其含义。sqlstate 是按类代码进行分组的;对于子代码,请参阅相应的表。

表 2. sqlstate 类代码 类
代码  
含义 要获得子代码,
参阅...
00 完全成功完成 表 3
01 警告 表 4
02 无数据 表 5
07 动态 sql 错误 表 6
08 连接异常 表 7
09 触发操作异常 表 8
0a 功能部件不受支持 表 9
0d 目标类型规范无效 表 10
0f 无效标记 表 11
0k resignal 语句无效 表 12
0n sql/xml 映射错误 表 13
20 找不到 case 语句的条件 表 15
21 基数违例 表 16
22 数据异常 表 17
23 约束违例 表 18
24 无效的游标状态 表 19
25 无效的事务状态 表 20
26 无效 sql 语句标识 表 21
28 无效权限规范 表 23
2d 无效事务终止 表 24
2e 无效连接名称 表 25
34 无效的游标名称 表 26
36 游标灵敏度异常 表 27
38 外部函数异常 表 28
39 外部函数调用异常 表 29
3b savepoint 无效 表 30
40 事务回滚 表 31
42 语法错误或访问规则违例 表 32
44 with check option 违例 表 33
46 java ddl 表 34
51 无效应用程序状态 表 35
53 无效操作数或不一致的规范 表 36
54 超出 sql 限制,或超出产品限制 表 37
55 对象不处于先决条件状态 表 38
56 其他 sql 或产品错误 表 39
57 资源不可用或操作员干预 表 40
58 系统错误 表 41
5u 实用程序 表 42

类代码 00 完全成功完成
表 3. 类代码 00:完全成功完成 sqlstate 值  
含义
00000 操作执行成功,并且未产生任何类型的警告或异常情况。

类代码 01 警告
表 4. 类代码 01:警告 sqlstate 值  
含义
01002 发生 disconnect 错误。
01003 从列函数的参数消去 null 值。
01004 字符串值在指定给具有较短长度的另一字符串数据类型时被截断。
01005 sqlda 中的条目数不够。
01007 未授予特权。
0100c 从过程返回了一个或多个特殊结果集。
0100d 关闭的游标已在链中的下一个结果集上重新打开。
0100e 生成的过程大于允许的最大结果集数目。只有第一个整数结果集已经返回到调用者。
01503 结果列数比提供的主机变量数大。
01504 update 或 delete 语句不包括 where 子句。
01506 对 date 或 timestamp 值进行了调整,以更正算术运算得出的无效日期。
01509 由于用户虚拟机中的存储器不够,取消游标的分块。
01515 已为主机变量指定了一个空值,因为列的非空值不在主机变量的范围之内。
01516 已忽略不可用的 with grant option。
01517 用替代字符替换不能转换的字符。
01519 已为主机变量指定了一个空值,因为数字值超出范围。
01524 列函数的结果不包括由算术表达式求值得出的空值。
01526 隔离级别已升级。
01527 set 语句引用的专用寄存器在 as 上不存在。
01539 连接成功但只应使用 sbcs 字符。
01543 已忽略重复约束。
01545 未限定列名已解释为相关引用。
01550 索引未创建,因为具有指定描述的索引已经存在。
01560 忽略了一个冗余的 grant。
01562 在数据库配置文件中的新日志路径(newlogpth)无效。
01563 日志文件的当前路径(logpath)无效。日志文件路径被复位为缺省值。
01564 已为主机变量指定了空值,因为发生了被零除的错误。
01586 该语句导致一个或多个表自动置于设置完整性暂挂状态。
01589 语句包含有冗余规范。
01592 在引用 source 函数的 create function 语句中,或:
输入参数的长度、精度或小数位大于源函数相应参数的长度、精度或小数位;或
returns 或 cast from 参数的长度、精度或小数位比源函数的小;或
create function 语句中的 cast from 参数的长度、精度或小数位比 returns 参数的大。
运行时可能发生截断(那时可能会引起错误)。
01594 对于所有信息,sqlda 内的条目数不够多(即,没有足够的描述符返回相异名称)。
01595 该视图已替换现有无效视图。
01596 没有为基于长字符串数据类型的单值类型创建比较函数。
01598 尝试激活活动的事件监视器,或尝试释放不活动的事件监视器。
01599 忽略 rebind 上的绑定选项。
01602 优化级别已降低。
01603 check data 处理过程中发现约束违例,已将其移至异常表。
01604 已经说明了 sql 语句,但是未执行它。
01605 递归公共表表达式可能包含无限循环。
01606 节点或系统数据库目录是空的。
01607 只读事务中节点的时间差超过定义的阈值。
01608 已经替换了不受支持的值。
01609 生成的过程大于允许的最大结果集数目。只有第一个整数结果集已经返回到调用者。
01610 从过程返回了一个或多个特殊结果集。
01611 关闭的游标已在链中的下一个结果集上重新打开。
01614 定位器数小于结果集数。
01616 估计的 cpu 成本超出了资源限制。
01618 重新分发节点组是更改数据库分区所必需的。
01620 union all 的某些基本表可能是同一个表。
01621 检索到的 lob 值可能已更改。
01622 语句成功完成,但在语句完成之后发生了系统错误。
01623 忽略 degree 的值。
01625 模式名在 current path 中出现了多次。
01626 数据库只有一个活动的缓冲池。
01627 datalink 值可能无效,因为该表处理协调暂挂或协调不可能的状态。
01632 并发连接数超出了该产品的定义授权。
01633 可能不能使用具体化查询表来优化查询的处理。
01636 数据库管理器一直未验证非增量数据的完整性。
01637 未启用调试。
01639 联合对象可能需要调用程序具有对数据源对象的必要特权。
01641 datalink 类型属性限制结构化类型的使用。
01642 对于最大的可能 user 缺省值,列不足够长。
01643 对 sql 例程中 sqlstate 或 sqlcode 变量的赋值可能会被覆盖,不会激活任何处理程序。
01645 sql 过程的可执行文件未保存在数据库目录中。
01648 忽略了 compress 列属性,因为对表取消激活了 value compression。
01649 缓冲池操作已经完成,但是直到下一次数据库重新启动才会生效。
01650 索引和表统计信息不一致。
01651 成功激活了事件监视器,但是某些监视信息可能丢失了。
01652 由于语句上下文而忽略了隔离子句。
01653 权限授予给 user。因为权限名称大于 8 字节,所以不考虑组。
01654 未启动缓冲池。
01655 成功创建了事件监视器,但是至少有一个事件监视器目标表已存在。
01657 缓冲池操作在下一次数据库重新启动之后才会生效。
01665 列名或参数名被截断。
01667 可能不能使用视图来优化查询的处理。
01669 由于远程目录与本地目录之间的模式不一致,因此,未彻底更新指定昵称的统计信息。
01670 对新表来说,不存在缺省主表空间。
01671 高速缓存的语句的环境与当前环境不同。将使用当前环境来重新优化指定的语句。
01674 表空间属性对于查询性能不是最佳的。
01675 指定的表空间数超过了需要的表空间数。多余的表空间将被忽略。
01676 忽略了传送操作,因为授权标识已经是数据库对象的所有者。
01677 对于已经定义了插件的服务器忽略了包装器选项。
01678 对用户映射的更改只应用于联合目录表,而不应用于外部用户映射存储库。
01679 无法为指定的授权标识建立可信连接。
01684 不支持指定的语言环境。返回的消息使用的是英语语言环境。
01686 表空间正在从 regular 转换为 large。必须对此表空间中的表的索引进行重组或重建,以便支持大型 rid。
01689 在未连接到数据源的情况下完成了 sql 编译。
0168a 在数据源上找不到源过程的程序包主体,或者它无效。
01h51 “mqseries 应用程序消息传递接口”消息被截断。
01h52 例程的执行已完成,但是执行期间至少遇到了一个错误或警告。提供了更多信息。
01h53 例程遇到了警告。参阅 sqlcode 以获取详细信息。
01hxx 由用户定义的函数或外部过程 call 返回了有效警告 sqlstae。

类代码 02 无数据
表 5. 类代码 02:无数据 sqlstate 值  
含义
02000 发生下述异常之一:
select into 语句或 insert 语句的子查询的结果为空表。
在搜索的 update 或 delete 语句内标识的行数为零。
在 fetch 语句中引用的游标位置处于结果表最后一行之后。
 
02501 游标位置对于当前行的 fetch 无效。
02502 检测到删除或更新孔
02506 遇到了错误,并且已按 return data until 子句指定那样容许它。

类代码 07 动态 sql 错误
表 6. 类代码 07:动态 sql 错误 sqlstate 值  
含义
07001 对于参数标记的数目来说,主机变量的数目不正确。
07002 调用参数列表或控制块无效。
07003 在 execute 语句内标识的语句是一条 select 语句,或未处于已预编译状态。
07004 动态参数需要 using 子句或 into 子句。
07005 游标的语句名标识的是一个不能与游标关联的已预编译语句。
07006 由于其数据类型的缘故不能使用某输入主机变量。

类代码 08 连接异常
表 7. 类代码 08:连接异常 sqlstate 值  
含义
08001 应用程序请求器不能建立连接。
08002 连接已存在。
08003 连接不存在。
08004 应用程序服务器拒绝了建立连接。
08007 事务解析未知。
08502 用 twophase 的 syncpoint 运行的应用程序进程发出的 connect 语句无效,因为无事务管理器可用。
08504 当处理指定的路径重命名配置文件时遇到错误。

类代码 09 触发操作异常
表 8. 类代码 09:触发操作异常 sqlstate 值  
含义
09000 触发 sql 语句失败。

类代码 0a 不支持功能部件
表 9. 类代码 0a:不支持功能部件 sqlstate 值  
含义
0a001 connect 语句无效,因为进程不处于可连接状态。
0a502 未对此数据库实例启用操作。
0a503 由于潜在的数据不一致,不能编译联合插入、更新或删除操作。

类代码 0d 目标类型规范无效
表 10. 类代码 0d:目标类型规范无效 sqlstate 值  
含义
0d000 目标结构化数据类型规范是源结构化数据类型的正确子类型。

类代码 0f 无效标记
表 11. 类代码 of:无效标记 sqlstate 值  
含义
0f001 lob 标记变量当前不表示任何值。

类代码 0k resignal 语句无效
表 12. 类代码 0k:resignal 语句无效 sqlstate 值  
含义
0k000 resignal 语句不在处理程序中。

类代码 0n sql/xml 映射错误
表 13. 类代码 0n:sql/xml 映射错误 sqlstate 值  
含义
0n002 无法将字符映射至有效 xml 字符。

类代码 10 xquery 错误
表 14. 类代码 10:xquery 错误 sqlstate 值  
含义
10000 xquery 错误。
10501 xquery 表达式缺少静态或动态上下文组件的指定。
10502 在 xquery 表达式的序言中遇到了错误。
10503 在 xquery 或 xpath 表达式中定义了重复的名称。
10504 在无效 uri 中指定了 xquery 名称空间声明。
10505 字符、标记或子句在 xquery 表达式中缺少了或者无效。
10506 xquery 表达式引用了一个未定义的名称。
10507 处理 xpath 或 xquery 表达式时遇到了类型错误。
10508 xquery 表达式在已计算的构造函数中包括一个无效的名称表达式。
10509 指定了不受支持的 xquery 语言功能部件。
10510 未指定字符串文字作为强制类型转换表达式操作数或构造函数参数。
10601 在处理 xquery 函数或运算符时遇到了算术错误。
10602 在处理 xquery 函数或运算符时遇到了数据类型转换错误。
10603 在处理 xquery 函数或运算符时遇到了字符处理错误。
10604 未提供文档上下文来处理 xquery 函数。
10605 在处理 xquery 函数或运算符时遇到了日期时间错误。
10606 没有上下文项用来处理 xquery 函数或运算符。
10607 在处理 xquery 函数或运算符时遇到了名称空间错误。
10608 在 xquery 函数或运算符的参数中遇到了错误。
10609 在处理 xquery 函数或运算符时遇到了正则表达式错误。
10610 在处理 xquery 函数或运算符时遇到了类型错误。
10611 在处理 xquery 函数或运算符时遇到了未标识的错误。
10901 xquery 原子值超出了 db2 xquery 数据类型的范围。
10902 xquery 原子值超过了 db2 xquery 运算符或函数的长度限制。
10903 已超过相匹配的 xquery 节点数的内部限制。

类代码 20 找不到 case 语句的条件
表 15. 类代码 20:找不到 case 语句的条件 sqlstate 值  
含义
20000 找不到 case 语句的条件。

类代码 21 基数违例
表 16. 类代码 21:基数违例 sqlstate 值  
含义
21000 select into 的结果是一个多行的结果表,或者,基本谓词的子查询结果为多个值。
21501 对自引用表进行多行 insert 是无效的。
21502 主键的多行 update 是无效的。
21504 从删除规则为 restrict 或 set null 的自引用表进行多行 delete 是无效的。
21505 行函数返回的内容不能超过一行。 
21506 表的同一行不能是多个更新、删除或插入操作的目标。

类代码 22 数据异常
表 17. 类代码22:数据异常 sqlstate 值  
含义
22001 字符数据,发生右截断;例如,更新或插入值对于列来说太长(字符串),或者日期时间值由于太小而不能赋给主机变量。
22002 检测到空值或缺少指示符参数;例如,不能将空值赋给主机变量,因为没有指定指示符变量。
22003 数值超出范围。
22004 不能从定义为 parameter style general 的过程或者从用非空参数调用的类型保留方法中返回空值。
22007 检测到无效的日期时间格式;即指定了无效的字符串表示法或值。
22008 发生日期时间字段溢出;例如,对日期或时间戳记算术运算的结果不在有效日期范围之内。
2200g 大多数特定类型都不匹配。
2200l xml 值不是具有单个根元素的结构良好的文档。
2200m 未能将值作为结构良好的 xml 文档进行解析或者根据 xml 模式来验证该值。
2200s xml 注释无效。
2200t xml 处理指令无效。
2200w xml 值包含未能序列化的数据。
22011 发生子字符串错误;例如,substr 的参数超出范围。
22012 用零作除数是无效的。
22018 对于 cast、decimal、float、或 integer 标量函数,字符值是无效的。
22019 like 谓词有无效转义字符。
22021 某字符不在编码字符集中。
22024 以 nul 结束的输入主机变量或参数不包含 nul。
22025 like 谓词字符串模式包含无效的转义字符。
2202d 配合 mutator 方法使用了空实例。
2202h 在 tablesample 子句中指定的样本大小无效。
22501 变长字符串的长度控制字段为负值或大于最大值。
22504 混合数据值是无效的。
22506 对日期时间专用寄存器的引用无效,因为 tod 时钟发生故障或操作系统时区参数超出范围。
22522 ccsid 值根本无效,对数据类型或子类型无效,或对编码方案无效。
22525 数据分区键值无效。
22526 键变换函数没有生成任何行或生成了重复的行。
22527 对多行 insert 操作检测到了无效的输入数据。
22532 在 xml 模式存储库中未找到 xsrobject。
22533 在 xml 模式存储库中未找到唯一的 xsrobject。
22534 xml 模式文档未通过使用包括或重新定义而连接至其他 xml 模式文档。
22535 xml 模式未声明指定的全局元素。
22536 xml 值不包含必需的根元素。
225d1 未启用指定的 xml 模式以进行分解。
225d2 在分解 xml 文档期间发生了 sql 错误。
225d3 分解 xml 文档时遇到了对于 xml 模式类型无效的值。
225d4 分解 xml 文档时遇到了对于目标 sql 类型无效的值。
225d5 分解 xml 文档时遇到了上下文中未知或无效的 xml 节点。
225d6 指定的 xml 模式需要迁移到当前版本以支持分解。
225d7 分解 xml 文档时遇到了一个根元素,该根元素不是 xml 模式中的复杂类型的全局元素。
225de 无法启用 xml 模式以进行分解。

类代码 23 约束违例
表 18. 类代码 23:约束违例 sqlstate 值  
含义
23001 restrict 更新或删除规则防止父键被更新或删除。
23502 插入或更新值为空,但该列不能包含空值。
23503 外键的插入或更新值无效。
23504 no action 更新或删除规则防止父键被更新或删除。
23505 发生由唯一索引或唯一约束强加的约束违例。
23510 使用由 rlst 表强加的命令时发生约束违例。
23511 不能删除父行,因为检查约束限制该删除。
23512 不能添加检查约束,因为该表含有不满足约束定义的行。
23513 insert 或 update 的结果行不符合检查约束定义。
23514 检查数据处理中发现约束违例。
23515 未能创建唯一索引,或者不能添加唯一约束,因为该表包含指定键的重复值。
23520 不能定义外键,因为其所有的值都不同于父表的父键。
23521 对目录表的更新违反了内部约束。
23522 标识列值的范围或者序列用完。
23523 已经为安全标号列提供了无效值。
23524 union all 视图内的无效行移动。
23525 未能插入或更新 xml 值,这是因为在插入或更新 xml 列的索引期间检测到错误。
23526 未能创建 xml 列的索引,因为在将 xml 值插入到索引中时检测到错误。

类代码 24 无效的游标状态
表 19. 类代码 24:无效的游标状态 sqlstate 值  
含义
24501 标识的游标未打开。
24502 在 open 语句中标识的游标已经打开。
24504 在 update、delete、set 或 get 语句中标识的游标未定位在行上。
24506 在 prepare 中标识的语句是一个打开游标语句。
24510 对一个删除孔或更新孔尝试了

update 或 delete 操作。
24512 结果表与基本表不一致。
24513 不允许 fetch next、prior、current 或 relative,原因是游标位置未知。
24514 先前的错误已禁用此游标。
24516 已对结果集指定了一个游标。
24517 外部函数或方法将游标保持为打开。

 

类代码 25 无效的事务状态
表 20. 类代码 25:无效的事务状态 sqlstate 值  
含义
25000 插入、更新或删除操作在指定它的上下文中无效。
25001 该语句只允许作为工作单元的第一条语句。
25501 该语句只允许作为工作单元的第一条语句。
25502 操作在单个事务中不能多次出现。

类代码 26 无效 sql 语句标识
表 21. 类代码 26:无效 sql 语句标识 sqlstate 值  
含义
26501 标识的语句不存在。

类代码 27 触发的数据更改违例
表 22. 类代码 27:触发的数据更改违例 sqlstate 值   含义
27000 试图在同一 sql 语句中多次更改同一个表中的同一行。

类代码 28 无效权限规范
表 23. 类代码 28:无效权限规范 sqlstate 值  
含义
28000 权限名称无效。

类代码 2d 无效事务终止
表 24. 类代码 2d:无效事务终止 sqlstate 值  
含义
2d521 sql commit 或 rollback 在当前操作环境中无效。
2d522 atomic 复合语句中不允许 commit 和 rollback。
2d528 动态 commit 对于应用程序执行环境无效。
2d529 动态 rollback 对于应用程序执行环境无效。

类代码 2e 无效连接名称
表 25. 类代码 2e:无效连接名称 sqlstate 值  
含义
2e000 连接名称无效。

类代码 34 无效的游标名称
表 26. 类代码 34:无效的游标名称 sqlstate 值  
含义
34000 游标名无效。

类代码 36 无效游标规范
表 27. 类代码 36:无效游标规范 sqlstate 值  
含义
36001 不能为指定的 select 语句定义敏感游标。

类代码 38 外部函数异常
表 28. 类代码 38:外部函数异常 sqlstate 值  
含义
38xxx 外部例程或触发器返回有效错误 sqlstate。
38001 不允许外部例程执行 sql 语句。
38002 例程尝试修改数据,但例程未定义为 modifies sql data。
38003 例程中不允许该语句。
38004 例程尝试读取数据,但例程未定义为 reads sql data。
38501 (使用 simple call 或 simple call with nulls 调用约定)调用用户定义的函数、外部过程或触发器时出错。
38502 不允许外部函数执行 sql 语句。
38503 用户定义的函数异常终止(abend)。
38504 用户定义的函数已被用户中断,以停止可能的循环条件。
38505 final call 上的例程中不允许 sql 语句。
38506 函数因来自 ole db 提供程序的错误而失败。
38552 sysfun 模式(由 ibm 提供)中的函数已异常终止。
可以在消息正文中找到下列原因码之一:

01
数值超出范围
02
被零除
03
算术溢出或下溢
04
日期格式无效
05
时间格式无效
06
时间戳记格式无效
07
时间戳记持续时间的字符表示法无效
08
时间间隔类型无效(必须是 1、2、4、8、16、32、64、128、256 之一)
09
字符串太长
10
字符串函数中的长度或位置超出范围
11
浮点数的字符表示法无效 
38553 系统模式中的例程已因错误而终止。
38h01 mqseries 函数未能初始化。
38h02 mqseries 的“应用程序消息传递接口”未能终止会话。
38h03 mqseries 的“应用程序消息传递接口”未能正确地处理消息。
38h04 mqseries 的“应用程序消息传递接口”未能发送消息。
38h05 mqseries 的“应用程序消息传递接口”未能读取/接收消息。
38h06 mqseries 的“应用程序消息传递接口”预订(不预订)请求失败。
38h07 mqseries 的“应用程序消息传递接口”未能落实工作单元。
38h08 mqseries 的“应用程序消息传递接口”策略错误。
38h09 mqseries xa(两阶段落实)api 调用错误。
38h0a mqseries 的“应用程序消息传递接口”未能回滚工作单元。

类代码 39 外部函数调用异常
表 29. 类代码 39:外部函数调用异常 sqlstate 值  
含义
39001 用户定义的函数已返回无效 sqlstate。
39004 不允许 in 或 inout 参数为空值。
39501 与参数相关联的 eye-catcher(引人注目的事物)已被修改。

类代码 3b savepoint 无效
表 30. 类代码 3b:savepoint 无效 sqlstate 值  
含义
3b001 保存点无效。
3b002 已经达到最大保存点数目。
3b501 检测到重复的保存点名。
3b502 指定了 release 或 rollback to savepoint,但是保存点不存在。
3b503 在触发器或全局事务中不允许 savepoint、 release savepoint 或 rollback to savepoint。

类代码 40 事务回滚
表 31. 类代码 40:事务回滚 sqlstate 值  
含义
40001 发生了伴随自动回滚的超时或死锁。
40003 语句完整性未知。
40504 由于系统错误导致工作单元被回滚。
40506 由于 sql 错误,当前事务已回滚。
40507 由于创建索引时发生故障,因此当前事务已回滚。

类代码 42 语法错误或访问规则违例
表 32. 类代码 42:语法错误或访问规则违例 sqlstate 值  
含义
42501 授权标识不具有对标识对象执行指定操作的特权。
42502 授权标识不具有执行指定操作的特权。
42504 无法从指定的权限名撤销指定的特权、安全标号或免除凭证。
42506 发生所有者授权失败。
42508 不能将指定的数据库特权授予 public。
42509 因为 staticrules 选项而未授权 sql 语句。
42511 未能检索 datalink 值。
42512 授权标识对受保护列没有访问权。
42514 授权标识不具有对象的所有权需要的特权。
42516 用户映射存储库中的认证失败。
42519 不允许此授权标识对受保护表执行操作。
42520 由于此授权标识没有安全标号,所以无法执行内置函数。
42521 无法将权限或特权授予指定的授权标识。
42522 此授权标识没有凭证,因此无法保护列或者对该列除去保护。
42601 字符、标记或子句无效或丢失。
42602 检测到名称中有无效字符。
42603 检测到未终止的字符串常量。
42604 检测到无效数字或字符串常量。
42605 为标量函数指定的参数的数目无效。
42606 检测到无效十六进制常数。
42607 列函数的操作数无效。
42608 在 values 中使用 null 或 default 是无效的。
42609 运算符或谓词的所有操作数都是参数标记。
42610 不允许参数标记。
42611 列或参数定义无效。
42612 语句字符串是一条 sql 语句,它在它所出现的上下文中是不可接受的。
42613 子句互斥。
42614 重复关键字无效。
42615 检测到无效备用项。
42616 指定了无效的选项。
42617 语句字符串是空白或空的。
42618 不允许主机变量。
42620 对 update 子句指定了只读 scroll。
42621 检查约束无效。
42622 名称或标号太长。
42623 不能指定 default 子句。
42625 case 表达式无效。
42627 必须在使用 expression as 子句的谓词规范之前指定 returns 子句。
42628 在变换定义中多次定义了 to sql 或 from sql 变换函数。
42629 必须为 sql 例程指定参数名。
42630 在嵌套复合语句中不能存在 sqlstate 或 sqlcode 变量声明。
42631 sql 函数或方法中的 return 语句必须包括返回值。
42633 xmlattributes 或 xmlforest 的参数需要 as 子句。
42634 xml 名称无效。
42635 xml 名称空间前缀无效。
42636 缺少 by ref 子句,或者不正确使用了该子句。
42637 无法在 declare cursor 语句中指定 xquery 表达式。
42701 在插入或更新操作或 set 转换变量语句中检测到重复列名。
42702 由于名称重复,列引用有歧义。
42703 检测到一个未定义的列、属性或参数名。 
42704 检测到未定义的对象或约束名。
42705 检测到未定义的服务器名。
42707 order by 内的列名不标识结果表中的列。
42709 在键列列表中指定了重复的列名。
42710 检测到重复的对象或约束名。
42711 在对象定义或 alter 语句中检测到重复列名或属性名。
42712 在 from 子句中检测到重复的表标志符。
42713 在对象列表中检测到重复对象。
42720 在节点目录内未找到远程数据库的节点名。
42723 模式中已经存在带有相同特征符的函数。
42724 不能访问用于用户定义的函数或过程的外部程序。
42725 直接引用了例程(不是通过特征符或者通过特定实例名进行引用),但是该例程有多个特定实例。
42726 检测到指定的派生表的名称重复。
42727 对新表来说,不存在缺省主表空间。
42728 在节点组定义中检测到重复节点。
42729 节点未定义。
42730 容器名已由另一表空间使用。
42731 容器名已由该表空间使用。
42732 在 set current path 语句中检测到重复的模式名。
42734 检测到重复的参数名、sql 变量名、游标名、条件名或标号。
42735 对缓冲池,未定义表空间的节点组。
42736 在 leave 语句上指定的标号找不到或无效。
42737 未定义在处理程序中指定的条件。
42738 在 for 语句的 declare cursor 语句中指定了重复的列名或未命名的列。
42739 检测到重复的变换。
42740 未找到指定类型的变换。未删除任何变换。
42741 未对数据类型定义变换组。
42742 类型表或带类型视图层次结构中已存在同类子表或子视图。
42743 在索引扩展名中未找到搜索方法。 
42744 在变换组中未定义 to sql 或 from sql 变换函数。
42745 例程将用现有方法定义覆盖关系。
42746 在同一类型层次结构中,方法名不能与结构化类型名相同。
42748 存储路径对于数据库来说已存在或者被指定了多次。
42749 对于 xml 模式来说,已经存在具有相同目标名称空间和模式位置的 xml 模式文档。
4274a 在 xml 模式存储库中未找到 xsrobject。
4274b 在 xml 模式存储库中未找到唯一的 xsrobject。
4274f 在安全标号组件中未定义组件元素。
4274g 在给定安全标号所使用的安全标号策略中未定义安全标号组件。
4274h 指定的安全策略不存在指定的访问规则。
4274i 指定的安全策略不存在安全标号。
4274j 数据库分区组已被此缓冲池使用。
42802 插入或更新值的数目与列数不相同。
42803 在 select 或 having 子句中的列引用无效,因为它不是分组列;或者在 group by 子句中的列引用无效。
42804 case 表达式中的结果表达式不兼容。
42805 order by 子句中的整数不标识结果表中的列。
42806 不能将某值赋予某主机变量, 因为数据类型不兼容。
42807 对该对象不允许执行 insert、update 或 delete。
42808 插入或更新操作中标识的列不可更新。
42809 标识的对象不是语句所应用的对象类型。
42810 foreign key 子句中没有标识基本表。
42811 指定的列数与 select 子句中的列数不相同。
42813 with check option 不能用于指定的视图。
42814 无法删除该列,因为它是表中唯一的列。
42815 数据类型、长度、小数位、值或 ccsid 无效。
42816 表达式中的日期时间值或持续时间无效。
42817 由于某个视图或约束依赖于该列,并且指定了 restrict,或者由于该列包含在分区键中,或者由于该列是安全标号列,所以无法删除该列。
42818 运算符或函数的操作数不兼容或者不可比较。
42819 算术运算的操作数或需要数字的函数的操作数不是数字。
42820 数字常数太长,或其值不在该数据类型取值范围内。
42821 更新或插入值与列不兼容。
42823 从仅允许一列的子查询中返回了多列。
42824 like 的操作数不是字符串,或第一个操作数不是列。
42825 union、intersect、except 或 values 的行没有兼容列。
42826 union、intersect、except 或 values 的行的列数不相同。
42827 update 或 delete 中标识的表与游标指定的表不相同。
42828 由 update 或 delete 语句的游标指定的表不能修改,或该游标是只读游标。
42829 for update of 无效,因为由该游标指定的结果表不能修改。
42830 外键不符合父键的描述。
42831 主键或唯一键列不允许空值。
42832 不允许对系统对象执行该操作。
42834 不能指定 set null,因为不能对外键的任何列指定空值。
42835 在指定的派生表之间不能指定循环引用。
42836 指定的递归派生表的规范无效。
42837 不能改变该列,原因是它的属性与当前的列属性不兼容。
42838 检测到无效使用了表空间。
42839 索引和长列不能处于与该表独立的表空间内。
42840 检测到无效使用了 as cast 选项。
42841 参数标记不能是用户定义的类型或引用类型。
42842 列定义无效,因为指定的选项与列描述不一致。
42845 检测到无效使用了 variant 或 external action 函数。
42846 不支持从源类型到目标类型的强制类型转换。
42849 外部例程不支持所指定的选项。
42852 在 grant 或 revoke 中指定的特权无效或不一致。(例如,视图上的 grant alter。)
42853 指定了选项的两个备用项,或者同一选项被指定了多次。
42854 选择列表中的结果列数据类型与在带类型视图或具体化查询表定义中定义的类型不兼容。
42855 不允许对此主机变量指定 lob。此游标的 lob 值的所有访存的目标主机变量必须是定位器或 lob 变量。
42858 不能将该操作应用于指定对象。
42863 检测到 rexx 中有未定义的主机变量。
42866 在 create function 语句的 cast from 子句中的 returns 子句的数据类型对于有源函数或函数体中的 return 语句返回的数据类型不适合。
42867 指定了冲突的选项。
42872 fetch 语句子句与游标定义不兼容。
42875 要在 create schema 中创建的对象的限定符必须与模式名相同。
42877 不能限定该列名。
42878 无效的函数或过程名称与 external 关键字一起使用。
42879 在 create function 语句中一个或多个输入参数的数据类型对于源函数中相应的数据类型不适合。
42880 cast to 和 cast from 数据类型不兼容,或总会导致固定字符串截断。
42881 使用基于行的函数无效。
42882 特定实例名限定符与函数名限定符不相同。
42883 找不到具有匹配特征符的例程。
42884 找不到具有指定名称和兼容参数的任何例程。
42885 在 create function 语句中指定的输入参数数目与 source 子句中指定的函数所提供的参数数目不匹配。
42886 in、out 或 inout 参数属性不匹配。
42887 在该函数出现的上下文中该函数无效。
42888 表没有主键。
42889 该表已有主键。
42890 在引用子句中指定了列表,但是标识的父表没有指定列名的唯一约束。
42891 重复的 unique 约束已存在。
42893 无法删除、改变或传输该对象或约束,或者无法从对象中撤销权限,因为还有其他对象依赖于该对象。
42894 default 值无效。
42895 对于静态 sql,不能使用输入主机变量,因为其数据类型与过程或用户定义的函数的参数不兼容。
428a0 用户定义的函数所基于的有源函数出错。
428a1 不能访问主机文件变量所引用的文件。
428a2 表不能指定给多节点节点组,因为它没有分区键。
428a3 为事件监视器指定了无效路径。
428a4 为事件监视器选项指定了无效值。
428a5 在 set integrity 语句中指定的异常表结构不正确,或者已用生成的列、约束或触发器定义了该异常表。
428a6 在 set integrity 语句中指定的异常表不能与正在检查的表之一相同。
428a7 检查的表数目与在 set integrity 语句中指定的异常表数目不匹配。
428a8 在父表或底层的表处于设置完整性暂挂状态时,不能对派生表使用 set integrity 语句复位设置完整性暂挂状态。
428a9 节点范围无效。
428aa 列名不是事件监视器表的有效列。
428b0 在 rollup、cube 或 grouping sets 中有非法嵌套。
428b1 未指定给特定节点的表空间容器的规范数目不正确。
428b2 容器的路径名无效。
428b3 指定了无效的 sqlstate。
428b7 在 sql 语句中指定的编号不在有效范围内。
428bo 不能为联合数据源创建方案。
428c0 不能删除该节点,因为它是节点组中唯一的节点。
428c1 只能为表指定一个 rowid、identity 或安全标号列。
428c2 检查函数体指出应已在 create function 语句中指定给出的子句。
428c4 谓词运算符两边的元素的数目不相同。
428c5 从数据源中找不到数据类型的数据类型映射。
428c9 不能将 rowid 列指定为 insert 或 update 的目标列。
428ca 处于追加方式的表不能具有集群索引。
428cb 表空间的页大小必须与相关联的缓冲池的页大小相匹配。
428d1 不能访问 datalink 值所引用的文件。
428d4 在 open、close 或 fetch 语句中不能引用在 for 语句中指定的游标。
428d5 结束标号与开始标号不匹配。
428d6 not atomic 语句不允许 undo。
428d7 不允许条件值。
428d8 sqlstate 或 sqlcode 变量的声明或使用无效。
428db 作为超类型、超表或超视图,该对象无效。 
428dc 对于此类型的变换,该函数或方法无效。
428dd 未定义要求的变换。
428de pagesize 值不受支持。
428df 在 create cast 中指定的数据类型无效。
428dg 在 create cast 中指定的函数无效。
428dh 操作对于类型表无效。
428dj 不能更改或删除继承列或属性。
428dk 已定义引用列的作用域。
428dl 外部函数或有源函数的参数已定义了作用域。
428dm 作用域表或视图对于引用类

型无效。
428dn 未在外部函数的 returns 子句中指定 scope,或在有源函数的 return 子句中指定了 scope。
428dp 该类型不是结构化类型。
428dq 子表或子视图的模式名不能与其上一级表或上一级视图的模式名不同。
428dr 无法将操作应用于子表或子视图。
428ds 不能在子表中定义指定列的索引。 
428dt 表达式的操作数不是有效的作用域引用类型。
428du 要求的类型层次结构中不包括的一种类型。 
428dv 解析引用运算符的左操作数无效。
428dw 不能使用解析引用运算符来引用对象标识列。
428dx 对象标识列是定义一个类型表或带类型视图层次结构的根表或根视图所必需的。
428dy 不能对目标对象类型更新统计信息。
428dz 不能更新对象标识列。
428e0 索引的定义与索引扩展名的定义不匹配。
428e1 用于产生范围的表函数的结果与索引扩展名的键变换表函数的结果不一致。
428e2 目标键参数的数目或类型与索引扩展名的键变换函数的数目或类型不匹配。
428e3 索引扩展名中函数的参数无效。
428e4 函数在 create index extension 语句中不受支持。
428e5 只能用用户定义的谓词来指定 selectivity 子句。
428e6 用户定义的谓词中的方法的搜索参数与索引扩展名的相应搜索方法的搜索参数不匹配。
428e7 用户定义的谓词中跟在比较运算符后的操作数类型与 returns 数据类型不匹配。
428e8 搜索目标或搜索参数参数与正在创建的该函数的参数名不匹配。
428e9 在相同的使用规则中参数的参数名不能同时作为搜索目标和搜索参数。
428ea 带类型视图中的全查询无效。
428eb 当上一级视图中的某一列为可更新时,子视图中相应的列不能是只读的。
428ec 为具体化查询表指定的全查询无效。
428ed 不能构造具有 datalink 或 reference 类型属性的结构化类型。
428ee 选项对此数据源无效。
428ef 该选项的值对此数据源无效。
428eg 丢失此数据源所必需的选项。
428eh 不能 add 已定义的选项。
428ej 不能 set 或 drop 尚未添加的选项。
428ek 已声明的全局临时表名的限定符必须是 session。
428el 变换函数不能与函数或方法一起使用。
428em transform group 子句是必需的。
428en 变换组被指定为未使用。
428ep 结构化类型不能直接或间接依赖于它本身。
428eq 例程的返回类型与主题类型不同。
428er 在删除方法主体之前,不能删除方法规范。
428es 方法主体与方法规范的语言类型不对应。
428eu 在服务器定义中未指定 type 或 version。
428ev 对于该数据源类型,传递(pass-through)功能不受支持。
428ew 表不能与具体化查询表互相转换。
428ex 例程不能用作变换函数,因为它是内置函数或方法。
428ey 用户定义的谓词中搜索目标的数据类型与指定索引扩展名的源键的数据类型不匹配。
428ez olap 函数的窗口规范无效。
428f0 row 函数必须包括至少两列。
428f1 sql table 函数必须返回表结果。
428f2 sql 过程中的 return 语句值的数据类型必须是 integer。
428f3 scroll 与 with return 是互斥的。
428f4 在 fetch 上指定的 sensitivity 不允许用于游标。
428f6 游标是可滚动的,但结果表涉及来自表函数的输出。
428f7 尝试对外部例程进行的操作仅应用于 sql 例程。
428f9 在此上下文中不能指定序列表达式。
428fa 十进制数的小数位必须为零。
428fb 序列名不能是由系统为标识列生成的序列。
428fc 加密密码的长度无效。
428fd 用于解密的密码与加密数据时所使用的密码不匹配。
428fe 数据不是 encrypt 函数的结果。
428ff 缓冲池规范无效。
428fg 登台表或具体化查询表定义无效。
428fh set integrity 选项无效
428fi 指定了 order of,但表标志符不包含 order by 子句。
428fj 视图或具体化查询表的外部全查询不允许使用 order by。
428fl 在指定 sql 数据更改语句的上下文中,不允许 sql 数据更改语句。
428fm select 中的 insert 语句指定了一个不是对称视图的视图。
428fp 只允许将一个 instead of 触发器用于对主题视图的每种操作。
428fq instead of 触发器不能指定使用 with check option 定义的视图、在使用 with check option 定义的另一个视图上定义的视图或者嵌套在使用 with row movement 子句定义的视图中的视图。
428ft 表与指定的数据分区操作不兼容。
428fu 从 from sql 变换函数或方法返回的内置类型与 to sql 变换函数或方法的相应内置类型不匹配。
428fv 不能将方法定义为覆盖方法。
428fz 仅为某些操作定义了 instead of 触发器的视图不能在 merge 语句中用作目标。
428g1 数据分区数超过了表的表空间数。
428g2 无法从表中删除最后一个数据分区。
428g3 当全查询中的 sql 数据更改语句的目标视图定义了 instead of 触发器时,final table 无效。
428g4 无效使用了 input sequence 排序。
428g5 update 语句的赋值子句必须至少指定不是 include 列的一列。
428g6 指定了不能从全查询的 from 子句中的数据更改语句的目标中选择的一列。
428g8 不能启用视图以进行查询优化。
428ga 不能添加、删除或改变联合选项。
428gd partition by 子句必须指定单个列,并且它必须与 organize by 子句的第一列相同。
428ge 源表无法连接至分区目标表。
428gg 无效使用了容许错误的嵌套表表达式。
428go 列选项在透明 ddl 语句中无效。
428gi xml 模式不完整,因为缺少 xml 模式文档。
428gp 无法为类型为 array 的组件指定多个元素。
428gr 已经将具有相同访问类型(read 或 write)的安全标号授予给授权标识。
428gq 安全标号的 grant 与组件的现有已授权的安全标号相冲突。
428gs 对该过程指定的选项值与源过程的对应选项不匹配。
428gt 表未受安全策略保护。
42901 列函数不包括列名。
42903 where 子句或 set 子句包括无效引用,例如列函数。
42904 由于编译错误,未创建 sql 过程。
42907 字符串太长。
42908 语句不包括必需的列表。
42910 复合语句中不允许该语句。
42911 十进制除法运算无效,因为其结果的小数位为负。
42912 列不能更新,因为它未在游标的 select 语句的 update 子句中标识。
42914 delete 无效,因为子查询中引用的表可能会受该操作影响。
42915 检测到无效引用约束。
42916 不能创建别名,因为它会导致重复的别名链。
42917 不能显式删除或改变该对象。
42918 用户定义的数据类型不能用系统定义数据类型名(例如 integer)创建。
42919 不允许嵌套复合语句。
42921 容器不能添加至该表空间。
42925 指定的递归派生表不能指定 select distinct,而必须指定 union all。
42928 不能为该表指定 with empty table。
42932 程序预编译假设不正确。
42939 不能使用该名称,因为指定的标识是保留给系统使用的。
42961 指定的服务器名与当前服务器不匹配。
42962 长列、lob 列、xml 列或结构化类型列不能用于索引、键或约束。
42963 指定的安全标号列无效。
42968 连接失败,因为没有当前软件许可证。
42969 未创建程序包。
42972 merge 语句的连接条件或 on 子句中的表达式引用多个操作数表中的列。
42985 例程中不允许该语句。
42987 不允许此语句出现在过程或触发器中。
42989 使用表达式生成的列或者安全标号列不能在前触发器中使用。
42990 不允许唯一索引或唯一约束,因为键列不是分区键列的超集。
42991 boolean、binary 和 varbinary 数据类型当前仅在内部受支持。
42993 定义的列太大而不能记录。
42994 不支持原始设备容器。
42995 所请求的函数不应用于全局临时表。
42997 此版本的 db2 应用程序请求器、db2 应用程序服务器或两者的组合不支持该功能。
429a1 节点组对于表空间无效。
429a9 sql 语句不能由 datajoiner 处理。
429b2 为结构化类型或列指定的直接插入长度值太小。
429b3 可能未在子表中定义对象。
429b4 数据过滤函数不能是 language sql 函数。
429b5 索引扩展名中实例参数的数据类型无效。
429b8 用 parameter style java 定义的例程不能具有作为参数类型或返回类型的结构化类型。
429b9 在属性赋值中不能使用 default 或 null。
429ba federated 关键字必须与对联合数据库对象的引用配合使用。
429bb 在 sql 例程中不支持对参数或变量指定的数据类型。
429bc 在 alter tablespace 语句中有多个容器操作。
429be 主键或唯一键是维子句中的列的子集。
429bg 范围集群表不支持该函数。
429bh 分区表定义包含不受支持的列定义,该列可能是标识列、datalink 列或 xml 列。
429bj 在视图中无效使用了 with row movement。
429bk 由于移动行涉及到基础视图,因此,尝试更新视图无效。
429bl 在非法上下文中调用了将修改 sql 数据的函数。
429bo 不能为联合数据源创建方案。
429bp 昵称列表达式无效。
429bs 涉及到 xmlpattern 子句或使用数据类型 xml 定义的列的索引定义无效。
429bt 由于存在依赖性而使得转移所有权失败。
429bu 无法访问插件的用户映射存储库中的用户映射。
429bz 由于其中一个底层表受保护,所以对 union all 视图执行的更新、删除或插入操作失败。
429c0 查询必须包含使用了所指示的列的谓词。

 

类代码 44 with check option 违例
表 33. 类代码 44:with check option 违例 sqlstate 值  
含义
44000 不允许插入或更新操作,因为结果行不满足视图定义。

类代码 46 java ddl
表 34. 类代码 46:java ddl sqlstate 值  
含义
46001 java ddl - 无效 url。
46002 java ddl - 无效 jar 名称。
46003 java ddl - 无效类删除。
46007 java ddl - 无效特征符。
46008 java ddl - 无效方法规范。
46103 java 例程遇到了 classnotfound 异常。
46501 java ddl - 未实现可选组件。

类代码 51 无效应用程序状态
表 35. 类代码 51:无效应用程序状态 sqlstate 值  
含义
51002 未找到与 sql 语句执行请求相对应的程序包。
51003 一致性标记不匹配。
51004 sqlda 中的地址无效。
51005 上一系统错误已禁用此函数。
51008 预编译的程序的发行版号无效。
51015 尝试执行在绑定时发现有错的节。
51017 用户没有登录。
51021 在应用程序进程执行了回滚操作之后才能执行 sql 语句。
51022 当 connect 语句中指定的服务器已存在连接(不论处于当前状态还是休眠状态)时,指定权限名称的 connect 无效。
51023 该数据库已由数据库管理器的另一实例使用。
51024 不能使用视图,因为它已被标记为不可操作。
51025 在 xa 事务处理环境中的应用程序未用 syncpoint twophase 绑定。
51026 无法打开事件监视器,因为它的目标路径已由另一事件监视器使用。
51027 因为表是用户维护的具体化查询表或未处于设置完整性暂挂状态,所以 set integrity 语句的 immediate checked 选项无效。
51028 不能使用程序包,因为它被标记为不可操作。
51030 在应用程序进程中尚未调用 allocate cursor 或 associate locators 语句中所引用的过程。
51034 使用 modifies sql data 定义的例程在调用它的上下文中无效。
51035 不能使用 prevval 表达式,原因是在此会话中还没有为序列生成值。
51038 sql 语句可能不再由例程发出。
51039 未设置 encryption password 值。
51040 编译环境无效。

类代码 53 无效操作数或不一致的规范
表 36. 类代码 53:无效操作数或不一致的规范 sqlstate 值  
含义
53038 键限制值的数目为零或者大于键中的列数。
53040 不能像指定的那样更改缓冲池。
53045 键限制常量的数据类型与列的数据类型不相同。
53090 同一条 sql 语句中只能引用具有一种编码方案(ascii、ebcdic 或 unicode)的数据。
53091 指定的编码方案与当前用于包含对象的编码方案不相同。

类代码 54 超过 sql 或产品限制
表 37. 类代码 54:超过 sql 限制或产品限制 sqlstate 值  
含义
54001 语句太长或者太复杂。
54002 字符串常量太长。
54004 语句中 select 或 insert 列表中的项或表名太多。
54006 并置的结果太长。
54008 键太长,键的列太长,或者键的列数太多。
54010 表的记录长度太长。
54011 为表或视图指定了太多列。
54023 用于函数或过程的参数或自变量数目超出限制。
54028 已达到并发 lob 句柄最大数。
54029 已达到打开目录扫描最大数。
54030 活动事件监视器已达最大数。
54031 已对事件监视器分配了最大文件数。
54032 已达到表的最大大小。
54033 已达到分区映射最大数。
54034 表空间的所有容器名的组合长度太长。
54035 已超过内部对象限制。
54036 容器或存储路径的路径名太长。
54037 表空间的容器映射太复杂。
54038 超出了嵌套例程或触发器的最大深度。
54045 已超出类型层次结构的最大级别。
54046 索引扩展名中已超出允许的参数的最大值。
54047 已超出表空间的最大大小。
54048 具有足够页大小的临时表空间不存在。
54049 结构化类型的实例的长度超过了系统限制。
54050 在结构化类型中超过了允许的最大属性数目。
54052 缓冲池的块页数对缓冲池对于缓冲池的大小来说太大了。
54053 为 blocksize 指定的值不在有效范围内。
54054 超过了分区数或者超过了表空间分区数与分区限制键的相应长度的组合。
54057 xml 元素名称、属性名称、名称空间前缀或 uri 太长。
54058 xml 路径的内部表示太长。
54059 只具有空格字符的文本节点字符串值太长,无法进行 strip whitespace 处理。
54061 对安全标号组件指定了太多元素。
54062 已经超过了安全策略中的最大组件数。

类代码 55 对象不处于先决条件状态
表 38. 类代码 55:对象不处于先决条件状态。 sqlstate 值  
含义
55001 数据库必须迁移。
55002 未正确定义解释表。
55006 对象不能删除,因为它当前正由同一应用程序进程使用。
55007 不能改变对象,因为它当前正由同一应用程序进程使用。
55009 系统尝试对只读文件或写保护软盘进行写入。
55012 在表中已存在一个集群索引。
55019 表的状态对于该操作无效。
55022 未向此数据库注册文件服务器。
55023 调用例程时发生错误。
55024 表空间不能删除,因为与表相关的数据也在另一表空间中。
55025 必须重新启动数据库。
55026 不能删除临时表空间。
55031 错误映射文件的格式不正确。
55032 connect 语句无效,因为在该应用程序启动后,数据库管理器停止。
55033 事件监视器不能在创建它或修改它所处的同一工作单元内激活。
55034 事件监视器处于无效的操作状态。
55035 不能删除该表,因为它是受保护的。
55036 不能删除该节点,因为它未从该分区映射除去。
55037 不能删除该分区键,因为该表在多节点节点组内。
55038 该节点组不能使用,因为它正在进行重新平衡。
55039 不允许访问或状态转换,因为该表空间未处于适当状态。
55041 在进行重新平衡时,不能将容器添加至表空间。
55043 当基于该类型的类型表或带类型视图存在时,不能改变结构化类型的属性。
55045 不能为该例程创建“sql 归档”(sar)文件,因为服务器上未提供所需组件。
55046 指定的 sql 归档与目标环境不匹配。
55047 外部函数或方法尝试访问联合对象。
55048 不能再加密已加密的数据。
55049 未正确定义事件监视器表。
55051 alter bufferpool 语句当前正在处理中。
55054 不能将方法定义为覆盖方法。
55056 由于未启用数据库进行联合,因此不能更新昵称统计信息。
55057 不允许使用该语句,因为它将使增量维护某些从属表失效。
55060 还没有为数据库定义自动存储器。
55061 无法对自动存储器表空间更改表空间存储器。
55062 因为没有对数据库启用自动存储器,所以不能提供存储路径。
55063 对于该操作来说,xml 模式未处于正确状态。
55064 无法将基于标号的访问控制应用于列,因为表没有安全策略。
55065 一个表最多只能有一种安全策略。
55066 表不能分配新页,因为索引尚不支持大型 rid。
55067 表不能生成受保护的表,因为 mqt 或登台表依赖于它。

类代码 56 其他 sql 或产品错误
表 39. 类代码 56:其他 sql 或产品错误 sqlstate 值  
含义
56016 为数据分区指定了无效范围。
56031 子句或标量函数无效,因为该系统不支持混合数据和 dbcs 数据。
56033 长字符串列的插入值或更新值必须是主机变量或 null。
56038 此环境不支持请求的功能部件。
56072 由于低级别服务器不支持函数,所以执行失败,这不会影响后续 sql 语句的执行。
56084 在 drda 中不支持 lob 数据。
56091 执行复合 sql 语句时发生多个错误。
56092 权限类型不能确定,因为权限名称既是用户标识又是组标识。
56095 绑定选项无效。
56097 在 device 上构建的 tablespace 中不允许 long varchar 和 long vargraphic 字段。
56098 在隐式重新绑定或预编译期间出错。
56099 目标数据库不支持 real 数据类型。
560a0 对 lob 值的操作失败。
560aa 只有 unicode 数据库图形数据才支持使用此子句或标量函数。
560ac 包装器定义不能用于指定类型或版本的数据源。
560af 当使用网关集中器时,prepare 语句不受支持。
560b0 调整的新表空间或表空间容器大小值无效。
560b1 存储过程中有无效的游标规范。
560b7 对于多行 insert,对于每一行,序列表达式的用法都必须相同。
560bb 对于动态预编译的 call 语句中的 inout 参数,必须在 using 和 into 子句中使用相同的主机变量。
560bc 访问文件时发生错误。
560bd 联合服务器从数据源中接收到意外的错误代码。
560bf 加密工具不可用。
560c0 不能在 sql 函数或 sql 方法中使用以 unicod

e 编码方案创建的表。
560c1 以 unicode 编码方案创建的表不能是类型表或者包含图形类型或用户定义的类型。
560c2 为已删除表写历史记录文件条目失败。
560c3 后触发器不能修改为 insert 语句插入的一行。
560c6 引用约束不能修改由全查询内的 sql 数据更改语句修改的行。
560c8 不能更新某些昵称统计信息。
560c9 不能说明指定的语句。
560cb 联合服务器从 web service 数据源中接收到 soap 故障。
560cd 在检索警报配置设置时指定的一个或多个值无效。
560ce 由于最近的落实或回滚操作,使得 sql 变量不可供引用。
560cf 无法将表空间转换为大型表空间。
560cg xml 值包含一些 xml 节点的组合,该组合导致超过了内部标识限制。
560ch 超过了 xml 值中 xml 节点的子节点的最大数目。
560ci 指定要返回给客户机的结果集无效。
560cj 必须在 ibmcatgroup 数据库分区组中创建表空间。

 

类代码 57 资源不可用或操作员干预
表 40. 类代码 57:资源不可用或操作员干预 sqlstate 值  
含义
57001 表不可用,因为它没有主索引。
57003 尚未激活指定的缓冲池。
57007 对象不能使用,因为 drop 或 alter 处于暂挂状态。
57009 虚拟存储器或数据库资源暂时不可用。
57011 虚拟存储器或数据库资源不可用。
57012 非数据库资源不可用。这不会影响后续语句的成功执行。
57013 非数据库资源不可用。这将影响后继语句的成功执行。
57014 按照请求取消了处理。
57016 因为表不活动,所以不能访问它。
57017 未定义字符转换。
57019 该语句因资源问题未成功。
57020 包含数据库的驱动器被锁定。
57021 软盘驱动器门是打开的。
57022 不能创建表,因为语句的授权标识不拥有任何合适的 dbspaces。
57030 与应用程序服务器的连接超出安装定义的限制。
tp57032 已启动最大并发数据库数。
57033 发生死锁或超时,而没有自动回滚。
57036 事务日志不属于当前的数据库。
57046 不能启动新的事务,因为数据库或实例被停顿。
57047 不能创建内部数据库文件,因为该目录不可访问。
57048 访问表空间的容器时发生错误。
57049 已达到操作系统进程界限。
57050 文件服务器当前不可用。 
57051 估计的 cpu 成本超出了资源限制。
57052 节点不可用,因为它所含有的容器不足以满足所有的临时表空间。
57053 因为冲突操作,所以不能对表执行操作。
57055 带有足够页大小的临时表空间不可用。 
57056 程序包不可用,因为数据库处于 no package lock 方式。
57057 由于 sql 语句的 drda 链中的优先条件,不能执行该 sql 语句。
57059 表空间中没有足够的空间用于执行指定的操作。

类代码 58 系统错误
表 41. 类代码 58:系统错误 sqlstate 值  
含义
58004 发生系统错误(它不一定阻止后续 sql 语句的成功执行)。
58005 发生系统错误(它阻止后续 sql 语句的成功执行)。
58008 由于分发协议错误致使执行失败,它不影响后续 ddm 命令或 sql 语句的成功执行。
58009 由于分发协议错误致使执行失败,它导致对话的释放。
58010 由于分发协议错误致使执行失败,它将影响后续 ddm 命令或 sql 语句的成功执行。
58011 进行绑定时 ddm 命令无效。
58012 具有指定程序包名和一致性标记的绑定进程不活动。
58014 ddm 命令不受支持。
58015 ddm 对象不受支持。
58016 ddm 参数不受支持。
58017 ddm 参数值不受支持。
58018 不支持 ddm 应答消息。
58023 系统错误导致当前程序被取消。
58030 发生 i/o 错误。
58031 连接因系统错误而未成功。
58032 不能将该进程用于设防方式的用户定义的函数。
58034 尝试在 dms 表空间中寻找对象的页时检测到错误。
58035 尝试在 dms 表空间中释放对象的页时检测到错误。
58036 指定的内部表空间标识不存在。

类代码 5u 实用程序
表 42. 类代码 5u:实用程序 sqlstate 值  
含义
5u001 指定的函数或功能部件不受支持。
5u002 指定的应用程序当前不存在。
5u003 找不到活动监控器报告。
5u004 保存监视任务时所提供的一个或多个值无效。
5u005 指定的操作方式无效。
5u006 未打开必需的监视开关。
5u007 返回了 clp 错误。有关详细信息,请参阅 clp 消息文档。
5u008 实用程序操作标识无效。
5u009 已达到存储路径的最大数目。
5u010 对非目录数据库分区执行的复原操作不能指定自动存储路径。
5u011 复原操作必须指定自动存储路径。
5u012 路径中的数据库分区表达式无效或者不正确地使用了它。
5u013 不能继续进行复原,因为数据库分区不可用。
5u014 授权标识没有对表运行 load 命令所必需的 lbac 凭证。
5u0zz 例程遇到了错误。参阅 sqlcode 以获取详细信息。
zzzzz 占位符 sqlstate 仅供开发使用。在交付代码之前必须更改它。

文章来源:



芦苇 2007-04-12 15:57
]]>
mysql的transaction实现http://www.blogjava.net/i369/articles/108906.html芦苇芦苇fri, 06 apr 2007 05:04:00 gmthttp://www.blogjava.net/i369/articles/108906.htmlhttp://www.blogjava.net/i369/comments/108906.htmlhttp://www.blogjava.net/i369/articles/108906.html#feedback0http://www.blogjava.net/i369/comments/commentrss/108906.htmlhttp://www.blogjava.net/i369/services/trackbacks/108906.htmltransaction在数据库编程中是一个重要的概念,这样做可以控制对数据库操作的事务提交。
但是要想在程序中实现事务,要求数据库本身支持事务。
现在的关系型数据库,我们日常使用的mysql,oracle等等都支持事务,有的是安装后直接就支持,有的需要做一些设置。
这篇文章是针对mysql的,讲述从数据库安装,设置,一直到sql语句,甚至到java程序中,如何实现transaction。
1.安装
要想在mysql的表中支持transaction,必须要求是innodb表。普通表使用的autocommit模式,会自动提交每一条sql语句,不能算是transaction吧。
安装时要指定mysql支持innodb,./configure --with-innodb。

2.配置
安装后,可以对innodb做一些配置,在my.cnf或my.ini中的[mysqld]段。
#存储目录,如果不指定默认为安装的data目录,为空时以innodb_data_file_path指定路径为准
innodb_data_home_dir =
#数据文件名及大小,默认为ibdata1,10m大小。autoextend可以自增,max:2000m文件最大2g,因为有的硬盘有2g文件大小限制。
innodb_data_file_path = ibdata1:2000m;ibdata2:2000m:autoextend:max:2000m
# 设置缓冲池大小
set-variable = innodb_buffer_pool_size=70m
set-variable = innodb_additional_mem_pool_size=10m
#设置日志文件路径,默认在date目录下,名称为ib_logfile...
innodb_log_group_home_dir =
#设置日志文件数目,默认为3
set-variable = innodb_log_files_in_group=3
# 设置日志文件大小
set-variable = innodb_log_file_size=10m
# 设置日志缓冲大小
set-variable = innodb_log_buffer_size=8m
# 任何事务提交前写入日志,方便故障诊断,请设为1。如果丢失最近的几个事务影响不大的话,设置为0(默认值)。
innodb_flush_log_at_trx_commit=1
#设置超时时间
set-variable = innodb_lock_wait_timeout=50

注意:innodb不会自动生成目录,上面所有指定目录要手工生成。默认不用。

完整的配置参数如下表(下表引自http://man.chinaunix.net/database/mysql/inonodb_zh/2.htm#innodb_start):

 

innodb_data_home_dir

这是innodb表的目录共用设置。如果没有在 my.cnf进行设置,innodb 将使用mysqldatadir目录为缺省目录。如果设定一个空字串,可以在 innodb_data_file_path中设定绝对路径。

innodb_data_file_path

单独指定数据文件的路径与大小。数据文件的完整路径由 innodb_data_home_dir 与这里所设定值的组合。 文件大小以 mb 单位指定。因此在文件大小指定后必有“m” innodb 也支持缩写“g” 1g = 1024m。从 3.23.44 开始,在那些支持大文件的操作系统上可以设置数据文件大小大于 4 gb。而在另一些操作系统上数据文件必须小于 2 gb。数据文件大小总和至少要达到 10 mb。在 mysql-3.23 中这个参数必须在 my.cnf中明确指定。在 mysql-4.0.2 以及更新版本中则不需如此,系统会默认在 mysql datadir目录下创建一个 16 mb 自扩充(auto-extending)的数据文件 ibdata1你同样可以使用一个 原生磁盘分区(raw raw disk partitions(raw devices)) 作为数据文件, 如何在 my.cnf中详细指定它们请查看第 12.1 节。

innodb_mirrored_log_groups

为了保护数据而设置的日志文件组的拷贝数目,默认设置为 1。在 my.cnf中以数字格式设置。

innodb_log_group_home_dir

innodb 日志文件的路径。必须与 innodb_log_arch_dir设置相同值。 如果没有明确指定将默认在 mysql datadir目录下建立两个 5 mb 大小的 ib_logfile...文件。

innodb_log_files_in_group

日志组中的日志文件数目。innodb 以环型方式(circular fashion)写入文件。数值 3 被推荐使用。在 my.cnf中以数字格式设置。

innodb_log_file_size

日志组中的每个日志文件的大小(单位 mb)。如果 n 是日志组中日志文件的数目,那么理想的数值为 1m 至下面设置的缓冲池(buffer pool)大小的 1/n。较大的值,可以减少刷新缓冲池的次数,从而减少磁盘 i/o。但是大的日志文件意味着在崩溃时需要更长的时间来恢复数据。 日志文件总和必须小于 2 gb3.23.55 4.0.9 以上为小于 4 gb。在 my.cnf中以数字格式设置。

innodb_log_buffer_size

innodb 将日志写入日志磁盘文件前的缓冲大小。理想值为 1m 8m。大的日志缓冲允许事务运行时不需要将日志保存入磁盘而只到事务被提交(commit)。 因此,如果有大的事务处理,设置大的日志缓冲可以减少磁盘i/o。 在 my.cnf中以数字格式设置。

innodb_flush_log_at_trx_commit

通常设置为 1,意味着在事务提交前日志已被写入磁盘, 事务可以运行更长以及服务崩溃后的修复能力。如果你愿意减弱这个安全,或你运行的是比较小的事务处理,可以将它设置为 0 ,以减少写日志文件的磁盘 i/o。这个选项默认设置为 0

innodb_log_arch_dir

the directory where fully written log files would be archived if we used log archiving. 这里设置的参数必须与 innodb_log_group_home_dir相同。 从 4.0.6 开始,可以忽略这个参数。

innodb_log_archive

这个值通常设为 0。 既然从备份中恢复(recovery)适合于 mysql 使用它自己的 log files,因而通常不再需要 archive innodb log files。这个选项默认设置为 0

innodb_buffer_pool_size

innodb 用来高速缓冲数据和索引内存缓冲大小。 更大的设置可以使访问数据时减少磁盘 i/o。在一个专用的数据库服务器上可以将它设置为物理内存的 80 %。 不要将它设置太大,因为物理内存的使用竞争可能会影响操作系统的页面调用。在 my.cnf中以数字格式设置。

innodb_additional_mem_pool_size

innodb 用来存储数据字典(data dictionary)信息和其它内部数据结构(internal data structures)的存储器组合(memory pool)大小。理想的值为 2m,如果有更多的表你就需要在这里重新分配。如果 innodb 用尽这个池中的所有内存,它将从操作系统中分配内存,并将错误信息写入 mysql 的错误日志中。在 my.cnf中以数字格式设置。

innodb_file_io_threads

innodb 中的文件 i/o 线程。 通常设置为 4,但是在 windows 下可以设定一个更大的值以提高磁盘 i/o。在 my.cnf中以数字格式设置。

innodb_lock_wait_timeout

在回滚(rooled back)之前,innodb 事务将等待超时的时间(单位 秒)innodb 会自动检查自身在锁定表与事务回滚时的事务死锁。如果使用 lock tables命令,或在同一个事务中使用其它事务安全型表处理器(transaction safe table handlers than innodb),那么可能会发生一个 innodb 无法注意到的死锁。在这种情况下超时将用来解决这个问题。这个参数的默认值为 50 秒。在 my.cnf中以数字格式设置。

innodb_flush_method

这个参数仅仅与 unix 相关。这个参数默认值为 fdatasync。 另一个设置项为 o_dsync。这仅仅影响日志文件的转储,在 unix 下以 fsync转储数据。innodb 版本从 3.23.40b 开始,在 unix 下指定 fdatasync为使用 fsync方式、指定 o_dsync为使用 o_sync方式。由于这在某些 unix 环境下还有些问题所以在 'data' versions 并没有被使用。

innodb_force_recovery

警告:此参数只能在你希望从一个被损坏的数据库中转储(dump)数据的紧急情况下使用! 可能设置的值范围为 1 - 6。查看下面的章节 'forcing recovery' 以了解这个参数的具体含义。参数设置大于 0 的值代表着 innodb 防止用户修改数据的安全度。从 3.23.44 开始,这个参数可用。在 my.cnf中以数字格式设置。

innodb_fast_shutdown

innodb 缺少在关闭之前清空插入缓冲。这个操作可能需要几分钟,在极端的情况下可以需要几个小时。如果这个参数据设置为 1 innodb 将跳过这个过程而直接关闭。从 3.23.44 4.0.1 开始,此参数可用。从 3.23.50 开始,此参数的默认值为 1

innodb_thread_concurrency

innodb 会试图将 innodb 服务的使用的操作系统进程小于或等于这里所设定的数值。此参数默认值为 8。如果计算机系统性能较低或 innodb_monitor显示有很多线程等侍信号,应该将这个值设小一点。如果你的计算机系统有很我的处理器与磁盘系统,则可以将这个值设高一点以充分利用你的系统资源。建议设值为处理器数目磁盘数目。 从 3.23.44 4.0.1 开始,此参数可用。在 my.cnf中以数字格式设置。

innodb还需要使用二进制日志文件:

log-bin指定二进制文件名称,不指定默认生成。
log-bin-index 可以指定索引文件。
使用 binlog-do-db可以指定记录的数据库。
使用 binlog-ignore-db可以指定不记录的数据库。
注意的是: binlog-do-db 和binlog-ignore-db 一次只指定一个数据库,指定多个数据库需要多个语句。而且,mysql会将所有的数据库名称改成小写, 在指定数据库时必须全部使用小写名字,否则不会起作用。

3.添加表
create table user (id int not null auto_increment,primary key,fname varchar(15),sname varchar(20),sex varchar(6),age varchar(3)) type=innodb;
记得后面的type=innodb。

4.sql语句的transaction实现
两种方式:
如果set autocommit=0;也就是关闭了自动提交,那么任何commit或rallback语句都可以触发事务提交。
比如:
 mysql> set autocommit=0;
 query ok, 0 rows affected (0.00 sec)
 
 mysql> insert into user(fname,sname) values ('max','ma');
 query ok, 1 row affected (0.00 sec)

 mysql> insert into user(fname,sname) values ('sky','sun');
 query ok, 1 row affected (0.00 sec)
 
 mysql> commit;
 query ok, 0 rows affected (0.00 sec)
这样事务就算提交了。
如果set autocommit=1;也就是开启了自动提交(默认值),那么必须要以begin或者start transaction声明事务的开始,然后再以commit或rallback语句都可以触发事务提交。
比如:
 mysql> set autocommit=1;
 query ok, 0 rows affected (0.00 sec)

 mysql> begin;
 query ok, 0 rows affected (0.00 sec)
 
 mysql> insert into user(fname,sname) values ('max','ma');
 query ok, 1 row affected (0.00 sec)

 mysql> insert into user(fname,sname) values ('sky','sun');
 query ok, 1 row affected (0.00 sec)
 
 mysql> commit;
 query ok, 0 rows affected (0.00 sec)

像其他关系型数据库一样,也可以使用存储过程(procedure)来封装事务。

5.java程序开发中的实现。
涉及到程序开发实现方法就多了。
一.自己写方法把mysql的底层transaction命令封装。我感觉程序开发中应该尽量避免和底层数据库的过多交互,我没有实现它。
有人实现了,下面是他实现的一个例子网址:
二.java的jdbc开发包包含了操作transaction的方法,在java.sql.connection接口里。
使用他的好处是可以和多种类型数据库交互。
三.hibernate等orm框架工具。
hibernate 中也封状了对transaction的操作,在org.hibernate.session类中,使用begintransaction()方法开启 transaction;使用gettransaction().commit()提交transaction;使用gettransaction(). rollback()方法回滚transaciton。
四.这是我常用的一种方法,把hibernate的session的方法封装或者实现jdbc的connection的接口。



trackback: http://tb.blog.csdn.net/trackback.aspx?postid=1481131



芦苇 2007-04-06 13:04
]]>
mysql 5 详细安装指南(windows) http://www.blogjava.net/i369/articles/89558.html芦苇芦苇fri, 22 dec 2006 08:28:00 gmthttp://www.blogjava.net/i369/articles/89558.htmlhttp://www.blogjava.net/i369/comments/89558.htmlhttp://www.blogjava.net/i369/articles/89558.html#feedback0http://www.blogjava.net/i369/comments/commentrss/89558.htmlhttp://www.blogjava.net/i369/services/trackbacks/89558.html附件 ] 里面是安装版的详细图解(右击->目标另存为),下载后把扩展名改为.rar,然后解压。
以下叙述的是非安装版的配置方法:

一.     下载mysql 5.0.18
  1.  下载路径:
  2.  下载解压版本(绿色)

       绿色软件不许要安装,只需解压到任意目录下即可(建议解压名称不带空格和中文)

二.     配置mysql
  1.  解压mysql.zip 到 任意目录    /*目录可以为任意目录,不推荐带空格和中文名称*/

  2.  在命令提示符下输入命令%system%,查看本系统的系统文件夹(xp一般是windows) 在系统目录%system%下建立文件my.ini

  3.  在mysql根目录下有5个ini文件,我们使用mysql-small.ini /*根据实际情况选择*/,copy文件内所有内容到my.ini文件内。

  4.  更改mysql默认字符集,这样可以让mysql默认支持中文或者其它字符集。同样在[mysqld]内增加 default-character-set=gbk 。

三.     mysql安装为服务

  1.  命令提示符下进入mysql-〉bin目录

  2.  运行命令:mysqld-nt –install

  3.  右键点击我的电脑——〉选择 管理——〉选择服务和应用程序——〉在服务中找到mysql的服务启动即可

四.     运行mysql

  1.  命令提示符下:进入mysql的bin目录下输入mysql -u root (默认用户为root)

  2.  可以安装图形化界面进行管理
   mysql front    
   下载地址:
   mysql control center 0.93
   下载地址:

trackback: http://tb.blog.csdn.net/trackback.aspx?postid=740819



芦苇 2006-12-22 16:28
]]>
open session and hibernate事务处理机制 http://www.blogjava.net/i369/articles/86994.html芦苇芦苇mon, 11 dec 2006 11:32:00 gmthttp://www.blogjava.net/i369/articles/86994.htmlhttp://www.blogjava.net/i369/comments/86994.htmlhttp://www.blogjava.net/i369/articles/86994.html#feedback0http://www.blogjava.net/i369/comments/commentrss/86994.htmlhttp://www.blogjava.net/i369/services/trackbacks/86994.html 在没有使用 spring 提供的 open session in view 情况下,因需要在 service(or dao) 层里把 session 关闭,所以 lazy loading true 的话,要在应用层内把关系集合都初始化,如 company.getemployees() ,否则 hibernate session already closed exception;     open session in view 提供了一种简便的方法,较好地解决了 lazy loading 问题 .

    它有两种配置方式opensessioninviewinterceptor opensessioninviewfilter(具体参看) ,功能相同,只是一个在 web.xml 配置,另一个在 application.xml 配置而已。

    open session in view request session 绑定到当前 thread 期间一直保持 hibernate session open 状态,使 session request 的整个期间都可以使用,如在 view 层里 po 也可以 lazy loading 数据,如 ${ company.employees } 。当 view 层逻辑完成后,才会通过 filter dofilter 方法或 interceptor posthandle 方法自动关闭 session


						
opensessioninviewinterceptor配置
  1. "opensessioninviewinterceptor"
  2. class ="org.springframework.orm.hibernate3.support.opensessioninviewinterceptor">
  3. "sessionfactory">
  4. "sessionfactory"/>
  5. "urlmapping"
  6. class ="org.springframework.web.servlet.handler.simpleurlhandlermapping">
  7. "interceptors">
  8. "opensessioninviewinterceptor"/>
  9. "mappings">
  10. ...
  11. ...
						
opensessioninviewfilter配置
  1. ...
  2. hibernatefilter
  3. org.springframework.orm.hibernate3.support.opensessioninviewfilter
  4. singlesession
  5. true
  6. ...
  7. hibernatefilter
  8. *.do
  9. ...

很多人在使用opensessioninview过程中提及一个错误:

						
  1. org.springframework.dao.invaliddataaccessapiusageexception: write operations
  2. are not allowed in read-only mode (flushmode.never) - turn your session into
  3. flushmode.auto or remove 'readonly' marker from transaction definition

看看opensessioninviewfilter里的几个方法

						
  1. protected void dofilterinternal ( httpservletrequest request,
    httpservletresponse response,filterchain filterchain)
    throws servletexception, ioexception
    {
     sessionfactory sessionfactory = lookupsessionfactory();
     logger.debug("opening hibernate session in opensessioninviewfilter");
     session session = getsession(sessionfactory);
     transactionsynchronizationmanager.bindresource
    (
      sessionfactory, new sessionholder(session));
     try
    {
      filterchain.dofilter(request, response);
     
    }
     finally
    {
     transactionsynchronizationmanager.unbindresource(sessionfactory);
     logger.debug("closing hibernate session in opensessioninviewfilter");
     closesession(session, sessionfactory);
     
    }
    }





     
  2. protected session getsession(sessionfactory sessionfactory )
    throws dataaccessresourcefailureexception
    {
     session session = sessionfactoryutils.getsession(sessionfactory, true);
     session.setflushmode(flushmode.never);
     return session;
    }

  3. protected
    void closesession ( session session, sessionfactory sessionfactory )
    throws cleanupfailuredataaccessexception
    {
     sessionfactoryutils.closesessionifnecessary(session, sessionfactory);
    }

          关于绑定session的方式,通过看spring里transactionsynchronizationmanager的实现,发现:它维护一个java.lang.threadlocal类型的resources,resources负责持有线程局部变量,这里resources持有的是一个hashmap,通过transactionsynchronizationmanager.bindresource()方法在map里绑定和线程相关的所有变量到他们的标识上,包括如上所述的绑定在sessionfactory上的线程局部session。sessionholder只不过是存放可以hold一个session并可以和transtaction同步的容器。可以看到opensessioninviewfilter在getsession的时候,会把获取回来的session的flush mode 设为flushmode.never。然后把该sessionfactory绑定到transactionsynchronizationmanager,使request的整个过程都使用同一个session,在请求过后再接除该sessionfactory的绑定,最后closesessionifnecessary根据该session是否已和transaction绑定来决定是否关闭session。绑定以后,就可以防止每次不会新开一个session呢?看看hibernatedaosupport的情况:

						
								     1.  public
								final void setsessionfactory(sessionfactory sessionfactory) {    2.      this.hibernatetemplate = new hibernatetemplate(sessionfactory);    3.  }    4.  protectedfinal hibernatetemplate gethibernatetemplate() {    5.      return hibernatetemplate;    6.  }
				

        我们的dao将使用这个template进行操作.

public abstract class basehibernateobjectdao extends hibernatedaosupport
implements baseobjectdao {
     protected baseentityobject getbyclassid(final long id) {
                baseentityobject obj =(baseentityobject) gethibernatetemplate().execute(new hibernatecallback() {
                        public object doinhibernate(session session) throws hibernateexception {
                                    return session.get(getpersistentclass(),new long(id));
                        }
                });
                return obj;
      }
     public void save(baseentityobject entity) {
                  gethibernatetemplate().saveorupdate(entity);
     }

    public void remove(baseentityobject entity) {
              try {
                     gethibernatetemplate().delete(entity);
              } catch (exception e) {
                      throw new flexenterprisedataaccessexception(e);
             }
     }

      public void refresh(final baseentityobject entity) {
               gethibernatetemplate().execute(new hibernatecallback() {
                          public object doinhibernate(session session) throws hibernateexception {
                                      session.refresh(entity);
                                      return null;
                          }
               });
      }

     public void replicate(final object entity) {
                gethibernatetemplate().execute(new hibernatecallback() {
                          public object doinhibernate(session session)throws hibernateexception {
                                      session.replicate(entity,replicationmode.overwrite);
                                      return null;
               }
                });
      }
}

        而hibernatetemplate试图每次在execute之前去获得session,执行完就力争关闭session

						
								  1. public
								object execute(hibernatecallback action) throws dataaccessexception {  2.    session session = (!this.allowcreate ?  3.          sessionfactoryutils.getsession(getsessionfactory(),   4.                false) :  5.          sessionfactoryutils.getsession(getsessionfactory(),  6.                 getentityinterceptor(),  7.                 getjdbcexceptiontranslator()));  8.     boolean existingtransaction =    9.         transactionsynchronizationmanager.hasresource(getsessionfactory());  10.    if (!existingtransaction && getflushmode() == flush_never) {  11.          session.setflushmode(flushmode.never);  12.    }  13.    try {  14.          object result = action.doinhibernate(session);  15.          flushifnecessary(session, existingtransaction);  16.          return result;  17.    }  18.    catch (hibernateexception ex) {  19.          throw converthibernateaccessexception(ex);  20.    }  21.    finally {  22.          sessionfactoryutils.closesessionifnecessary(  23.                  session, getsessionfactory());  24.    }  25. }
				

      而这个sessionfactoryutils能否得到当前的session以及closesessionifnecessary是否真正关闭session,端取决于这个session是否用sessionholder和这个sessionfactory在我们最开始提到的transactionsynchronizationmanager绑定。

     publicstaticvoidclosesessionifnecessary(session session, sessionfactory sessionfactory)

						
  1. throws cleanupfailuredataaccessexception {
  2. if ( session == null ||
    transactionsynchronizationmanager.hasresource(sessionfactory)){
  3. return ;
  4. }
  5. logger.debug("closing hibernate session");
  6. try {
  7. session.close();
  8. }
  9. catch ( jdbcexception ex){
  10. // sqlexception underneath
  11. throw new cleanupfailuredataaccessexception("could not close hibernate session", ex.getsqlexception());
  12. }
  13. catch ( hibernateexception ex){
  14. throw new cleanupfailuredataaccessexception("could not close hibernate session", ex);
  15. }
  16. }

    在这个过程中,若hibernatetemplate 发现自当前session有不是readonly的transaction,就会获取到flushmode.auto session,使方法拥有写权限。也即是,如果有不是readonly的transaction就可以由flush.never转为flush.auto,拥有insert,update,delete操作权限,如果没有transaction,并且没有另外人为地设flush model的话,则dofilter的整个过程都是flush.never。所以受transaction保护的方法有写权限,没受保护的则没有。

  1. 可能的解決方式有:
    1、将singlesession设为false,这样只要改web.xml,缺点是hibernate session的instance可能会大增,使用的jdbc connection量也会大增,如果connection pool的maxpoolsize设得太小,很容易就出问题。
    2、在控制器中自行管理session的flushmode,麻烦的是每个有modify的method都要多几行程式。
          session.setflushmode(flushmode.auto);
          session.update(user);
          session.flush();
    3、extend opensessioninviewfilter,override protected session getsession(sessionfactory sessionfactory),将flushmode直接改为auto。
    4、让方法受spring的事务控制。这就是常使用的方法:

采用spring的事务声明,使方法受transaction控制

				
  1.   class="org.springframework.transaction.interceptor.transactionproxyfactorybean"
              abstract="true">
           
           
           
               
                    propagation_required,readonly
                    propagation_required,readonly
                    propagation_required,readonly
                    propagation_required
                    propagation_required
                    propagation_required
                    propagation_required
               

           

       

  2.    
           
               
           

       

对于上例,则以save,add,update,remove开头的方法拥有可写的事务,如果当前有某个方法,如命名为importexcel(),则因没有transaction而没有写权限,这时若方法内有insert,update,delete操作的话,则需要手动设置flush model为flush.auto,如

				
  1. session.setflushmode(flushmode.auto);
  2. session.save(user);
  3. session.flush();

     尽管open session in view看起来还不错,其实副作用不少。看回上面opensessioninviewfilter的dofilterinternal方法代码,这个方法实际上是被父类的dofilter调用的,因此,我们可以大约了解的opensessioninviewfilter调用流程: request(请求)->open session并开始transaction->controller->view(jsp)->结束transaction并close session.

     一切看起来很正确,尤其是在本地开发测试的时候没出现问题,但试想下如果流程中的某一步被阻塞的话,那在这期间connection就一直被占用而不释放。最有可能被阻塞的就是在写jsp这步,一方面可能是页面内容大,response.write的时间长,另一方面可能是网速慢,服务器与用户间传输时间久。当大量这样的情况出现时,就有连接池连接不足,造成页面假死现象。

open session in view是个双刃剑,放在公网上内容多流量大的网站请慎用。

 

另外:这样会产生一点危险性,毕竟把数据库访问的环境放到了表现层。(:用vo)

 


 

 


 

 

        hibernate是对jdbc的轻量级对象封装,hibernate本身是不具备transaction处理功能的,hibernate的transaction实际上是底层的jdbc transaction的封装,或者是jta transaction的封装,下面我们详细的分析:

  hibernate可以配置为jdbctransaction或者是jtatransaction,这取决于你在hibernate.properties中的配置:

#hibernate.transaction.factory_class
net.sf.hibernate.transaction.jtatransactionfactory
#hibernate.transaction.factory_class
net.sf.hibernate.transaction.jdbctransactionfactory

  如果你什么都不配置,默认情况下使用jdbctransaction,如果你配置为:

hibernate.transaction.factory_class
net.sf.hibernate.transaction.jtatransactionfactory

  将使用jtatransaction,不管你准备让hibernate使用jdbctransaction,还是jtatransaction,我的忠告就是什么都不配,将让它保持默认状态,如下:

#hibernate.transaction.factory_class
net.sf.hibernate.transaction.jtatransactionfactory
#hibernate.transaction.factory_class
net.sf.hibernate.transaction.jdbctransactionfactory

  在下面的分析中我会给出原因。

  一、jdbc transaction

  看看使用jdbc transaction的时候我们的代码例子:

session session = sf.opensession();
transaction tx = session.begintransactioin();
...
session.flush();
tx.commit();
session.close();
  这是默认的情况,当你在代码中使用hibernate的transaction的时候实际上就是jdbctransaction。那么jdbctransaction究竟是什么东西呢?来看看源代码就清楚了:

  hibernate2.0.3源代码中的类

  net.sf.hibernate.transaction.jdbctransaction:

public void begin() throws hibernateexception {
...
if (toggleautocommit) session.connection().setautocommit(false);
...
}
  这是启动transaction的方法,看到 connection().setautocommit(false) 了吗?是不是很熟悉?

  再来看

public void commit() throws hibernateexception {
...
try {
if ( session.getflushmode()!=flushmode.never ) session.flush();
try {
session.connection().commit();
committed = true;
}
...
toggleautocommit();
}

  这是提交方法,看到connection().commit() 了吗?下面就不用我多说了,这个类代码非常简单易懂,通过阅读使我们明白hibernate的transaction都在干了些什么?我现在把用hibernate写的例子翻译成jdbc,大家就一目了然了:

connection conn = ...;               <--- session = sf.opensession();
conn.setautocommit(false);   <--- tx = session.begintransactioin();
... <--- ...
conn.commit();                           <--- tx.commit(); (对应左边的两句)
conn.setautocommit(true);
conn.close();                              <--- session.close();

  看明白了吧,hibernate的jdbctransaction根本就是conn.commit而已,根本毫无神秘可言,只不过在hibernate中,session打开的时候,就会自动conn.setautocommit(false),不像一般的jdbc,默认都是true,所以你最后不写commit也没有关系,由于hibernate已经把autocommit给关掉了,所以用hibernate的时候,你在程序中不写transaction的话,数据库根本就没有反应。 

 二、jtatransaction

如果你在ejb中使用hibernate,或者准备用jta来管理跨session的长事务,那么就需要使用jtatransaction,先看一个例子:

javax.transaction.usertransaction tx = new initialcontext().lookup("javax.transaction.usertransaction");

session s1 = sf.opensession();
...
s1.flush();
s1.close();
...

session s2 = sf.opensession();
...
s2.flush();
s2.close();

tx.commit();


这是标准的使用jta的代码片断,transaction是跨session的,它的生命周期比session要长。如果你在ejb中使用hibernate,那么是最简单不过的了,你什么transaction代码统统都不要写了,直接在ejb的部署描述符上配置某某方法是否使用事务就可以了。

现在我们来分析一下jtatransaction的源代码, net.sf.hibernate.transaction.jtatransaction:

public void begin(initialcontext context, ...
...
ut = (usertransaction) context.lookup(utname);
...


看清楚了吗? 和我上面写的代码 tx = new initial context?().lookup("javax.transaction.usertransaction"); 是不是完全一样?

public void commit() ...
...
if (newtransaction) ut.commit();
...


jtatransaction的控制稍微复杂,不过仍然可以很清楚的看出来hibernate是如何封装jta的transaction代码的。

但是你现在是否看到了什么问题? 仔细想一下,hibernate transaction是从session中获得的,tx = session.begintransaction(),最后要先提交tx,然后再session.close,这完全符合jdbc的transaction的操作顺序,但是这个顺序是和jta的transactioin操作顺序彻底矛盾的!!! jta是先启动transaction,然后启动session,关闭session,最后提交transaction,因此当你使用jta的transaction的时候,那么就千万不要使用hibernate的transaction,而是应该像我上面的jta的代码片断那样使用才行。

总结:
1、在jdbc上使用hibernate

必须写上hibernate transaction代码,否则数据库没有反应。此时hibernate的transaction就是connection.commit而已

2、在jta上使用hibernate

写jta的transaction代码,不要写hibernate的transaction代码,否则程序会报错

3、在ejb上使用hibernate

什么transactioin代码都不要写,在ejb的部署描述符里面配置

|---cmt(container managed transaction)
|
|---bmt(bean managed transaction)
|
|----jdbc transaction
|
|----jta transaction

 


 

 


 

关于session:

1.  servlet的session机制基于cookies,关闭浏览器的cookies则session失效即不能用网站的登录功能。

2.  hibernate session.

      1>. session 清理缓存时,按照以下顺序执行sql语句:

            session.save()的实体insert                                                                                                                                         

            实体的update

            对 集合的delete

            集合元素的delete,update,insert

            集合的insert

            session.delete()的先后,执行实体的delete

       2>. 默认时,session在以下时间点清理缓存:

              net.sf.hibernate.transaction.commit():先清理缓存,再向数据库提交事务                                                          

              session.find()或iterate()时,若缓存中持久化对象的属性发生了变化,就会先清缓存,以保证查询结果正确

 

       3>.  session的commit()和flush()的区别:flush()只执行sql语句,不提交事务;commit()先调用flush(),再提交事务

       4>.  session.setflushmode()用于设定清理缓存的时间点。

清理缓存的模式 session的查询方法 session.commit() session.flush()
flushmode.auto 清理 清理 清理
flushmode.commit 不清理 清理 清理
flushmode.never 不清理 不清理 清理

           



trackback: http://tb.blog.csdn.net/trackback.aspx?postid=797399



芦苇 2006-12-11 19:32
]]>
开源数据库逐个数http://www.blogjava.net/i369/articles/86061.html芦苇芦苇thu, 07 dec 2006 04:04:00 gmthttp://www.blogjava.net/i369/articles/86061.htmlhttp://www.blogjava.net/i369/comments/86061.htmlhttp://www.blogjava.net/i369/articles/86061.html#feedback0http://www.blogjava.net/i369/comments/commentrss/86061.htmlhttp://www.blogjava.net/i369/services/trackbacks/86061.html编辑导语

开源数据库最初的诞生和发展大都依靠自由软件开发者,但是,现在越来越多的it公司开始把触角伸向了开源数据库。而早期投身于其中的it厂商早已获利,比如sleepycat公司从1996年就开始盈利,收入来源主要是向使用其产品的软件商收取年费。  而最为成功的开源数据库公司则是mysql。其2002年的销售收入就已达到500万美元,2003年更是达到1200万美元。较商业化的开源数据库有:sqlite、simplesql、berkely db、minosse、firebird( 前身是是borland公司的interbase)、postgresql、mysql等。下面我们对这几个数据库一一介绍。[编辑:张耀宏]

blogjava-凯发k8网页登录

mysql是一个遵循gpl的开源软件、在linux平台底下它是lamp组合重要组成部分(lamp 在英语中是“灯”的意思,但是在 it 行业当然不是那么简单的一个意思了。这个术语在德国十分流行。代表了 linux 平台上的 apache 网站服务器;mysql 数据库以及 perl 、python 或者 php 编程语言的结合)。

postgres数据库的后开源版本,号称拥有任何其他数据库没有的大量新特性,似乎目标是要做超大型的oo关系型数据库系统,目前已经发展到8.2,有.net驱动,中文官方网站有详细介绍。

firebird脱胎于borland公司的开源版数据库interbase6.0,是一个完全非商业化的产品,用c和c 开发。由于与interbase的血缘关系,大部分interbase的开发工具可以直接应用到firebird开发中。完全支持ansi sql92、98等,有3种模式,单机独立,典型c/s,超级服务器。

c 编写的大型关系型数据库系统,还额外地支持xml(把xml当成数据库),号称2百万的安装量,mysql也只不过号称5百万安装量而已,跨平台。你可以把他用于嵌入式的设备呀,他的体积非常小,完全能哆胜任任何关于数据操作的要求。

simplesql是一个64位的关系型数据库,一个标准的服务端免费的数据库组件,具有符合sql 和 jdbc标准的事务性数据库服务器,具有轻便型的单数据库文件,第一个数据库的开发语言是java和c 。

sqlite 一个轻量级别数据库, 具有很多不错的特点。最新版本:3.3.6 支持事件,不需要配置,不需要安装,也不需要管理员 支持大部分sql92,一个完整的数据库保存在磁盘上面一个文件同一个数据库文件可以在不同机器上面使用,最大支持数据库到2t,字符和blob的支持仅限制于可用内存 整个系统少于3万行代码,少于250kb的内存占用(gcc) ,大部分应用比目前常见的客户端/服务端的数据库快没有其它依赖 源代码开放, 代码95%有较好的注释

纯c#编写的大型关系型数据库系统,理想是超越ms sql server!最新版本:0.2.0,真难得,纯java写的看得多了,纯c#的,不是移植别人的,还是第一个,佩服作者:包含c/s和嵌入式版本,并可跨越大部分平台,因为它不用windows的东西,可以在mono下编译。

轻型数据库sqlite结合php的开发 sqlite是一款轻型的数据库,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百k的内存就够了。
作者:zieckey( zieckey@yahoo.com.cn ) all rights reserved! 一. 编译动态链接库库文件下面的是我的编译过程,或许对你有些帮助: 1). 打开vc新建一个“win32 dynamic-link library”工程,命名为:sqlite32).
firebird database (快速入门) 参考文件(均可自firebird网站找到):novice's guidemigration from ms-sql to firebird firebord release notes 学习数据库基础是在sql的语法应用
我有个朋友曾经感叹,firebird最需要的是一个好的管理工具。从interbase 6.0到 firebird1.5,我一直用的是sql脚本加marathon。客观的说,这是一个非常优秀的admin tool,但是,marathon却有几个无法回避的问题
开源就像一辆载满货物疾驰而来的火车无法停下来,虽然微软可能很希望它能停下来。lamp(一个linux操作系统,一个apache web服务器,一个mysql数据库,和一个脚本语言php)的体系结构可用于某些需要满足某些关键条件的数据库应用程序和系统。
随着compiere、sugarcrm、plone以及asterisk的崛起,一波新的开源风潮正在向业界逼近。开源软件不再是玩物,开源也不再只是一件无利可图的事情。
人们经常说开源没有创新,而是模仿。这肯定是专有软件行业希望你相信的。看一看目前企业中使用的一些最著名的开源项目中的活动,让你不由得不同意。


芦苇 2006-12-07 12:04
]]>
语法错误或存取规则违规http://www.blogjava.net/i369/articles/80508.html芦苇芦苇fri, 10 nov 2006 14:48:00 gmthttp://www.blogjava.net/i369/articles/80508.htmlhttp://www.blogjava.net/i369/comments/80508.htmlhttp://www.blogjava.net/i369/articles/80508.html#feedback0http://www.blogjava.net/i369/comments/commentrss/80508.htmlhttp://www.blogjava.net/i369/services/trackbacks/80508.html阅读全文

芦苇 2006-11-10 22:48
]]>
db2结果集返回前n行http://www.blogjava.net/i369/articles/80494.html芦苇芦苇fri, 10 nov 2006 13:40:00 gmthttp://www.blogjava.net/i369/articles/80494.htmlhttp://www.blogjava.net/i369/comments/80494.htmlhttp://www.blogjava.net/i369/articles/80494.html#feedback0http://www.blogjava.net/i369/comments/commentrss/80494.htmlhttp://www.blogjava.net/i369/services/trackbacks/80494.html


select * from table1 fetch first n rows only







芦苇 2006-11-10 21:40
]]>
取當前日期各种數据庫的寫法[转]http://www.blogjava.net/i369/articles/80493.html芦苇芦苇fri, 10 nov 2006 13:38:00 gmthttp://www.blogjava.net/i369/articles/80493.htmlhttp://www.blogjava.net/i369/comments/80493.htmlhttp://www.blogjava.net/i369/articles/80493.html#feedback0http://www.blogjava.net/i369/comments/commentrss/80493.htmlhttp://www.blogjava.net/i369/services/trackbacks/80493.html http://www.chinaunix.net 作者:  发表于:2003-09-30 11:31:08 【】【】【】【】

取當前日期各种數据庫的寫法 
1. oracle 
select sysdate from dual 
2. db2 
select current timestamp from sysibm.sysdummy1 
3. informix 
select today from table 
4. sqlserver 
select getdate() from table 
5. sqlserver 
select getdate() from table 
6. mysql 
mysql>; select now(); 
mysql>; select sysdate(); 
mysql>; select curdate(); 
mysql>; select current_date; 
mysql>; select curtime(); 
mysql>; select current_time; 
7. foxpro 
select date() from table

歡迎大家補充!


芦苇 2006-11-10 21:38
]]>
db2 常用命令大全http://www.blogjava.net/i369/articles/80492.html芦苇芦苇fri, 10 nov 2006 13:36:00 gmthttp://www.blogjava.net/i369/articles/80492.htmlhttp://www.blogjava.net/i369/comments/80492.htmlhttp://www.blogjava.net/i369/articles/80492.html#feedback0http://www.blogjava.net/i369/comments/commentrss/80492.htmlhttp://www.blogjava.net/i369/services/trackbacks/80492.html


  1. 建立数据库db2_gcb 



  create database db2_gcb on g: alias db2_gcb 

  using codeset gbk territory cn collate using system dft_extent_sz 32 



  2. 连接数据库 



  connect to sample1 user db2admin using 8301206 



  3. 建立别名 



  create alias db2admin.tables for sysstat.tables; 

  create alias db2admin.views for syscat.views 

  create alias db2admin.columns for syscat.columns; 

  create alias guest.columns for syscat.columns; 



  4. 建立表 



  create table zjt_tables as 

  (select * from tables) definition only; 

  create table zjt_views as 

  (select * from views) definition only; 



  5. 插入记录 



  insert into zjt_tables select * from tables; 

  insert into zjt_views select * from views; 



  6. 建立视图 



  create view v_zjt_tables as select tabschema,tabname from zjt_tables; 


    7. 建立触发器 



  create trigger zjt_tables_del 

  after delete on zjt_tables 

  referencing old as o 

  for each row mode db2sql 

  insert into zjt_tables1 values(substr(o.tabschema,1,8),substr(o.tabname,1,10)) 



  8. 建立唯一性索引 



  create unique index i_ztables_tabname 

  on zjt_tables(tabname); 

  9. 查看表 



  select tabname from tables 

  where tabname='zjt_tables'; 



  10. 查看列 



  select substr(colname,1,20) as 列名,typename as 类型,length as 长度 

  from columns 

  where tabname='zjt_tables'; 



  11. 查看表结构 



  db2 describe table user1.department 

  db2 describe select * from user.tables 



  12. 查看表的索引 



  db2 describe indexes for table user1.department 



  13. 查看视图 



  select viewname from views 

  where viewname='v_zjt_tables'; 



  14. 查看索引 



  select indname from indexes 

  where indname='i_ztables_tabname'; 



15. 查看存贮过程 



  select substr(procschema,1,15),substr(procname,1,15) 

  from syscat.procedures; 



  16. 类型转换(cast) 



  ip datatype:varchar 

  select cast(ip as integer) 50 from log_comm_failed 



  17. 重新连接 



  connect reset 



  18. 中断数据库连接 



  disconnect db2_gcb 



  19. view application 



  list application; 



  20. kill application 



  force application(0); 

  db2 force applications all (强迫所有应用程序从数据库断开) 



  21. lock table



  lock table test in exclusive mode 



  22. 共享 



  lock table test in share mode 



  23. 显示当前用户所有表 



  list tables 



  24. 列出所有的系统表 



  list tables for system 



 25. 显示当前活动数据库 



  list active databases 



  26. 查看命令选项 



  list command options 





  27. 系统数据库目录 



  list database directory 



  28. 表空间 



  list tablespaces 



  29. 表空间容器 



  list tablespace containers for 

  example: list tablespace containers for 1 



  30. 显示用户数据库的存取权限 



  get authorizations 





  31. 启动实例 



  db2start 



  32. 停止实例 



  db2stop 



  33. 表或视图特权 



  grant select,delete,insert,update on tables to user 

  grant all on tables to user with grant option 



  34. 程序包特权 



  grant execute 

  on package package-name 

  to public 



35. 模式特权 



  grant createin on schema schema-name to user 



  36. 数据库特权 



  grant connect,createtab,dbadm on database to user 



  37. 索引特权 



  grant control on index index-name to user 



  38. 信息帮助 (? xxxnnnnn ) 



  例:? sql30081 



  39. sql 帮助(说明 sql 语句的语法) 



  help statement 

  例如,help select 



  40. sqlstate 帮助(说明 sql 的状态和类别代码) 



  ? sqlstate 或 ? class-code 



  41. 更改与"管理服务器"相关的口令 



  db2admin setid username password 



  42. 创建 sample 数据库 



  db2sampl 

  db2sampl f:(指定安装盘) 



  43. 使用操作系统命令 



  ! dir 



  44. 转换数据类型 (cast) 



  select empno, cast(resume as varchar(370)) 

  from emp_resume 

  where resume_format = 'ascii' 

45. udf



  要运行 db2 java 存储过程或 udf,还需要更新服务器上的 db2 数据库管理程序配置,以包括在该机器上安装 jdk 的路径 



  db2 update dbm cfg using jdk11_path d:\sqllib\java\jdk 

  terminate 

  update dbm cfg using spm_name sample 



  46. 检查 db2 数据库管理程序配置 



  db2 get dbm cfg 



  47. 检索具有特权的所有授权名 



  select distinct grantee, granteetype, 'database' from syscat.dbauth 

  union 

  select distinct grantee, granteetype, 'table ' from syscat.tabauth 

  union 

  select distinct grantee, granteetype, 'package ' from syscat.packageauth 

  union 

  select distinct grantee, granteetype, 'index ' from syscat.indexauth 

  union 

  select distinct grantee, granteetype, 'column ' from syscat.colauth 

  union 

  select distinct grantee, granteetype, 'schema ' from syscat.schemaauth 

  union 

  select distinct grantee, granteetype, 'server ' from syscat.passthruauth 

  order by grantee, granteetype, 3 



  create table yhdab 

  (id varchar(10), 

  password varchar(10), 

  ywlx varchar(10), 

  kh varchar(10)); 

  create table ywlbb 

  (ywlbbh varchar(8), 

  ywmc varchar(60)) 



48. 修改表结构 



  alter table yhdab alter kh set data type varchar(13); 

  alter table yhdab alter id set data type varchar(13); 

  alter table lst_bsi alter bsi_money set data type int; 

  insert into yhdab values 

  ('20000300001','123456','user01','20000300001'), 

  ('20000300002','123456','user02','20000300002'); 



  49. 业务类型说明 



  insert into ywlbb values 

  ('user01','业务申请'), 

  ('user02','业务撤消'), 

  ('user03','费用查询'), 

  ('user04','费用自缴'), 

  ('user05','费用预存'), 

  ('user06','密码修改'), 

  ('user07','发票打印'), 

  ('gl01','改用户基本信息'), 

  ('gl02','更改支付信息'), 

  ('gl03','日统计功能'), 

  ('gl04','冲帐功能'), 

  ('gl05','对帐功能'), 

  ('gl06','计费功能'), 

  ('gl07','综合统计')



  二. 目录视图说明



说明 目录视图 

检查约束 syscat.checks 

列   syscat.columns 

检查约束引用的列 syscat.colchecks  

关键字中使用的列   syscat.keycoluse  

数据类型   syscat.datatypes  

函数参数或函数结果   syscat.funcparms  

参考约束   syscat.references  

模式  syscat.schemata  

表约束   syscat.tabconst  

表   syscat.tables  

触发器   syscat.triggers  

用户定义函数  syscat.functions  

视图   syscat.views  



三. 字符串类型



  二进制大对象 (blob) 字符串。 

  字符大对象 (clob) 字符串,它的字符序列可以是单字节字符或多字节字符,或这两者的组合。 

  双字节字符大对象 (dbclob) 字符串,它的字符序列是双字节字符。 



  四. 数据库范式



  第一种规范形式:表中的每一行和每一列均有一个值,永远不会是一组值。 

  第二种规范形式:不在关键字中的每一列提供取决于整个关键字的事实。 

  第三种规范形式:每个非关键字列提供与其他非关键字列无关并只取决于该关键字的事实。 

  第四种规范形式:没有行包含有关一个实体的两个或更多个独立的多值事实。 



  五. 数据类型



数据类型  类型   特性   示例或范围 

char(15)  定长字符串  最大长度为 254    'sunny day ' 

varchar(15)  变长字符  最大长度为 4000    'sunny day' 

smallint   数字  长度为 2 字节精度为 5 位  范围为-32768 至 32767 

integer   数字  长度为 4 字节精度为 10 位  范围为-2147483648 至 2147483647 

real   数字  单精度浮点32 位近似值   范围为-3.402e 38至-1.175e-37或 1.175e-37 至-3.402e 38或零 

double   数字  双精度浮点64 位近似值  范围为-1.79769e 308 至-2.225e-307或 2.225e-307 至 1.79769e 308或零 

decimal(5,2)  数字  精度为 5小数位为 2  范围为 -10**31 1 至 10**31-1 

date  日期时间   三部分值  1991-10-27    

time  日期时间   三部分值  13.30.05    

timestamp  日期时间   七部分值    1991-10-27-13.30.05.000000 





六. 列函数 



  列函数对列中的一组值进行运算以得到单个结果值。下列就是一些列函数的示例。 



  avg 



  返回某一组中的值除以该组中值的个数的和 



  count 



  返回一组行或值中行或值的个数 



  max 



  返回一组值中的最大值 



  min 



  返回一组值中的最小值 



  七. 标量函数 



  标量函数对值进行某个运算以返回另一个值。下列就是一些由db2 通用数据库提供的标量函数的示例。 



  abs 



  返回数的绝对值 



  hex 



  返回值的十六进制表示 



  length 



  返回自变量中的字节数(对于图形字符串则返回双字节字符数。) 



  year 



  抽取日期时间值的年份部分 


芦苇 2006-11-10 21:36
]]>
自写脚本,让db2命令行安装变得更轻松 http://www.blogjava.net/i369/articles/80489.html芦苇芦苇fri, 10 nov 2006 13:32:00 gmthttp://www.blogjava.net/i369/articles/80489.htmlhttp://www.blogjava.net/i369/comments/80489.htmlhttp://www.blogjava.net/i369/articles/80489.html#feedback0http://www.blogjava.net/i369/comments/commentrss/80489.htmlhttp://www.blogjava.net/i369/services/trackbacks/80489.html  在linux平台下db2 udb v8.1提供了命令行和图形界面两种安装方式,图形界面虽然通过交互简化了安装的复杂性,但安装过程需要人工干预,耗时相对较长,并且在内核较新的linux版本下还存在无法启动gui安装界面的问题,虽然可以通过设置环境变量进行解决,还是显得有些麻烦。

  当然如果你用命令行方式手动安装就不存在这个问题,不过需要手动完成很多步骤,如果安装或卸载比较频繁的情况下,就不如把整个安装过程写入shell脚本执行方便。

  下面是我完成的一个用于安装和卸载的shell脚本,在数据库安装时,只需指定安装文件的源路径,即可完成全部安装。包括创建必要的用户和组,创建das服务以及实例,在系统注册服务名和服务端口,设置注册表变量,设置自动启动等。

  另外可以通过三个可选的参数指定忽略拷贝安装文件,或者忽略创建用户或者组,以节约安装时间。

  卸载功能可以用于卸载使用本安装脚本安装的数据库,包括删除实例和das服务,清除前面创建的用户和组,恢复系统的配置文件等,可通过可选的参数指定同时删除安装时拷贝的package文件。
  
  在脚本的开始部分,有一些参数可以自行根据实际环境修改,比如要创建的实例名、用于das的用户名及组名、数据库的默认建立路径等,在使用本脚本之前可以先进行修改。

  将本脚本保存为文件,本例存为instdb.sh,添加可执行属性,在root权限下运行,例如:

  使用源路径'/mnt/db2udb8forlinux' 进行安装;

# ./instdb2 -d /mnt/db2udb8forlinux

  删除已经进行的db2安装,同时删除所有已经拷贝到安装目录的package文件。

# ./instdb2 -d /mnt/db2udb8forlinux -remove -all

  本文中脚本在如下环境测试通过:redhat enterprise linux 3.0、db2 v8.1 for linux

  参考资源

  ibm db2 开发者园地
  

  ibm db2 信息中心
  

  《db2 udb v8.1 for linux, unix, windows 数据库管理》george baklarz, bill wong 合著,机械工业出版社出版

  《db2数据库管理与应用教程》庄济诚 著,清华大学出版社出版



芦苇 2006-11-10 21:32
]]>
sql server与oracle、db2的比较 http://www.blogjava.net/i369/articles/80490.html芦苇芦苇fri, 10 nov 2006 13:32:00 gmthttp://www.blogjava.net/i369/articles/80490.htmlhttp://www.blogjava.net/i369/comments/80490.htmlhttp://www.blogjava.net/i369/articles/80490.html#feedback0http://www.blogjava.net/i369/comments/commentrss/80490.htmlhttp://www.blogjava.net/i369/services/trackbacks/80490.html开放性   sql server
  只能在windows 上运行,没有丝毫的开放性,操作系统的系统的稳定对数据库是十分重要的。windows9x系列产品是偏重于桌面应用,nt server只适合中小型企业。而且windows平台的可靠性,安全性和伸缩性是非常有限的。它不象unix那样久经考验,尤其是在处理大数据量的关键业务时。
  oracle
  能在所有主流平台上运行(包括 windows)。完全支持所有的工业标准。采用完全开放策略。可以使客户选择最适合的凯发天生赢家一触即发官网的解决方案。对开发商全力支持。
  db2
  能在所有主流平台上运行(包括windows)。最适于海量数据。db2在企业级的应用最为广泛,在全球的500家最大的企业中,几乎85%以上用db2数据库服务器,而国内到97年约占5%。

  可伸缩性,并行性   sql server
  并行实施和共存模型并不成熟。很难处理日益增多的用户数和数据卷。伸缩性有限。oracle
平行服务器通过使一组结点共享同一簇中的工作来扩展window nt的能力,提供高可用性和高伸缩性的簇的凯发天生赢家一触即发官网的解决方案。如果windowsnt不能满足需要, 用户可以把数据库移到unix中。
  db2
  db2具有很好的并行性。db2把数据库管理扩充到了并行的、多节点的环境。数据库分区是数据库的一部分,包含自己的数据、索引、配置文件、和事务日志。数据库分区有时被称为节点或数据库节点。

  安全性
  sql server
  没有获得任何安全证书。
  oracle server
  获得最高认证级别的iso标准认证。
  db2
  获得最高认证级别的iso标准认证。

  性能
  sql server
  多用户时性能不佳
  oracle
  性能最高, 保持windowsnt下的tpc-d和tpc-c的世界记录。
  db2
  适用于数据仓库和在线事物处理,性能较高。

  客户端支持及应用模式
  sql server
  c/s结构,只支持windows客户,可以用ado,dao,oledb,odbc连接。
  oracle
  多层次网络计算,支持多种工业标准,可以用odbc,jdbc,oci等网络客户连接。
  db2
  跨平台,多层结构,支持odbc,jdbc等客户。

  操作简便
  sql server
  操作简单,但只有图形界面。
  oracle
  较复杂, 同时提供gui和命令行,在windows nt和unix下操作相同。
  db2
  操作简单,同时提供gui和命令行,在windows nt和unix下操作相同。

  使用风险

  sql server
  完全重写的代码,经历了长期的测试,不断延迟,许多功能需要时间来证明。并不十分兼容早期产品。使用需要冒一定风险。
  oracle
  长时间的开发经验,完全向下兼容。得到广泛的应用。完全没有风险。
  db2
  在巨型企业得到广泛的应用,向下兼容性好。风险小。



芦苇 2006-11-10 21:32
]]>
关于ibm db2 数据库的使用小技巧小结http://www.blogjava.net/i369/articles/80488.html芦苇芦苇fri, 10 nov 2006 13:27:00 gmthttp://www.blogjava.net/i369/articles/80488.htmlhttp://www.blogjava.net/i369/comments/80488.htmlhttp://www.blogjava.net/i369/articles/80488.html#feedback0http://www.blogjava.net/i369/comments/commentrss/80488.htmlhttp://www.blogjava.net/i369/services/trackbacks/80488.html1. 查看本地节点目录

命令窗口中输入: list node directory

2. 编目一个tcp/ip节点

命令窗口:db2 catalog tcpip node remote server ostype

3. 取消节点编目

db2 uncatalog node

4. 查看系统目录

db2 list database directory

5. 查看本地数据库目录

db2 list database directory on <盘符>

在本地数据库目录中有而系统数据库目录中没有的数据库不能访问,可以在控制中心中选中<数据库>右键单击选择添加,然后输入需要添加的数据库名称或者点击刷新按钮选择数据库,加入数据库后即可以访问。

6. 编目数据库

db2 catalog database as at node

7. 取消数据库编目

db2 uncatalog database

8. 测试远程数据库的连接

db2 connect to user using

9. 设置默认模式

任何用户均可通过设置current schema专用寄存器为特定的数据库连接设置默认模式,初始默认值为当前会话用户的权限id。

set schema =

可以由用户交互式的使用,也可在应用程序中使用,如果用dynamicrules bind选项绑定包,这个语句就没有作用。此语句不在事务控制之下。

10. 代码页的设置

在创建数据库时设置字符集

create database using codeset territory

例:

create database dbtest using codeset ibm-437 territory us

也可以设置整个数据库的代码页,在win2000/nt/xp中,在我的电脑-->属性-->高级-->环境变量中添加变量db2codepage = ,例:db2codepage = 437 或 db2codepage = 1386。或者在ibm db2命令窗口输入 db2set db2codepage=1386,设置后需要重新启动db2生效。

11. db2低版本数据到高版本的迁移

先将低版本数据备份使用恢复功能导入高版本数据库,然后在命令窗口输入 db2 migrate database 。

12. 表名或模式中含有引号时访问表

命令窗口:db2 select * from "tabschema"."tabname"

命令行处理器:db2=> select * from "tabschema"."tabname"

13. 导出数据库的表结构生成ddl文件

命令窗口:db2look -d -e -c -o

14. 执行脚本文件

命令窗口:db2 -tvf

15. 代码页的转换

16. 获取当前db2的版本

select * from sysibm.sysversions

17. db2表的字段的修改限制?

只能修改varchar2类型的并且只能增加不能减少

alter table alter column set data type varchar(size)

18. 如何查看表的结构?

describe table

or

describe select * from .

19. 如何快速清除一个大表?

alter table table_name active not logged initally with empty table

20. 如何查看数据库的存储过程?

select * from syscat.pocedures

21. 如何查看表的约束?

select * from syscat.checks where tabname =

22. 如何查看表的引用完整约束?

select * from syscat.references where tabname =

23. 如何知道buffools状况?

select * from syscat.bufferpools

24. 如何在命令行下查看修改实例和数据库配置参数?

查看实例配置参数: db2 get dbm cfg

修改实例配置参数: db2 update dbm cfg using 参数名 新值

查看数据库配置参数: db2 get db cfg for

修改数据库配置参数: db2 update db cfg for using 参数名 新值

25. 如何修改缓冲区?

增加缓冲区: create bufferpool size [pagesize 4096] {[not] extended storage}

修改缓冲区: alter bufferpool size {[not] extended storage}

删除缓冲区: drop bufferpool

如果缓冲区大小设置为 -1 表示缓冲池的页面数目由数据库配置参数buffpage决定。

注意: 数据库配置参数buffpage仅对缓冲区大小设置为 -1 的缓冲池起作用。

26. 多个字段时如何不通过使用select子句使用in/not in

select * from tabschema.tabname where (cola, colb, colc) [not] in (values (valuea1, valueb1, valuec1), (valuea2, valueb2, valuec2), ...(valuean, valuebn, valuecn))

27. 查看当前连接到数据库的应用

db2 list application [show detail]

28. 如何确认db2数据库的一致性

db2dart /db

/db表示检查整个数据库的一致性

29. 测试sql语句的性能

db2batch -d -f [-a userid/passwd] [-r ]

-r 选项表示将查询结果输出到一个文件中。

30. 导出某个表的数据

export to

如:导出用户表

export to c:user.ixf of ixf select * from user

31. 导入数据

import from

:导入用户表。导入时可以直接建立新表。如果有该表存在也可以用insert 插入,或者用update更新

import from c:user.ixf of ixf [create/insert into / update] tablename



芦苇 2006-11-10 21:27
]]>
网站地图