2008年9月22日星期一

[转]ORACLE各种数据类型详细介绍


ORACLE数据类型大约分为:character, number, date, LOB, 和RAW等类型。虽然
ORACLE8i也允许你自定义数据类型,但是它们是最基本的数据类型。  

在下面的文章中你将了解到他们在oracle 中的用法、限制以及允许值。
  
  Character 数据类型

  Character 数据类型用来存储字母数字型数据。当你在oracle 中定义一个character 数据时通常需要制定字段的长度,它是该字段的最大长度。ORACLE提供以下几种character 数据类型:

CHAR() CHAR数据类型是一种有固定长度和最大长度的字符串。存储在数据类型为CHAR字段中的数据将以空格的形式补到最大长度。长度定义在1——2000字节之间。当你创建一个CHAR型字段,数据库将保证在这个字段中的所有数据是定义长度,如果某个数据比定义长度短,那么将用空格在数据的右边补到定义长度。如果长度大于定义长度将会触发错误信息。
  

VARCHAR() varchar型数据是varchar2型数据的快照[目前varchar是varchar2的同义词。工业标准的varchar类型可以存储空字符串,但是oracle不这样做,尽管它保留以后这样做的权利。Oracle自己开发了一个数据类型varchar2,这个类型不是一个标准的varchar,它将在数据库中varchar列可以存储空字符串的特性改为存储null值。如果你想有向后兼容的能力,Oracle建议使用varchar2而不是varchar]

VARCHAR2() varchar2数据类型是一种可变长度的、有最大长度的字母数字型数据。Varchar2类型的字段长度可以达到4000字节,Varchar2类型的变量长度可以达到32676字节。
一个空的varchar2(2000)字段和一个空的varchar2(2)字段所占用的空间是一样的。

NCHAR()NVARCHAR2() NCHAR() 和 NVARCHAR2()数据类型分别与CHAR() 和 VARCHAR2()类型是相同的,只不过它们用来存储NLS(National Language Support)[本地语言支持]数据。
  
  LONG LONG 数据类型是一个遗留下来的而且在将来不会被支持的数据类型。它将被LOB(Large Object) [大型对象]数据类型所代替。

  

  比较规则 Varchar2和char数据类型根据尾部的空格有不同的比较规则。对Char型数据,尾部的空格将被忽略掉,对于Varchar2型数据尾部带空格的数据排序比没有空格的要大些。比如:
  
  Char 型数据:        'YO' = 'YO ' 

  Varchar2型数据:      'YO' < 'YO '   


  Numberic 数据类型


  Numberic 数据类型用来存储负的和正的整数、分数和浮点型数据,范围在-1*10-103 和9.999…99*10125之间,有38位的精确度。标识一个数据超出这个范围时就会出错。

  Number(p,s) Number数据类型存储一个有p位精确度的s位等级的数据。

  
  DATE 数据类型

  DATE 数据类型用来存储日期和时间格式的数据。这种格式可以转换为其他格式的数据去浏览,而且它有专门的函数和属性用来控制和计算。以下的几种信息都包含在DATE数据类型中:

  Century 
  Year 
  Month 
  Day  
  Hour  
  Minute  
  Second

  

  LOB 数据类型

  LOB(Large Object) 数据类型存储非结构化数据,比如二进制文件,图形文件,或其他外部文件。LOB 可以存储到4G字节大小。数据可以存储到数据库中也可以存储到外部数据文件中。LOB数据的控制通过DBMS_LOB 包实现。BLOB, NCLOB, 和CLOB 数据可以存储到不同的表空间中,BFILE存储在服务器上的外部文件中。LOB数据类型有以下几种:

  BLOB: 二进制数据 

  CLOB: 字符型数据

  BFILE: 二进制文件



  其他数据类型
 
  ROWID ROWID 数据类型是ORACLE数据表中的一个伪列,它是数据表中每行数据内在的唯一的标识。







2008年9月18日星期四

工作流环境jBPM搭建初探

使用jBPM开发基于WEB的工作流,首先需要搭建好开发环境,经过一段时间的摸索,先将环境搭建的步骤做个简要说明:
1.前提:
Eclipse 3.2
MyEclipse 5.0GA
jBPM3.1.2(jbpm-starters-kit-3.1.2)
Oracle 10g
Struts1.2
Hibernate3

2.至于数据库的脚本生成就不说了,有些参考资料讲得比较清楚,也有备份。
3.安装完JBPM的相关Eclipse插件以后,就可以使用Eclipse创建(new...)一个Process Project以及相关的ProcessDefinition,但这不是我们想要的。我们想要的从步骤4开始。

4.使用Eclipse创建一个Web Project,加入必要的框架包,如Struts,JSTL等。

5.在构建路径中配置jBPM库,这也是环境搭建的重点。由于使用默认的Process Project可以帮我们创建好jBPM库,但没有帮我们创建WEB环境,因此,我们首先建立WEB工程,再来搭建JBPM库。
6.在工程的“Build Path”中选择配置构建路径(Config Build Path...)。
7.在打开的窗口中选择右边的Libraries标签库,通过Add Library选项,在打开的窗口中添加一个jBPM库。
8.可以看到没有所谓的jBPM库选项,因此要自己动手,选择User Library选项,创建一个自定义的用户库,取名为jBPM Library [jBPM Runtime]。
9.添加jar文件到我们自定义的User Library中,需要添加的内容是:
jbpm-starters-kit-3.1.2\jbpm.3\lib目录下的所有jar包;
jbpm-starters-kit-3.1.2\jbpm.3\build目录下的所有jar包。

OK,开发环境初步搭建完成,我们同样可以在新建的工程中自由的创建Process Definition文件。

2008年9月17日星期三

使用Oracle的闪回技术恢复被删除的表

使用Oracle 10g版本的数据库时,查询数据库表,偶尔会出现一些以BIN$开头命名的表,这些表是ORACLE数据库中被DROP掉的表,保留在一个回收站中。如果万一错删了一个重要的表,则可以使用“闪回”的方法来恢复。
现在做一个测试:

SQL> create table aa(
2  col001 varchar2(20) primary key,
3 col002 varchar2(20),
4 col003 varchar2(100)
5 );

SQL> insert into aa values('001','China','Asia');

1 rows inserted

SQL> select * from aa;

COL001 COL002 COL003
-------------------- -------------------- -------------------
001 China Asia

SQL> drop table aa;

Table dropped

SQL> select * from user_recyclebin;

OBJECT_NAME ORIGINAL_NAME OPERATION
BIN$szLzmW8iSNe1cOL+pL3nDA==$0 AA DROP
BIN$uvwnj9g/TMOOZPxdVC9azg==$0 SYS_C0030540 DROP

如果我们要恢复表,可以在SQL*PLUS中使用如下命令:

SQL> flash back table TABLE_NAME to before drop

执行完毕后,查询用户表,可以发现表已经成功恢复,且数据完整。

由于被删除的表存在于回收站,并没有真正从硬盘删除,因此它还占用原有的存储空间。如果我们不想看到在查询表的时候出现回收站表的名称,是想释放存储空间,则可以清空回收表:

SQL> purge user_recyclebin;

这样做将删除回收站的所有表,有时候为了保险起见,我们只删除回收站中特定的表,可以使用带表名(也可以是回收站的特殊表名)的purge命令,如:

SQL> purge table TABLE_NAME;

SQL> purge table BIN$szLzmW8iSNe1cOL+pL3nDA==$0;

也可以在删除表的时候加上purge参数,直接删除而不保留在回收站,这样表就永久删除且不可恢复了。如:

SQL> drop table TABLE_NAME purge;

使用闪回技术还可以使表恢复到某个时间点,可以使用命令:
flashback table TABLE_NAME TO TIMESTAMP to_timestamp(string1, [ format_mask ],[ 'nlsparam' ] );

当表空间不足的时候,回收站也会由ORACLE自动管理,按照先进先出的原则删除回收站中的对象。

2008年9月12日星期五

PageRank算法代码实现


package org.jazz.pagerank;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* PageRank代码实现
* 支持从文件中读取邻接矩阵
* @author zhengtanyun
* @version 0.1
*/
public class PageRank{

public static void main(String[] args) throws IOException{

int nodeNum = 4; //节点数
int TIMES = 10; //迭代次数
int[]outLink = new int[nodeNum]; //存放节点的外链数A>>>>Z

float rank = 0f; //中间变量,保存rank值得中间值
float value = 0f; //计算后的pagerank值
float[] copyPR = new float[nodeNum]; //迭代完成后由新数组拷贝过来的副本

boolean flag = true;


/* --------------------------------------------------------*
* 相关参数获取
* 将邻接矩阵放在文本文件中,规则如下:
* 第一行:节点数;
* 第二行:迭代的初始PR值,个数与节点数一致,以逗号分隔;
* 第三行开始:每一行对应邻接矩阵的一行,共N行N列,N同节点数目,其中:
* 每个节点以逗号分隔,9代表节点自身,1代表有链接关系,0代表无链接关系。
* --------------------------------------------------------*/
FileReader reader = new FileReader("E:\\a.txt"); //邻接矩阵文件存放位置
BufferedReader br = new BufferedReader(reader);

String paramLine = br.readLine();
String initPR = br.readLine();

/* -----------------------------*
* 获取节点数
* -----------------------------*/
nodeNum = new Integer(paramLine).intValue(); //获取节点数
int[][] link = new int [nodeNum][nodeNum]; //邻接矩阵定义

/* -----------------------------*
* 获取迭代初值
* -----------------------------*/
float[] tempPR = new float[nodeNum];
String[] strInit = initPR.split(",");
for(int i=0;i<strInit.length;i++){
tempPR[i] = new Float(strInit[i]).floatValue();
System.out.print(tempPR[i]+"f, ");
}
System.out.println();

/* -----------------------------*
* 构造邻接矩阵
* -----------------------------*/
int tmp=0;
while(flag){
String lineText = br.readLine();
if(null==lineText){
flag=false;
continue;
}
String[] s = lineText.split(",");

for(int j=0;j<nodeNum;j++){
link[tmp][j] = new Integer(s[j]).intValue();
}
tmp++;
}

br.close(); //关闭流
reader.close(); //关闭文件

/* ---------------------------------*
* 邻接矩阵打印模块
* ---------------------------------*/
for(int i=0;i<nodeNum;i++){
for(int j=0;j<nodeNum;j++){
System.out.print(link[i][j]+",");
}
System.out.println();
}


/* ---------------------------------*
* 统计节点的外链接数
* ---------------------------------*/
for(int i=0;i<nodeNum;i++){
int links = 0;
for(int j=0;j<nodeNum;j++){
if(link[i][j]!=9){
links += link[i][j];
}
}
outLink[i] = links; //节点0到NODENUM的外链数 假设对应为A B C D
}
System.out.println("");

//计算PR值
/* ----------------------------------------------------------------*
* 循环对每个节点的"入链"进行计算,得到该节点的PR值。 所谓入链接点,就是指邻接矩阵
* 的纵向节点,其计算的方向为纵向;
*
* 对于横向的每个节点,有一个对应的纵向节点的数组。
* 为0表示没有链接,不用计算,
* 为9表示节点自身,不用计算,
* 为1表示有链接,我们在前一个步骤中已经得到了该入链节点的外链接数。
* ----------------------------------------------------------------*/
for(int m=0;m<TIMES;m++){ //迭代
/* ------------------------------------------------------------*
* 每次迭代完成后,要把各个节点的PR值放到一个数组中,用于下一次迭代
* 假设放到tempPR[]中;
* 同时,还要保留一个计算用PR值的副本,假设为copyPR[]
* ------------------------------------------------------------*/
//数组拷贝
for(int x=0;x<tempPR.length;x++){
copyPR[x] = tempPR[x];
}
float sum = 0f; //PageRank临时求和变量
//float[] fac = {2f,3f,4f,5f};
for(int node=0;node<nodeNum;node++){
/* --------------------------------------------------------*
* 这个循环是为了得到本轮各个节点计算后的PR值,将得到一个新的PR值数组
* --------------------------------------------------------*/
//使用copyPR[]进行计算
for(int j=0;j<nodeNum;j++){

int var = link[j][node];
/* --------------------------------------------------------*
* 比如要计算第0个节点,那么对应的第0列:
* link[0][0],link[1][0],link[2][0],link[3][0]
* 为其对应的纵向节点,
* 其中值为9代表节点本身,为0不参与计算,为1代表与节点有链接
* -------------------------------------------------------*/
if(var==0var==9){
continue; //没有链接就跳过
}else{
rank = rank+copyPR[j]/(outLink[j]); //计算
}
}
value = rank*0.85f + 0.15f; //这个得到该节点在本轮迭代的最后值
sum += value;

System.out.println("PR["+node+"]"+value); //信息打印
tempPR[node] = value;
rank = 0f; //本节点计算完成后,中间变量清零
}
System.out.println("AVG OF PR = "+sum/nodeNum);
System.out.println("=====================================");
}
}
}

2008年9月1日星期一

Web打印元素位置的保存

客户要求WEB打印能够随意拖拽,并能够保存位置,这是因为原先客户用的是独立的客户端打印程序,现在软件采用BS架构,如何能达到客户的要求呢?
针对客户的需求,提出两个解决方案:(1)页面元素拖拽;(2)元素位置持久化。
(1)页面元素拖拽有很多现成的例子,Google一下一大把,这里就不说了。
(2)因为软件基于B/S/S架构,用户基于浏览器浏览,可以使用Cookie来保存用户的个性化数据,这样一来,可以针对每台机器的登录用户,有一个独立的页面元素的位置设置信息。页面上可以拖动的元素往往多达10几个甚至更多,而Cookie只能保存一条数据,这样,我们就绕个弯,把各个元素的位置信息用连接符号串成一个字符串保存,到时候页面初始化的时候,从Cookie中读出信息,再进行分解,就可以得到每个元素的位置值了。

====START====
//设置Cookie值的函数
function setCookie(name, value){
var a = name;
var b = value;
var ExpiresTime = new Date();
ExpiresTime.setTime(ExpiresTime.getTime() + 365*24*3600*1000 );
document.cookie = a+"="+b+";expires="+ ExpiresTime.toGMTString();
}

//装载页面时读取Cookie
function window.onload(){
var cookieString = new String(document.cookie);
var cookieHeader = "position=";
var beginPosition = cookieString.indexOf(cookieHeader);
var pos="";
if (beginPosition != -1){
pos = cookieString.substring(beginPosition + cookieHeader.length);
var strArray=new Array();
strArray=pos.split("#");
var ename;
var pLeft;
var pTop ;
for(var i=0;i<strArray.length-1;i++){
var temp = new Array();
temp = strArray[i].split(":");
ename=temp[0];
eLeft=temp[1];
eTop =temp[2];
document.getElementById(ename).style.left=eLeft;
document.getElementById(ename).style.top = eTop;
}
}else{ }
}

//保存各元素的位置信息到Cookie
function savePosition(){
var pos = "";
for(var i=1;i<14;i++){
var id = "p"+i;
var obj=document.getElementById(id);
posLeft=obj.offsetLeft;
posTop =obj.offsetTop;
pos = pos+id+":"+posLeft+":"+posTop+"#"; //位置值串接
}
setCookie("position",pos);
alert("保存样式成功.");
}

==== OVER ====