新的起点

新的起点
随笔 - 9, 文章 - 1, 评论 - 1, 引用 - 0
数据加载中……

2008年1月6日

Oracle常用及非常用函数详解

转载自:http://wangyu.javaeye.com/blog/192292

感于总有些网友提出一些非常基础的问题,比如有没有实现某某功能的函数啊,某某函数是做什么用的啊,格式是什么等等,同时也感受到自己对oracle函数认识的不足,于是集中月余时间专注于oracle函数,小有心得不敢私藏,发之与诸公共享。

本文并不准备介绍全部的oracle函数,当前情势下,俺也还没这个时间,需要学习的东西太多了,要把多数时间花在学习经常能用上的技术方面:),所以如果是准备深入了解所有oracle函数的朋友,还是去关注:Oracle SQL Reference官方文档更靠谱一些。

本文更多将会介绍三思在日常中经常会用到的,或者虽然很少用到,但是感觉挺有意思的一些函数。分二类介绍,分别是:
著名函数篇 -经常用到的函数
非著名函数篇-即虽然很少用到,但某些情况下却很实用

注:N表示数字型,C表示字符型,D表示日期型,[]表示内中参数可被忽略,fmt表示格式。

单值函数在查询中返回单个值,可被应用到select,where子句,start with以及connect by 子句和having子句。
(一).数值型函数(Number Functions)
数值型函数输入数字型参数并返回数值型的值。多数该类函数的返回值支持38位小数点,诸如:COS, COSH, EXP, LN, LOG, SIN, SINH, SQRT, TAN, and TANH 支持36位小数点。ACOS, ASIN, ATAN, and ATAN2支持30位小数点。

1、MOD(n1,n2) 返回n1除n2的余数,如果n2=0则返回n1的值。
    例如:SELECT MOD(24,5) FROM DUAL;

2、 ROUND(n1[,n2]) 返回四舍五入小数点右边n2位后n1的值,n2缺省值为0,如果n2为负数就舍入到小数点左边相应的位上(虽然oracle documents上提到n2的值必须为整数,事实上执行时此处的判断并不严谨,即使n2为非整数,它也会自动将n2取整后做处理,但是我文档中其它提到必须为整的地方需要特别注意,如果不为整执行时会报错的)。
例如:SELECT ROUND(23.56),ROUND(23.56,1),ROUND(23.56,-1) FROM DUAL;

3、TRUNC(n1[,n2] 返回截尾到n2位小数的n1的值,n2缺省设置为0,当n2为缺省设置时会将n1截尾为整数,如果n2为负值,就截尾在小数点左边相应的位上。
例如:SELECT TRUNC(23.56),TRUNC(23.56,1),TRUNC(23.56,-1) FROM DUAL;

(二).字符型函数返回字符值(Character Functions Returning Character Values)
该类函数返回与输入类型相同的类型。
返回的CHAR类型值长度不超过2000字节;
返回的VCHAR2类型值长度不超过4000字节;
如果上述应返回的字符长度超出,oracle并不会报错而是直接截断至最大可支持长度返回。

返回的CLOB类型值长度不超过4G;
对于CLOB类型的函数,如果返回值长度超出,oracle不会返回任何错误而是直接抛出错误。

1、LOWER(c) 将指定字符串内字符变为小写,支持CHAR,VARCHAR2,NCHAR,NVARCHAR2,CLOB,NCLOB类型
    例如:SELECT LOWER('WhaT is tHis') FROM DUAL;

2、UPPER(c) 将指定字符串内字符变为大写,支持CHAR,VARCHAR2,NCHAR,NVARCHAR2,CLOB,NCLOB类型
    例如:SELECT UPPER('WhaT is tHis') FROM DUAL;

3、LPAD(c1,n[,c2]) 返回指定长度=n的字符串,需要注意的有几点:
如果n<c1.length则从右到左截取指定长度返回;
如果n>c1.length and c2 is null,以空格从左向右补充字符长度至n并返回;
如果n>c1.length and c2 is not null,以指定字符c2从左向右补充c1长度至n并返回;
例如:SELECT LPAD('WhaT is tHis',5),LPAD('WhaT is tHis',25),LPAD('WhaT is tHis',25,'-') FROM DUAL;
最后大家再猜一猜,如果n<0,结果会怎么样

4、RPAD(c1,n[,c2]) 返回指定长度=n的字符串,基本与上同,不过补充字符是从右向左方向正好与上相反;
    例如:SELECT RPAD('WhaT is tHis',5),RPAD('WhaT is tHis',25),RPAD('WhaT is tHis',25,'-') FROM DUAL;

5、TRIM([[LEADING||TRAILING||BOTH] c2 FROM] c1) 哈哈,被俺无敌的形容方式搞晕头了吧,这个地方还是看图更明了一些。
看起来很复杂,理解起来很简单:
如果没有指定任何参数则oracle去除c1头尾空格
例如:SELECT TRIM(' WhaT is tHis ') FROM DUAL;
如果指定了c2参数,则oracle去掉c1头尾c2(这个建议细致测试,有多种不同情形的哟)
例如:SELECT TRIM('W' FROM 'WhaT is tHis w W') FROM DUAL;
如果指定了leading参数则会去掉c1头部c2
例如:SELECT TRIM(leading 'W' FROM 'WhaT is tHis w W') FROM DUAL;
如果指定了trailing参数则会去掉c1尾部c2
例如:SELECT TRIM(trailing 'W' FROM 'WhaT is tHis w W') FROM DUAL;
如果指定了both参数则会去掉c1头尾c2(跟不指定有区别吗?没区别!)
例如:SELECT TRIM(both 'W' FROM 'WhaT is tHis w W') FROM DUAL;
注意:c2长度=1

6、LTRIM(c1[,c2]) 千万表以为与上面那个长的像,功能也与上面的类似,本函数是从字符串c1左侧截取掉与指定字符串c2相同的字符并返回。如果c2为空则默认截取空格。
例如:SELECT LTRIM('WWhhhhhaT is tHis w W','Wh') FROM DUAL;

7、RTRIM(c1,c2)与上同,不过方向相反
    例如:SELECT RTRIM('WWhhhhhaT is tHis w W','W w') FROM DUAL;

8、REPLACE(c1,c2[,c3]) 将c1字符串中的c2替换为c3,如果c3为空,则从c1中删除所有c2。
    例如:SELECT REPLACE('WWhhhhhaT is tHis w W','W','-') FROM DUAL;

9、SOUNDEX(c) 神奇的函数啊,该函数返回字符串参数的语音表示形式,对于比较一些读音相同,但是拼写不同的单词非常有用。计算语音的算法如下:
保留字符串首字母,但删除a、e、h、i、o、w、y。
将下表中的数字赋给相对应的字母:
1:b、f、p、v
2:c、g、k、q、s、x、z
3:d、t
4:l
5:m、n
6:R
如果字符串中存在拥有相同数字的2个以上(包含2个)的字母在一起(例如b和f),或者只有h或w,则删除其他的,只保留1个;
只返回前4个字节,不够用0填充
例如:SELECT SOUNDEX('dog'),soundex('boy') FROM DUAL;

10、SUBSTR(c1,n1[,n2]) 截取指定长度的字符串。稍不注意就可能充满了陷阱的函数。
n1=开始长度;
n2=截取的字符串长度,如果为空,默认截取到字符串结尾;
 如果n1=0 then n1=1
 如果n1>0,则oracle从左向右确认起始位置截取
例如:SELECT SUBSTR('What is this',5,3) FROM DUAL;
 如果n1<0,则oracle从右向左数确认起始位置
例如:SELECT SUBSTR('What is this',-5,3) FROM DUAL;
 如果n1>c1.length则返回空
例如:SELECT SUBSTR('What is this',50,3) FROM DUAL;
然后再请你猜猜,如果n2<1,会如何返回值呢

11、 TRANSLATE(c1,c2,c3) 就功能而言,此函数与replace有些相似。但需要注意的一点是,translate是绝对匹配替换,这点与replace函数具有非常大区别。什么是绝对匹配替换呢?简单的说,是将字符串c1中按一定的格式c2替换为c3。如果文字形容仍然无法理解,我们通过几具实例来说明:
例如:
SELECT TRANSLATE('What is this','','-') FROM DUAL;
SELECT TRANSLATE('What is this','-','') FROM DUAL;
结果都是空。来试试这个:
SELECT TRANSLATE('What is this',' ',' ') FROM DUAL;
再来看这个:
SELECT TRANSLATE('What is this','ait','-*') FROM DUAL;
是否明白了点呢?Replace函数理解比较简单,它是将字符串中指定字符替换成其它字符,它的字符必须是连续的。而translate中,则是指定字符串 c1中出现的c2,将c2中各个字符替换成c3中位置顺序与其相同的c3中的字符。明白了?Replace是替换,而translate则像是过滤

(三).字符型函数返回数字值(Character Functions Returning Number Values)
本类函数支持所有的数据类型

1、INSTR(c1,c2[,n1[,n2]]) 返回c2在c1中位置
c1:原字符串
c2:要寻找的字符串
n1:查询起始位置,正值表示从左到右,负值表示从右到左 (大小表示位置,比如3表示左面第3处开始,-3表示右面第3处开始)。黑黑,如果为0的话,则返回的也是0
n2:第几个匹配项。大于0
例如:SELECT INSTR('abcdefg','e',-3) FROM DUAL;

2、LENGTH(c) 返回指定字符串的长度。如果
例如:SELECT LENGTH('A123中') FROM DUAL;
猜猜SELECT LENGTH('') FROM DUAL;的返回值是什么

(四).日期函数(Datetime Functions)
本类函数中,除months_between返回数值外,其它都将返回日期。

1、ADD_MONTHS() 返回指定日期月份+n之后的值,n可以为任何整数。
例如:SELECT ADD_MONTHS(sysdate,12),ADD_MONTHS(sysdate,-12) FROM DUAL;

2、CURRENT_DATE 返回当前session所在时区的默认时间
例如:
SQL> alter session set nls_date_format = 'mm-dd-yyyy' ;
SQL> select current_date from dual;

3、 SYSDATE 功能与上相同,返回当前session所在时区的默认时间。但是需要注意的一点是,如果同时使用sysdate与current_date获得的时间不一 定相同,某些情况下current_date会比sysdate快一秒。经过与xyf_tck(兄台的大作ORACLE的工作机制写的很好,深入浅出)的 短暂交流,我们认为current_date是将current_timestamp中毫秒四舍五入后的返回,虽然没有找到文档支持,但是想来应该八九不 离十。同时,仅是某些情况下会有一秒的误差,一般情况下并不会对你的操作造成影响,所以了解即可。
例如:SELECT SYSDATE,CURRENT_DATE FROM DUAL;

4、LAST_DAY(d) 返回指定时间所在月的最后一天
例如:SELECT last_day(SYSDATE) FROM DUAL;

5、NEXT_DAY(d,n) 返回指定日期后第一个n的日期,n为一周中的某一天。但是,需要注意的是n如果为字符的话,它的星期形式需要与当前session默认时区中的星期形式相同。
例如:三思用的中文nt,nls_language值为SIMPLIFIED CHINESE
SELECT NEXT_DAY(SYSDATE,5) FROM DUAL;
SELECT NEXT_DAY(SYSDATE,'星期四') FROM DUAL;
两种方式都可以取到正确的返回,但是:
SELECT NEXT_DAY(SYSDATE,'Thursday') FROM DUAL;
则会执行出错,提供你说周中的日无效,就是这个原因了。

6、MONTHS_BETWEEN(d1,d2) 返回d1与d2间的月份差,视d1,d2的值大小,结果可正可负,当然也有可能为0
例如:
SELECT months_between(SYSDATE, sysdate),
months_between(SYSDATE, add_months(sysdate, -1)),
months_between(SYSDATE, add_months(sysdate, 1))
FROM DUAL;

7、ROUND(d[,fmt]) 前面讲数值型函数的时候介绍过ROUND,此处与上功能基本相似,不过此处操作的是日期。如果不指定fmt参数,则默认返回距离指定日期最近的日期。
例如:SELECT ROUND(SYSDATE,'HH24') FROM DUAL;

8、TRUNC(d[,fmt]) 与前面介绍的数值型TRUNC原理相同,不过此处也是操作的日期型。
例如:SELECT TRUNC(SYSDATE,'HH24') FROM DUAL;

(五).转换函数(Conversion Functions)
转换函数将指定字符从一种类型转换为另一种,通常这类函数遵循如下惯例:函数名称后面跟着待转换类型以及输出类型。

1、TO_CHAR() 本函数又可以分三小类,分别是
转换字符->字符TO_CHAR(c):将nchar,nvarchar2,clob,nclob类型转换为char类型;
例如:SELECT TO_CHAR('AABBCC') FROM DUAL;

转换时间->字符TO_CHAR(d[,fmt]):将指定的时间(data,timestamp,timestamp with time zone)按照指定格式转换为varchar2类型;
例如:SELECT TO_CHAR(sysdate,'yyyy-mm-dd hh24:mi:ss') FROM DUAL;

转换数值->字符TO_CHAR(n[,fmt]):将指定数值n按照指定格式fmt转换为varchar2类型并返回;
例如:SELECT TO_CHAR(-100, 'L99G999D99MI') FROM DUAL;

2、 TO_DATE(c[,fmt[,nls]]) 将char,nchar,varchar2,nvarchar2转换为日期类型,如果fmt参数不为空,则按照fmt中指定格式进行转换。注意这里的 fmt参数。如果ftm为'J'则表示按照公元制(Julian day)转换,c则必须为大于0并小于5373484的正整数。
例如:
SELECT TO_DATE(2454336, 'J') FROM DUAL;
SELECT TO_DATE('2007-8-23 23:25:00', 'yyyy-mm-dd hh24:mi:ss') FROM DUAL;

为什么公元制的话,c的值必须不大于5373484呢?因为Oracle的DATE类型的取值范围是公元前4712年1月1日至公元9999年12月31日。看看下面这个语句:
SELECT TO_CHAR(TO_DATE('9999-12-31','yyyy-mm-dd'),'j') FROM DUAL;

3、TO_NUMBER(c[,fmt[,nls]]) 将char,nchar,varchar2,nvarchar2型字串按照fmt中指定格式转换为数值类型并返回。
例如:SELECT TO_NUMBER('-100.00', '9G999D99') FROM DUAL;

(六).其它辅助函数(Miscellaneous Single-Row Functions)

1、DECODE(exp,s1,r1,s2,r2..s,r[,def]) 可以把它理解成一个增强型的if else,只不过它并不通过多行语句,而是在一个函数内实现if else的功能。
exp做为初始参数。s做为对比值,相同则返回r,如果s有多个,则持续遍历所有s,直到某个条件为真为止,否则返回默认值def(如果指定了的话),如果没有默认值,并且前面的对比也都没有为真,则返回空。
毫无疑问,decode是个非常重要的函数,在实现行转列等功能时都会用到,需要牢记和熟练使用。

例如:select decode('a2','a1','true1','a2','true2','default') from dual;

2、GREATEST(n1,n2,...n) 返回序列中的最大值
例如:SELECT GREATEST(15,5,75,8) "Greatest" FROM DUAL;

3、LEAST(n1,n2....n) 返回序列中的最小值
例如:SELECT LEAST(15,5,75,8) LEAST FROM DUAL;

4、NULLIF(c1,c2)
Nullif也是个很有意思的函数。逻辑等价于:CASE WHEN c1 = c2 THEN NULL ELSE c1 END
例如:SELECT NULLIF('a','b'),NULLIF('a','a') FROM DUAL;

5、NVL(c1,c2) 逻辑等价于IF c1 is null THEN c2 ELSE c1 END。c1,c2可以是任何类型。如果两者类型不同,则oracle会自动将c2转换为c1的类型。
例如:SELECT NVL(null, '12') FROM DUAL;

6、NVL2(c1,c2,c3) 大家可能都用到nvl,但你用过nvl2吗?如果c1非空则返回c2,如果c1为空则返回c3
例如:select nvl2('a', 'b', 'c') isNull,nvl2(null, 'b', 'c') isNotNull from dual;

7、SYS_CONNECT_BY_PATH(col,c) 该函数只能应用于树状查询。返回通过c1连接的从根到节点的路径。该函数必须与connect by 子句共同使用。
例如:
create table tmp3(
rootcol varchar2(10),
nodecol varchar2(10)
);

insert into tmp3 values ('','a001');
insert into tmp3 values ('','b001');
insert into tmp3 values ('a001','a002');
insert into tmp3 values ('a002','a004');
insert into tmp3 values ('a001','a003');
insert into tmp3 values ('a003','a005');
insert into tmp3 values ('a005','a008');
insert into tmp3 values ('b001','b003');
insert into tmp3 values ('b003','b005');

select lpad(' ', level*10,'=') ||'>'|| sys_connect_by_path(nodecol,'/')
from tmp3
start with rootcol = 'a001'
connect by prior nodecol =rootcol;

8、SYS_CONTEXT(c1,c2[,n]) 将指定命名空间c1的指定参数c2的值按照指定长度n截取后返回。
Oracle9i提供内置了一个命名空间USERENV,描述了当前session的各项信息,其拥有下列参数:
 CURRENT_SCHEMA:当前模式名;
 CURRENT_USER:当前用户;
 IP_ADDRESS:当前客户端IP地址;
 OS_USER:当前客户端操作系统用户;
等等数十项,更详细的参数列还请大家直接参考Oracle Online Documents

例如:SELECT SYS_CONTEXT('USERENV', 'SESSION_USER') FROM DUAL;
注:N表示数字型,C表示字符型,D表示日期型,[]表示内中参数可被忽略,fmt表示格式。

单值函数在查询中返回单个值,可被应用到select,where子句,start with以及connect by 子句和having子句。
(一).数值型函数(Number Functions)
数 值型函数输入数字型参数并返回数值型的值。多数该类函数的返回值支持38位小数点,诸如:COS, COSH, EXP, LN, LOG, SIN, SINH, SQRT, TAN, and TANH 支持36位小数点。ACOS, ASIN, ATAN, and ATAN2支持30位小数点。

1、ABS(n) 返回数字的绝对值
例如:SELECT ABS(-1000000.01) FROM DUAL;

2、COS(n) 返回n的余弦值
例如:SELECT COS(-2) FROM DUAL;

3、ACOS(n) 反余弦函数,n between -1 and 1,返回值between 0 and pi。
例如:SELECT ACOS(0.9) FROM DUAL;

4、BITAND(n1,n2) 位与运算,这个太有意思了,虽然没想到可能用到哪里,详细说明一下:
假设3,9做位与运算,3的二进制形式为:0011,9的二进制形式为:1001,则结果是0001,转换成10进制数为1。
例如:SELECT BITAND(3,9) FROM DUAL;

5、CEIL(n) 返回大于或等于n的最小的整数值
例如:SELECT ceil(18.2) FROM DUAL;
考你一下,猜猜ceil(-18.2)的值会是什么呢

6、FLOOR(n) 返回小于等于n的最大整数值
例如:SELECT FLOOR(2.2) FROM DUAL;
再猜猜floor(-2.2)的值会是什么呢

7、BIN_TO_NUM(n1,n2,....n) 二进制转向十进制
例如:SELECT BIN_TO_NUM(1),BIN_TO_NUM(1,0),BIN_TO_NUM(1,1) FROM DUAL;

8、SIN(n) 返回n的正玄值,n为弧度。
例如:SELECT SIN(10) FROM DUAL;

9、SINH(n) 返回n的双曲正玄值,n为弧度。
例如:SELECT SINH(10) FROM DUAL;

10、ASIN(n) 反正玄函数,n between -1 and 1,返回值between pi/2 and -pi/2。
例如:SELECT ASIN(0.8) FROM DUAL;

11、TAN(n) 返回n的正切值,n为弧度
例如:SELECT TAN(0.8) FROM DUAL;

12、TANH(n) 返回n的双曲正切值,n为弧度
例如:SELECT TANH(0.8) FROM DUAL;

13、ATAN(n) 反正切函数,n表示弧度,返回值between pi/2 and -pi/2。
例如:SELECT ATAN(-444444.9999999) FROM DUAL;

14、EXP(n) 返回e的n次幂,e = 2.71828183 ...
例如:SELECT EXP(3) FROM DUAL;

15、LN(n) 返回n的自然对数,n>0
例如:SELECT LN(0.9) FROM DUAL;

16、LOG(n1,n2) 返回以n1为底n2的对数,n1 >0 and not 1 ,n2>0
例如:SELECT LOG(1.1,2.2) FROM DUAL;

17、POWER(n1,n2) 返回n1的n2次方。n1,n2可以为任意数值,不过如果m是负数,则n必须为整数
例如:SELECT POWER(2.2,2.2) FROM DUAL;

18、SIGN(n) 如果n<0返回-1,如果n>0返回1,如果n=0返回0.
例如:SELECT SIGN(14),SIGN(-14),SIGN(0) FROM DUAL;

19、SQRT(n) 返回n的平方根,n为弧度。n>=0
例如:SELECT SQRT(0.1) FROM DUAL;

(二).字符型函数返回字符值(Character Functions Returning Character Values)
该类函数返回与输入类型相同的类型。
 返回的CHAR类型值长度不超过2000字节;
 返回的VCHAR2类型值长度不超过4000字节;
如果上述应返回的字符长度超出,oracle并不会报错而是直接截断至最大可支持长度返回。

 返回的CLOB类型值长度不超过4G;
对于CLOB类型的函数,如果返回值长度超出,oracle不会返回任何错误而是直接抛出错误。

1、CHR(N[ USING NCHAR_CS]) 返回指定数值在当前字符集中对应的字符
例如:SELECT CHR(95) FROM DUAL;

2、CONCAT(c1,c2) 连接字符串,等同于||
例如:SELECT concat('aa','bb') FROM DUAL;

3、INITCAP(c) 将字符串中单词的第一个字母转换为大写,其它则转换为小写
例如:SELECT INITCAP('whaT is this') FROM DUAL;

4、NLS_INITCAP(c) 返回指定字符串,并将字符串中第一个字母变大写,其它字母变小写
例如:SELECT NLS_INITCAP('中华miNZHu') FROM DUAL;
它还具有一个参数:Nlsparam用来指定排序规则,可以忽略,默认状态该参数为当前session的排序规则。

(三).字符型函数返回数字值(Character Functions Returning Number Values)
本类函数支持所有的数据类型
1、ASCII(c) 与chr函数的用途刚刚相反,本函数返回指定字符在当前字符集下对应的数值。
例如:SELECT ASCII('_') FROM DUAL;

(四).日期函数(Datetime Functions)
本类函数中,除months_between返回数值外,其它都将返回日期。
1、CURRENT_TIMESTAMP([n]) 返回当前session所在时区的日期和时间。n表示毫秒级的精度,不大于6
例如:SELECT CURRENT_TIMESTAMP(3) FROM DUAL;

2、LOCALTIMESTAMP([n]) 与上同,返回当前session所在时区的日期和时间。n表示毫秒级的精度,不大于6
例如:SELECT LOCALTIMESTAMP(3) FROM DUAL;

3、SYSTIMESTAMP([n]) 与上同,返回当前数据库所在时区的日期和时间,n表示毫秒级的精度,>0 and <6
例如:SELECT SYSTIMESTAMP(4) FROM DUAL;

4、DBTIMEZONE 返回数据库的当前时区
例如:SELECT DBTIMEZONE FROM DUAL;

5、SESSIONTIMEZONE 返回当前session所在时区
例如:SELECT SESSIONTIMEZONE FROM DUAL;

6、EXTRACT(key from date) key=(year,month,day,hour,minute,second) 从指定时间提到指定日期列
例如:SELECT EXTRACT(year from sysdate) FROM DUAL;

7、TO_TIMESTAMP(c1[,fmt]) 将指定字符按指定格式转换为timestamp格式。
例如:SELECT TO_TIMESTAMP('2007-8-22', 'YYYY-MM-DD HH:MI:SS') FROM DUAL;

(五).转换函数(Conversion Functions)
转换函数将指定字符从一种类型转换为另一种,通常这类函数遵循如下惯例:函数名称后面跟着待转换类型以及输出类型。

1、BIN_TO_NUM(n1,n2...n) 将一组位向量转换为等价的十进制形式。
例如:SELECT BIN_TO_NUM(1,1,0) FROM DUAL;

2、CAST(c as newtype) 将指定字串转换为指定类型,基本只对字符类型有效,比如char,number,date,rowid等。此类转换有一个专门的表列明了哪种类型可以转换为哪种类型,此处就不作酹述。
例如:SELECT CAST('1101' AS NUMBER(5)) FROM DUAL;

3、CHARTOROWID(c) 将字符串转换为rowid类型
例如:SELECT CHARTOROWID('A003D1ABBEFAABSAA0') FROM DUAL;

4、ROWIDTOCHAR(rowid) 转换rowid值为varchar2类型。返回串长度为18个字节。
例如:SELECT ROWIDTOCHAR(rowid) FROM DUAL;

5、TO_MULTI_BYTE(c) 将指定字符转换为全角并返回char类型字串
例如:SELECT TO_MULTI_BYTE('ABC abc 中华') FROM DUAL;

6、TO_SINGLE_BYTE(c) 将指定字符转换为半角并返回char类型字串
例如:SELECT TO_SINGLE_BYTE('ABC abc中华') FROM DUAL;

(六).其它辅助函数(Miscellaneous Single-Row Functions)
1、COALESCE(n1,n2,....n) 返回序列中的第一个非空值
例如:SELECT COALESCE(null,5,6,null,9) FROM DUAL;

2、DUMP(exp[,fmt[,start[,length]]])
    dump是个功能非常强悍的函数,对于深入了解oracle存储的人而言相当有用。所以对于我们这些仅仅只是应用的人而言就不知道能将其应用于何处了。此处仅介绍用法,不对其功能做深入分析。

    如上所示,dump拥有不少参数。其本质是以指定格式,返回指定长度的exp的内部表示形式的varchar2值。fmt含4种格 式:8||10||16||17,分别表示8进制,10进制,16进制和单字符,默认为10进制。start参数表示开始位置,length表示以,分隔 的字串数。
例如:SELECT DUMP('abcdefg',17,2,4) FROM DUAL;

3、EMPTY_BLOB,EMPTY_CLOB 这两个函数都是返回空lob类型,通常被用于insert和update等语句以初始化lob列,或者将其置为空。EMPTY表示LOB已经被初始化,只不过还没有用来存储数据。

4、NLS_CHARSET_NAME(n) 返回指定数值对应的字符集名称。
例如:SELECT NLS_CHARSET_NAME(1) FROM DUAL;

5、NLS_CHARSET_ID(c) 返回指定字符对应的字符集id。
例如:SELECT NLS_CHARSET_ID('US7ASCII') FROM DUAL;

6、NLS_CHARSET_DECL_LEN(n1,n2) 返回一个NCHAR值的声明宽度(以字符为单位).n1是该值以字节为单位的长度,n2是该值的字符集ID
例如:SELECT NLS_CHARSET_DECL_LEN(100, nls_charset_id('US7ASCII')) FROM DUAL;

7、SYS_EXTRACT_UTC(timestamp) 返回标准通用时间即格林威治时间。
例如:SELECT SYS_EXTRACT_UTC(current_timestamp) FROM DUAL;

8、SYS_TYPEID(object_type) 返回对象类型对应的id。
例如:这个这个,没有建立过自定义对象,咋做示例?

9、UID 返回一个唯一标识当前数据库用户的整数。
例如:SELECT UID FROM DUAL;

10、USER 返回当前session用户
例如:SELECT USER FROM DUAL;

11、USERENV(c) 该函数用来返回当前session的信息,据oracle文档的说明,userenv是为了保持向下兼容的遗留函数。oracle公司推荐你使用sys_context函数调用USERENV命名空间来获取相关信息,所以大家了解下就行了。
例如:SELECT USERENV('LANGUAGE') FROM DUAL;

12、VSIZE(c) 返回c的字节数。
例如:SELECT VSIZE('abc中华') FROM DUAL;


posted @ 2008-12-14 20:12 轧钢王子 阅读(763) | 评论 (0)编辑 收藏

literal does not match format string

把字符串赋值给日期型,解决:先把字符串转换成日期型再赋值如:where c.pbeg_date >= to_date('2007-11-12','yyyy - MM - DD') and c.pbeg_date <= to_date('2007-12-12','yyyy -MM - DD')

posted @ 2008-12-14 19:44 轧钢王子 阅读(863) | 评论 (0)编辑 收藏

收集的关于ERP论坛的站点

收集的关于ERP论坛的站点。
序号 名称 站点 说明
1 trypub.com技术论坛 http://www.trypub.com
2 中国oracle用户讨论组 http://www.oracle.com.cn
3 erp100.COM ERP论坛 http://bbs.erp100.com
4 Oracle Developer 论坛 http://www.oradev.net 开发类性质的论坛
5 秋毫ERP咨询 http://www.qiuhao.com
6 中国ERP大全 http://www.erpxp.com/bbs
7 ERP信息网论坛 http://www.erp001.com/bbs/
8 itpub.net http://www.itpub.net
9 SAP & Oracle论坛 http://www.shcon.com.cn
10 erp在中国 http://www.erpcn.net
11 中国ERP知识库 http://www.erpkm.com
12 上海鸿略计算机有限公司 http://www.wisdom-universe.com
13 Oracle原创技术论坛 http://www.oraclebbs.com
14 IT精英论坛 http://www.witef.com
15 SOLARIS+ORACLE+ERP   http://bbs.chinaunix.net

posted @ 2008-12-14 19:40 轧钢王子 阅读(259) | 评论 (0)编辑 收藏

Oracle数据库中null的使用详解

     摘要: Oracle中的NULL既是一个难点也是一个重点,如何理解它,以及如何处理它,都关系到我们查询结果的正确性。  阅读全文

posted @ 2008-12-14 19:35 轧钢王子 阅读(369) | 评论 (0)编辑 收藏

Oracle中Decode()函数 使用技巧

decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)
该函数的含义如下:
IF 条件=值1 THEN
RETURN(翻译值1)
ELSIF 条件=值2 THEN
RETURN(翻译值2)
......
ELSIF 条件=值n THEN
RETURN(翻译值n)
ELSE
RETURN(缺省值)
END IF
· 使用方法:
1、比较大小
select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值
sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1
例如:
变量1=10,变量2=20
则sign(变量1-变量2)返回-1,decode解码结果为“变量1”,达到了取较小值的目的。


下面的例子说明了,如何读取用户CHECKUP表SEAPARK中的BLOOD_TEST_FLAG列下的项目,作为DECODE函数的实参支持值。
SELECT checkup_type,
DECODE(blood_test_flag,’Y’,’Yes’,’N’,’No’,NULL,’None’,’Invalid’)
FROM checkup;

posted @ 2008-12-09 21:06 轧钢王子 阅读(135) | 评论 (0)编辑 收藏

误用SQL Server关键字导致的问题

 

刚才在练习使用Hibernate的复合主键例子时,自己很自信的认为已经领悟了其中的原理,于是开始制作例子程序。恩,想起前段时间确实有个可以利用复合主键的地方,那就是公寓寝室表,于是开始建立数据库表:

利用Eclipse自动生成机制,很快就完成了映射文件等的生成,测试一下,却发觉出现错误

 1WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
 2
 3log4j:WARN Please initialize the log4j system properly.
 4
 5Hibernate: insert into HAIING.dbo.DORMROOM (desc, dorm, room) values (???)
 6
 7org.hibernate.exception.GenericJDBCException: could not insert: [com.haiing.hibernate.fuhezhujian.DormRoom]
 8
 9    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:82)
10
11    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:70)
12
13    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
14
15    at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1869)
16
17    at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2200)
18
19    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:46)
20
21    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
22
23    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
24
25    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:136)
26
27    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
28
29    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
30
31    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
32
33    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:324)
34
35    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
36
37    at com.haiing.hibernate.fuhezhujian.DormRoomOperate.insert(DormRoomOperate.java:26)
38
39    at com.haiing.hibernate.fuhezhujian.Test2PK.main(Test2PK.java:19)
40
41Caused by: java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]在关键字 'desc' 附近有语法错误。
42
43    at com.microsoft.jdbc.base.BaseExceptions.createException(Unknown Source)
44
45    at com.microsoft.jdbc.base.BaseExceptions.getException(Unknown Source)
46
47    at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processErrorToken(Unknown Source)
48
49    at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReplyToken(Unknown Source)
50
51    at com.microsoft.jdbc.sqlserver.tds.TDSRPCRequest.processReplyToken(Unknown Source)
52
53    at com.microsoft.jdbc.sqlserver.tds.TDSRequest.processReply(Unknown Source)
54
55    at com.microsoft.jdbc.sqlserver.SQLServerImplStatement.getNextResultType(Unknown Source)
56
57    at com.microsoft.jdbc.base.BaseStatement.commonTransitionToState(Unknown Source)
58
59    at com.microsoft.jdbc.base.BaseStatement.postImplExecute(Unknown Source)
60
61    at com.microsoft.jdbc.base.BasePreparedStatement.postImplExecute(Unknown Source)
62
63    at com.microsoft.jdbc.base.BaseStatement.commonExecute(Unknown Source)
64
65    at com.microsoft.jdbc.base.BaseStatement.executeUpdateInternal(Unknown Source)
66
67    at com.microsoft.jdbc.base.BasePreparedStatement.executeUpdate(Unknown Source)
68
69    at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
70
71    at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1853)
72
73     12 more
74



郁闷了很长时间,开始以为是主键类复写的hash类和equals类有错误,于是使用org.apache.commons.lang中的对应方法重写,可还是不行。端详了很长时间,每一种可能的错误都考虑了,感觉没啥错误了呀!

又看了一遍错误的代码,发觉已经生成了HQL语句,而且错误代码几乎全是数据库的问题。数据库的驱动包我已经加进来了,而且在其他的例子中运行很正常呀!莫非是提交语句的错误,看了一下看不出什么来,莫非是数据库的问题?去查看表,发觉有点怪怪的!


这个desc怎么成介个样子了,莫非设置成复合主键之后就成了这个样子,加进一个新的字段没有呀。嘿嘿,那我就删了这个字段,在重新加进来。结果还是不行!
这时我又调整了思路,把生成的SQL语句复制到查询分析器中执行,还是显示“在关键字 'desc' 附近有语法错误”,我晕!看来就是数据库的问题了。等等,我突然意识到什么了!

关键字?

desc?

莫非?不是莫非,就是这样呀,我怎么忘得一干二净了,desc这么好的词汇早就被前辈们定义成关键字了,怎么会留给我来使用呢!
      
改掉desc,一切问题全部解决了,数据成功的插入到数据库之中!

唉,惭愧呀~

posted @ 2008-01-29 18:06 轧钢王子 阅读(942) | 评论 (0)编辑 收藏

Spring自学笔记(1)

 

用了一段时间的公司框架,还没时间认真的坐下来练习一下Spring开源框架的基础,真是有些不好意思。刚看完在网上下的关于Spring的视频教程,正好练习一下,就以水果作为今天例子程序的主角。

打开Myeclipse,添加对Spring的支持(也不知道这么选行不行,汗~)

       接下来按照默认设置直接点击Next,最后点完成即可。项目中生成了传说中功能强大的Spring配置文件applicationContext.xml,哈哈,亲一个!

       环境设置好了,接下来该编写类文件了。先生成一个Fruit接口:

1package com.haiing.myspring;
2
3public interface Fruit 
4
5{
6       //吃水果
7       public void eat();
8}

9

       接着编写实现此接口的类文件:

 1package com.haiing.myspring;
 2
 3public class Apple implements Fruit {
 4
 5  public void eat() {
 6
 7              // 吃苹果
 8
 9              System.out.println("我要吃苹果了~~~") ;       
10
11       }

12
13}

14


 1package com.haiing.myspring;
 2
 3public class potato implements Fruit 
 4{
 5       public void eat() 
 6       {
 7
 8            // 吃西红柿
 9
10              System.out.println("我要吃西红柿了~~~") ;
11       }

12}

13


 1package com.haiing.myspring;
 2
 3public class Orange implements Fruit {
 4
 5       public void eat() {
 6
 7              // 吃橘子
 8
 9              System.out.println("我要吃橘子了~~~") ;
10
11       }

12
13}

14


       接口文件写好了,现在要写测试类和配置Spring文件了。

       设置applicationContext.xml配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

    
<bean id="apple" class="com.haiing.myspring.Apple"></bean>

    
<bean id="potato" class="com.haiing.myspring.Potato"></bean>

    
<bean id="orange" class="com.haiing.myspring.Orange"></bean>

</beans>


       编写一个测试类文件:

 1package com.haiing.myspring;
 2
 3import org.springframework.context.ApplicationContext;
 4
 5import org.springframework.context.support.ClassPathXmlApplicationContext;
 6
 7public class TestFruit 
 8
 9{
10       public static void main(String[] args)
11       {
12
13              ApplicationContext context = null ;
14
15              context = new ClassPathXmlApplicationContext("applicationContext.xml") ;
16
17              Fruit fruit = (Fruit)context.getBean("orange") ; 
18
19              fruit.eat() ;            
20       }

21}

22

 

现在可以开始测试效果了,运行测试类,在控制台输出:

我要吃苹果了~~~

log4j:WARN No appenders could be found for logger (org.springframework.beans.factory.xml.XmlBeanDefinitionReader).

log4j:WARN Please initialize the log4j system properly.

大功告成,下面红字提示是因为没有设置日志。这样,在苹果涨价之后,我们就可以方便的修改测试文件,换成其他的水果,照吃不误了~

不过话又说回来了,换归换,吃其他的东西可是吃不出苹果的味道呀

posted @ 2008-01-29 08:19 轧钢王子 阅读(279) | 评论 (0)编辑 收藏

在Hibernate中使用oracle的sequence产生主键

    刚刚接触Hibernate不长时间,今天想动手做一个小例子,数据库使用的是Oracle。打算使用Oracle中的序列作为表的主键,却不知道使用Hibernate如何与其关联在一起。请教同事,被告知要使用诸如select语句进行查询“select   sequence.nextval   from   dual”,晕倒~

终于等到中午,上网去查资料。得解:
   1
、在oracle 首先创建sequence

      create sequence seq_id
      minvalue 
1
      start 
with 1
      increment 
by 1
      cache 
20;

   2.在你的hbm.xml中的配置

     <id column="ID0000" name="id" type="integer">
         
<generator class="sequence">
              
<param name="sequence">seq_id</param>
         
</generator>
     
</id>

   这样再插入数据的时候,Hibernate回自动生成如下语句:

       hibernate: select seq_id.nextval from dual 

       hibernate:  
insert into YXJK.T_YXJK_WHRYTXL (XM0000, ZW0000,                         LXDH00,SJHM00,DZYJ00,IP0000,ID0000) values (?, ?, ?, ?, ?, ?, ?)

   自动生成下一个序列值,然后将对象插入表中。
       这样问题得解!

PS:
sequence就是采用数据库提供的sequence机制生成主键。如oralce中的Sequence
native
就是由hibernate根据数据库的Dialect,自动采用identityhilosequence的其中一种作为主键生成方式

posted @ 2008-01-16 17:49 轧钢王子 阅读(1361) | 评论 (0)编辑 收藏

一个合格的程序员该做的事情

将此作为第一篇随笔,谨以自勉!祝愿自己今后一路好走~

程序员每天该做的事

1、总结自己一天任务的完成情况

最好的方式是写工作日志,把自己今天完成了什么事情,遇见了什么问题都记录下来,日后翻看好处多多

2、考虑自己明天应该做的主要工作

把明天要做的事情列出来,并按照优先级排列,第二天应该把自己效率最高的时间分配给最重要的工作

3、考虑自己一天工作中失误的地方,并想出避免下一次再犯的方法

出错不要紧,最重要的是不要重复犯相同的错误,那是愚蠢

4、考虑自己一天工作完成的质量和效率能否还能提高

一天只提高1%365天你的效率就能提高多少倍你知道吗? (1+0.01)^365 = 37

5、看一个有用的新闻网站或读一张有用的报纸,了解业界动态

闭门造车是不行的,了解一下别人都在做什么,对自己能带来很多启示

6、记住一位同事的名字及其特点

你认识公司的所有同事吗?你了解他们吗?

7、清理自己的代码

今天完成的代码,把中间的调试信息,测试代码清理掉,按照编码风格整理好,注释都写好了吗?

8、清理自己的桌面

当日事当日毕,保持清洁干劲的桌面才能让你工作时不分心,程序员特别要把电脑的桌面清理干净

程序员每月该做的事
1
、至少和一个同事一起吃饭或喝茶

不光了解自己工作伙伴的工作,还要了解他们的生活

2、自我考核一次
相对正式地考核自己一下,你对得起这个月的工资吗?

3、对你的同事考核一次
你的同事表现怎么样?哪些人值得学习,哪些人需要帮助?

3、制定下月的计划,确定下月的工作重点

4、总结自己工作质量改进状况
自己的质量提高了多少?

5、有针对性地对一项工作指标做深入地分析并得出改进的方案
可以是对自己的,也可以是对公司的,一定要深入地分析后拿出自己的观点来。要想在老板面前说得上话,做的成事,工作上功夫要做足。

6、与老板沟通一次
最好是面对面地沟通,好好表现一下自己,虚心听取老板的意见,更重要的是要了解老板当前关心的重点

程序员每年该做的事
1
、年终总结

每个公司都会做的事情,但你真正认真地总结过自己吗?

2、兑现给自己、给家人的承诺
给老婆、儿子的新年礼物买了没有?给自己的呢?

3、下年度工作规划
好好想想自己明年的发展目标,争取升职/加薪、跳槽还是自己出来干?

4、掌握一项新技术
至少是一项,作为程序员一年要是一项新技术都学不到手,那就一定会被淘汰。

掌握可不是看本书就行的,要真正懂得应用,最好你能够写一篇教程发表到你的blog

5、推出一种新产品
可以是一个真正的产品,也可以只是一个类库,只要是你创造的东西就行,让别人使用它,也为世界作点贡献。当然如果真的很有价值,收点注册费也是应该的

6、与父母团聚一次
常回家看看,常回家看看

posted @ 2008-01-06 23:55 轧钢王子 阅读(393) | 评论 (2)编辑 收藏