发表于: other | 作者: | 日期: 2008/11/05 10:11
标签:

让我与你共同分享一段小故事,或许在这个阶段,可以很实际地让我们走出目前的困境。

一九七六年的冬天,当时我十九岁,在休斯顿太空总署的大空梭实验室里工作,同时也在总署旁边的休斯顿大学主修电脑。纵然忙于学校、睡眠与工作之间,这几乎占据了我一天二十四小时的全部时间,但只要有多余的一分钟,我总是会把所有的精力放在我的音乐创作上。

我知道写歌词不是我的专长,所以在这段日子里,我处处寻找一位善写歌词的搭档,与我一起合作创作。我认识了一位朋友,她的名字叫凡內芮(Valerie Johnson)。自从二十多年前离开德州后,就再也没听过她的消息,但是她却在我事业的起步时,给了我最大的鼓励。仅十九岁的凡內芮在德州的诗词比赛中,不知得过多少奖牌。她的写作总是让我爱不释手,当时我们的确合写了许多很好的作品,一直到今天,我仍然认为这些作品充满了特色与创意。

一个星期六的周末,凡內芮又热情地邀请我至她家的牧场烤肉。她的家族是德州有名的石油大亨,拥有庞大的牧场。她的家庭虽然极为富有,但她的穿着、所开的车、与她谦诚待人的态度,更让我加倍地打从心底佩服她。凡內芮知道我对音乐的执着。然而,面对那遥远的音乐界及整个美国陌生的唱片市场,我们一点管道都没有。此时,我们两个人坐在德州的乡下,我们哪知道下一步该如何走。突然间,她冒出了一句话:

” Visualize ,What you are doing in 5 years?﹙想像你五年后在做什么?﹚”

我愣了一下。

她转过身来,手指着我说:”嘿!告诉我,你心目中“最希望”五年后的你在做什么,你那个时候的生活是一个什么样子?”我还来不及回答,她又抢着说:”別急,你先仔细想想,完全想好,确定后再说出来。”我沉思了几分钟,开始告诉她:”第一,五年后,我希望能有一张唱片在市场上,而这张唱片很受欢迎,可以得到许多人的肯定。第二,我住在一个有很多很多音乐的地方,能天天与一些世界一流的乐师一起工作。”

凡內芮说:”你确定了吗?”

我慢慢稳稳地回答,而且拉了一个很长的Yesssssss!

凡內芮接着说:”好,既然你确定了,我们就把这个目标倒算回来。如果第五年,你有一张唱片在市场上,那么你的第四年一定是要跟一家唱片公司签上合约。”

“那么你的第三年一定是要有一个完整的作品,可以拿给很多很多的唱片公司听,对不对?”

“那么你的第二年,一定要有很棒的作品开始录音了。”

“那么你的第一年,就一定要把你所有要准备录音的作品全部编曲,排练就位准备好。”

“那么你的第六个月,就是要把那些没有完成的作品修饰好,然后让你自己可以逐一筛选。”

“那么你的第一个月就是要把目前这几首曲子完工。”

“那么你的第一个礼拜就是要先列出一整个清单,排出哪些曲子需要修改,哪些需要完工。”

“好了,我们现在不就已经知道你下个星期一要做什么了吗?”凡內芮笑笑地说。

“喔,对了。你还说你五年后,要生活在一个有很多音乐的地方,然后与许多一流的乐师一起忙着工作,对吗?”她急忙地补充说。”如果,你的第五年已经在与这些人一起工作,那么你的第四年照道理应该有你自己的一个工作室或录音室。那么你的第三年,可能是先跟这个圈子里的人在一起工作。那么你的第二年,应该不是住在德州,而是已经住在纽约或是洛杉机了。”

次年(一九七七年),我辞掉了令许多人羨慕的太空总署的工作,离开了休斯顿,搬到洛杉机。

说也奇怪:不敢说是恰好五年,但大约可说是第六年。一九八三年,我的唱片在亚洲开始销起来,我一天二十四小时几乎全都忙着与一些顶尖的音乐高手,日出日落地一起工作。

每当我在最困惑的时候,我会静下来问我自己:五年后你”最希望”看到你自己在做什么?

如果,你自己都不知道这个答案的话,你又如何要求別人或上帝为你做选择或开路呢?別忘了!在生命中,上帝已经把所有”选择”的权力交在我们的手上了。

如果,你对你的生命经常在问”为什么会这样?””为什么会那样?”的时候,你不妨试着问一下自己,你是否很”清清楚楚”地知道你自己要的是什么?

如果连你自己要的是什么都不知道的话,那么爱你的主又如何帮你安排呢?不是吗?

而在你旁边的人,再怎么热心地为你敲锣打鼓,爱你的主也顶多给一些慈悲的安慰。因为连你自己都还没有清楚地告诉他,你要的是什么?那么你又岂能无辜地怪上帝没有为你开路呢?不是吗?

有这样一篇调查似乎也说明了什么:

有一年,一群意气风发的天之骄子从美国哈佛大学毕业了,他们即将开始穿越各自的玉米地。他们的智力、学历、环境条件都相差无几。在临出校门前,哈佛对他们进行了一次关于人生目标的调查。结果是这样的:

27%的人,没有目标;60%的人,目标模糊;

10%的人,有清晰但比较短期的目标;

3%的人,有清晰而长远的目标。

以后的25年,他们穿越玉米地。25年后,哈佛再次对这群学生进行了跟踪调查。结果又是这样的:

3%的人,25年间他们朝着一个方向不懈努力,几乎都成为社会各界的成功人士,其中不乏行业领袖、社会精英;

10%的人,他们的短期目标不断地实现,成为各个领域中的专业人士,大都生活在社会的中上层;

60%的人,他们安稳地生活与工作,但都没有什么特别成绩,几乎都生活在社会的中下层;

剩下27%的人,他们的生活没有目标,过得很不如意,并且常常在抱怨他人、抱怨社会、抱怨这个“不肯给他们机会”的世界。

其实,他们之间的差别仅仅在于:25年前,他们中的一些人知道为什么要穿越玉米地,而另一些人则不清楚或不很清楚。

作者:佚名
来源:网络

评论关闭
发表于: os/software | 作者: | 日期: 2008/11/05 09:11
标签: ,

http://sites.google.com/site/loveipod2/Home/winemnc

评论关闭
发表于: java/j2ee | 作者: | 日期: 2008/11/05 06:11
标签:

package com.sitech.grp.web.actionbean;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.upload.FormFile;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import java.io.*;
import com.sitech.grp.model.Dgrpcustcontract;
import com.sitech.grp.web.formbean.DGrpContractForm;
import com.sitech.grp.service.IDGrpContractManager;
import sun.net.TelnetOutputStream;
import sun.net.ftp.FtpClient;

public class DGrpContractAction extends DispatchAction {
private IDGrpContractManager grpContractManager;
private FtpClient ftpClient;
// 查询集团合同信息
public ActionForward queryGrpContractMsg(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
DGrpContractForm frm = (DGrpContractForm) form;
try {
Dgrpcustcontract dGrpContract = frm.getEntity();
frm.setResultList(grpContractManager
.queryGrpContractMsg(dGrpContract.getUnit_id()));
} catch (Exception e) {
System.out.println(e);
}
return mapping.findForward(“querygrpcontract”);
}

// 查询集团合同详细信息
public ActionForward querySingleContractMsg(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
DGrpContractForm frm = (DGrpContractForm) form;
try {
Dgrpcustcontract dGrpContract = frm.getEntity();
dGrpContract = grpContractManager.get(dGrpContract.getUnit_id());
frm.setEntity(dGrpContract);
} catch (Exception e) {
System.out.println(“querySingleContractMsg=” + e);
}
return mapping.findForward(“querySingleContractMsg”);
}

// 更新集团合同信息
public ActionForward updateContractMsg(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception{
DGrpContractForm frm = (DGrpContractForm) form;
TelnetOutputStream os = null;
FileInputStream is = null;
try {
Dgrpcustcontract dGrpContract = frm.getEntity();
// ——————————————–
String encoding = request.getCharacterEncoding();
if ((encoding != null) && (encoding.equalsIgnoreCase(“utf-8”))) {
response.setContentType(“text/html; charset=gb2312″);// 如果没有指定编码,编码格式为gb2312
}
FormFile file = frm.getFiles();// 取得上传的文件
if (file.getFileName().length() > 0) {
InputStream stream = file.getInputStream();// 把文件读入
// server:FTP服务器的IP地址;user:登录FTP服务器的用户名
// password:登录FTP服务器的用户名的口令;path:FTP服务器上的路径
ftpClient = new FtpClient();
String path=”/bboss/run/vippage/upload/contract/”;//上传文件路径
ftpClient.openServer(“10.161.1.58”);
ftpClient.login(“weblogic”, “asd123”);
//path是ftp服务下主目录的子目录
if (path.length() != 0)
ftpClient.cd(path);
//用2进制上传
ftpClient.binary();
//”upftpfile”用ftp上传后的新文件名
os = ftpClient.put(dGrpContract.getContract_id() + “-”
+ file.getFileName());
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);// 将文件写入服务器}
}

dGrpContract.setContract_file(file.getFileName());
}
// ——————————————–
grpContractManager.update(dGrpContract);
frm.setResultList(grpContractManager
.queryGrpContractMsg(dGrpContract.getUnit_id()));
frm.setOp_flag(“true”);
} catch (Exception e) {
frm.setOp_flag(“false”);
System.out.println(“updateContractMsg=” + e);
} finally {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
}
return mapping.findForward(“querygrpcontract”);
}

public void setGrpContractManager(IDGrpContractManager grpContractManager) {
this.grpContractManager = grpContractManager;
}

}

评论关闭
发表于: arch/management | 作者: | 日期: 2008/11/05 06:11
标签:

2005年12月6日
只有在实际编程的时候体会OOAD的思想,才会发现OOAD的妙处。 More …

评论关闭
发表于: DB/ES | 作者: | 日期: 2008/11/05 06:11
标签:

我们将讨论各种用于访问ORACLE数据库的DDL和TCL语句。

查询
SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELECT语句时,要与INTO子句一起使用,查询的返回值被赋予INTO子句中的变量,变量的声明是在DELCARE中。SELECT INTO语法如下:
SELECT [DISTICT|ALL]{*|column[,column,…]}
INTO (variable[,variable,…] |record)
FROM {table|(sub-query)}[alias]
WHERE…………
PL/SQL中SELECT语句只返回一行数据。如果超过一行数据,那么就要使用显式游标(对游标的讨论我们将在后面进行),INTO子句中要有与SELECT子句中相同列数量的变量。INTO子句中也可以是记录变量。

%TYPE属性
在PL/SQL中可以将变量和常量声明为内建或用户定义的数据类型,以引用一个列名,同时继承他的数据类型和大小。这种动态赋值方法是非常有用的,比如变量引用的列的数据类型和大小改变了,如果使用了%TYPE,那么用户就不必修改代码,否则就必须修改代码。

例:
v_empno SCOTT.EMP.EMPNO%TYPE;
v_salary EMP.SALARY%TYPE;
 不但列名可以使用%TYPE,而且变量、游标、记录,或声明的常量都可以使用%TYPE。这对于定义相同数据类型的变量非常有用。
DELCARE
V_A NUMBER(5):=10;
V_B V_A%TYPE:=15;
V_C V_A%TYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE
(‘V_A=’||V_A||’V_B=’||V_B||’V_C=’||V_C);
END

SQL>/
V_A=10 V_B=15 V_C=
PL/SQL procedure successfully completed.
SQL>

其他DML语句
其它操作数据的DML语句是:INSERT、UPDATE、DELETE和LOCK TABLE,这些语句在PL/SQL中的语法与在SQL中的语法相同。我们在前面已经讨论过DML语句的使用这里就不再重复了。在DML语句中可以使用任何在DECLARE部分声明的变量,如果是嵌套块,那么要注意变量的作用范围。

例:
CREATE OR REPLACE PROCEDURE FIRE_EMPLOYEE (pempno in number)
 AS
v_ename EMP.ENAME%TYPE;
BEGIN
 SELECT ename INTO v_ename
FROM emp
WHERE empno=p_empno;
INSERT INTO FORMER_EMP(EMPNO,ENAME)
VALUES (p_empno,v_ename);
DELETE FROM emp
WHERE empno=p_empno;
UPDATE former_emp
SET date_deleted=SYSDATE
WHERE empno=p_empno;

EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE(‘Employee Number Not Found!’);
END

DML语句的结果
当执行一条DML语句后,DML语句的结果保存在四个游标属性中,这些属性用于控制程序流程或者了解程序的状态。当运行DML语句时,PL/SQL打开一个内建游标并处理结果,游标是维护查询结果的内存中的一个区域,游标在运行DML语句时打开,完成后关闭。隐式游标只使用SQL%FOUND,SQL%NOTFOUND,SQL%ROWCOUNT三个属性.SQL%FOUND,SQL%NOTFOUND是布尔值,SQL%ROWCOUNT是整数值。

SQL%FOUND和SQL%NOTFOUND
在执行任何DML语句前SQL%FOUND和SQL%NOTFOUND的值都是NULL,在执行DML语句后,SQL%FOUND的属性值将是:

. TRUE :INSERT
. TRUE ELETE和UPDATE,至少有一行被DELETE或UPDATE.
. TRUE :SELECT INTO至少返回一行
当SQL%FOUND为TRUE时,SQL%NOTFOUND为FALSE。

SQL%ROWCOUNT
在执行任何DML语句之前,SQL%ROWCOUNT的值都是NULL,对于SELECT INTO语句,如果执行成功,SQL%ROWCOUNT的值为1,如果没有成功,SQL%ROWCOUNT的值为0,同时产生一个异常NO_DATA_FOUND.

SQL%ISOPEN
SQL%ISOPEN是一个布尔值,如果游标打开,则为TRUE, 如果游标关闭,则为FALSE.对于隐式游标而言SQL%ISOPEN总是FALSE,这是因为隐式游标在DML语句执行时打开,结束时就立即关闭。

事务控制语句
事务是一个工作的逻辑单元可以包括一个或多个DML语句,事物控制帮助用户保证数据的一致性。如果事务控制逻辑单元中的任何一个DML语句失败,那么整个事务都将回滚,在PL/SQL中用户可以明确地使用COMMIT、ROLLBACK、SAVEPOINT以及SET TRANSACTION语句。
COMMIT语句终止事务,永久保存数据库的变化,同时释放所有LOCK,ROLLBACK终止现行事务释放所有LOCK,但不保存数据库的任何变化,SAVEPOINT用于设置中间点,当事务调用过多的数据库操作时,中间点是非常有用的,SET TRANSACTION用于设置事务属性,比如read-write和隔离级等。

显式游标
当查询返回结果超过一行时,就需要一个显式游标,此时用户不能使用select into语句。PL/SQL管理隐式游标,当查询开始时隐式游标打开,查询结束时隐式游标自动关闭。显式游标在PL/SQL块的声明部分声明,在执行部分或异常处理部分打开,取数据,关闭。

使用游标
这里要做一个声明,我们所说的游标通常是指显式游标,因此从现在起没有特别指明的情况,我们所说的游标都是指显式游标。要在程序中使用游标,必须首先声明游标。

声明游标
语法:
CURSOR cursor_name IS select_statement;

在PL/SQL中游标名是一个未声明变量,不能给游标名赋值或用于表达式中。

例:
DELCARE
CURSOR C_EMP IS SELECT empno,ename,salary
FROM emp
WHERE salary>2000
ORDER BY ename;
……..
BEGIN
在游标定义中SELECT语句中不一定非要表可以是视图,也可以从多个表或视图中选择的列,甚至可以使用*来选择所有的列 。

打开游标
使用游标中的值之前应该首先打开游标,打开游标初始化查询处理。打开游标的语法是:
OPEN cursor_name
cursor_name是在声明部分定义的游标名。

例:
OPEN C_EMP;

关闭游标
语法:
CLOSE cursor_name

例:
CLOSE C_EMP;

从游标提取数据
从游标得到一行数据使用FETCH命令。每一次提取数据后,游标都指向结果集的下一行。语法如下:
FETCH cursor_name INTO variable[,variable,…]
对于SELECT定义的游标的每一列,FETCH变量列表都应该有一个变量与之相对应,变量的类型也要相同。

例:
SET SERVERIUTPUT ON
DECLARE
v_ename EMP.ENAME%TYPE;
v_salary EMP.SALARY%TYPE;
CURSOR c_emp IS SELECT ename,salary FROM emp;
BEGIN
OPEN c_emp;
FETCH c_emp INTO v_ename,v_salary;
DBMS_OUTPUT.PUT_LINE(‘Salary of Employee’|| v_ename ||’is’|| v_salary);
FETCH c_emp INTO v_ename,v_salary;
DBMS_OUTPUT.PUT_LINE(‘Salary of Employee’|| v_ename ||’is’|| v_salary);
FETCH c_emp INTO v_ename,v_salary;
DBMS_OUTPUT.PUT_LINE(‘Salary of Employee’|| v_ename ||’is’|| v_salary);
CLOSE c_emp;
END

这段代码无疑是非常麻烦的,如果有多行返回结果,可以使用循环并用游标属性为结束循环的条件,以这种方式提取数据,程序的可读性和简洁性都大为提高,下面我们使用循环重新写上面的程序:
SET SERVERIUTPUT ON
DECLARE
v_ename EMP.ENAME%TYPE;
v_salary EMP.SALARY%TYPE;
CURSOR c_emp IS SELECT ename,salary FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_ename,v_salary;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(‘Salary of Employee’|| v_ename ||’is’|| v_salary);
END

记录变量
定义一个记录变量使用TYPE命令和%ROWTYPE,关于%ROWsTYPE的更多信息请参阅相关资料。
记录变量用于从游标中提取数据行,当游标选择很多列的时候,那么使用记录比为每列声明一个变量要方便得多。
当在表上使用%ROWTYPE并将从游标中取出的值放入记录中时,如果要选择表中所有列,那么在SELECT子句中使用*比将所有列名列出来要安全得多。

例:
SET SERVERIUTPUT ON
DECLARE
R_emp EMP%ROWTYPE;
CURSOR c_emp IS SELECT * FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO r_emp;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUT.PUT.PUT_LINE(‘Salary of Employee’||r_emp.ename||’is’|| r_emp.salary);
END LOOP;
CLOSE c_emp;
END;

%ROWTYPE也可以用游标名来定义,这样的话就必须要首先声明游标:

SET SERVERIUTPUT ON
DECLARE
CURSOR c_emp IS SELECT ename,salary FROM emp;
R_emp c_emp%ROWTYPE;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO r_emp;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUT.PUT.PUT_LINE(‘Salary of Employee’||r_emp.ename||’is’|| r_emp.salary);
END LOOP;
CLOSE c_emp;
END;

带参数的游标
与存储过程和函数相似,可以将参数传递给游标并在查询中使用。这对于处理在某种条件下打开游标的情况非常有用。它的语法如下:

CURSOR cursor_name[(parameter[,parameter],…)] IS select_statement;

定义参数的语法如下:
Parameter_name [IN] data_type[{:=|DEFAULT} value]

  与存储过程不同的是,游标只能接受传递的值,而不能返回值。参数只定义数据类型,没有大小。
另外可以给参数设定一个缺省值,当没有参数值传递给游标时,就使用缺省值。游标中定义的参数只是一个占位符,在别处引用该参数不一定可靠。

在打开游标时给参数赋值,语法如下:

OPEN cursor_name[value[,value]….];
参数值可以是文字或变量。

例:
DECALRE
CURSOR c_dept IS SELECT * FROM dept ORDER BY deptno;
CURSOR c_emp (p_dept VARACHAR2) IS
SELECT ename,salary
FROM emp
WHERE deptno=p_dept
ORDER BY ename
r_dept DEPT%ROWTYPE;
v_ename EMP.ENAME%TYPE;
v_salary EMP.SALARY%TYPE;
v_tot_salary EMP.SALARY%TYPE;
BEGIN
OPEN c_dept;
LOOP
FETCH c_dept INTO r_dept;
EXIT WHEN c_dept%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(‘Department:’|| r_dept.deptno||’-‘||r_dept.dname);
v_tot_salary:=0;
OPEN c_emp(r_dept.deptno);
LOOP
FETCH c_emp INTO v_ename,v_salary;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(‘Name:’|| v_ename||’ salary:’||v_salary);
v_tot_salary:=v_tot_salary+v_salary;
END LOOP;
CLOSE c_emp;
DBMS_OUTPUT.PUT_LINE(‘Toltal Salary for dept:’|| v_tot_salary);
END LOOP;
CLOSE c_dept;
END;

游标FOR循环
在大多数时候我们在设计程序的时候都遵循下面的步骤:
1、打开游标
2、开始循环
3、从游标中取值
4、检查那一行被返回
5、处理
6、关闭循环
7、关闭游标
可以简单的把这一类代码称为游标用于循环。但还有一种循环与这种类型不相同,这就是FOR循环,用于FOR循环的游标按照正常的声明方式声明,它的优点在于不需要显式的打开、关闭、取数据,测试数据的存在、定义存放数据的变量等等。游标FOR循环的语法如下:

FOR record_name IN
(corsor_name[(parameter[,parameter]…)]
| (query_difinition)
LOOP
statements
END LOOP;

下面我们用for循环重写上面的例子:
DECALRE
CURSOR c_dept IS SELECT deptno,dname FROM dept ORDER BY deptno;
CURSOR c_emp (p_dept VARACHAR2) IS
SELECT ename,salary
FROM emp
WHERE deptno=p_dept
ORDER BY ename
v_tot_salary EMP.SALARY%TYPE;
BEGIN
FOR r_dept IN c_dept LOOP
DBMS_OUTPUT.PUT_LINE(‘Department:’|| r_dept.deptno||’-‘||r_dept.dname);
v_tot_salary:=0;
FOR r_emp IN c_emp(r_dept.deptno) LOOP
DBMS_OUTPUT.PUT_LINE(‘Name:’ || v_ename || ‘salary:’ || v_salary);
v_tot_salary:=v_tot_salary+v_salary;
END LOOP;
DBMS_OUTPUT.PUT_LINE(‘Toltal Salary for dept:’|| v_tot_salary);
END LOOP;
END;

在游标FOR循环中使用查询
在游标FOR循环中可以定义查询,由于没有显式声明所以游标没有名字,记录名通过游标查询来定义。
DECALRE
v_tot_salary EMP.SALARY%TYPE;
BEGIN
FOR r_dept IN (SELECT deptno,dname FROM dept ORDER BY deptno) LOOP
DBMS_OUTPUT.PUT_LINE(‘Department:’|| r_dept.deptno||’-‘||r_dept.dname);
v_tot_salary:=0;
FOR r_emp IN (SELECT ename,salary
   FROM emp
   WHERE deptno=p_dept
   ORDER BY ename) LOOP
DBMS_OUTPUT.PUT_LINE(‘Name:’|| v_ename||’ salary:’||v_salary);
v_tot_salary:=v_tot_salary+v_salary;
END LOOP;
DBMS_OUTPUT.PUT_LINE(‘Toltal Salary for dept:’|| v_tot_salary);
END LOOP;
END;

游标中的子查询
语法如下:

CURSOR C1 IS SELECT * FROM emp
WHERE deptno NOT IN (SELECT deptno
FROM dept
WHERE dname!=’ACCOUNTING’);
可以看出与SQL中的子查询没有什么区别。

游标中的更新和删除
在PL/SQL中依然可以使用UPDATE和DELETE语句更新或删除数据行。显式游标只有在需要获得多行数据的情况下使用。PL/SQL提供了仅仅使用游标就可以执行删除或更新记录的方法。
UPDATE或DELETE语句中的WHERE CURRENT OF子串专门处理要执行UPDATE或DELETE操作的表中取出的最近的数据。要使用这个方法,在声明游标时必须使用FOR UPDATE子串,当对话使用FOR UPDATE子串打开一个游标时,所有返回集中的数据行都将处于行级(ROW-LEVEL)独占式锁定,其他对象只能查询这些数据行,不能进行UPDATE、DELETE或SELECT…FOR UPDATE操作。

语法:
FOR UPDATE [OF [schema.]table.column[,[schema.]table.column]..
[nowait]

在多表查询中,使用OF子句来锁定特定的表,如果忽略了OF子句,那么所有表中选择的数据行都将被锁定。如果这些数据行已经被其他会话锁定,那么正常情况下ORACLE将等待,直到数据行解锁。

在UPDATE和DELETE中使用WHERE CURRENT OF子串的语法如下:

WHERE{CURRENT OF cursor_name|search_condition}

例:
DELCARE
CURSOR c1 IS SELECT empno,salary
FROM emp
WHERE comm IS NULL
FOR UPDATE OF comm;
v_comm NUMBER(10,2);
BEGIN
FOR r1 IN c1 LOOP
IF r1.salary<500 THEN v_comm:=r1.salary*0.25; ELSEIF r1.salary<1000 THEN v_comm:=r1.salary*0.20; ELSEIF r1.salary<3000 THEN v_comm:=r1.salary*0.15; ELSE v_comm:=r1.salary*0.12; END IF; UPDATE emp; SET comm=v_comm WHERE CURRENT OF c1l; END LOOP; END

评论关闭
发表于: os/software | 作者: | 日期: 2008/11/04 02:11
标签:

最简单的办法:
1 开始—运行—gpedit.msc
2 用户配置—管理模板—桌面—双击“从桌面删除‘回收站’选择已启用
3 刷新桌面

评论关闭
发表于: os/software | 作者: | 日期: 2008/11/03 01:11
标签: ,

Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.

C:\Documents and Settings\Administrator>netstat help

显示协议统计信息和当前 TCP/IP 网络连接。

NETSTAT [-a] [-b] [-e] [-n] [-o] [-p proto] [-r] [-s] [-v] [interval]

-a 显示所有连接和监听端口。
-b 显示包含于创建每个连接或监听端口的
可执行组件。在某些情况下已知可执行组件
拥有多个独立组件,并且在这些情况下
包含于创建连接或监听端口的组件序列
被显示。这种情况下,可执行组件名
在底部的 [] 中,顶部是其调用的组件,
等等,直到 TCP/IP 部分。注意此选项
可能需要很长时间,如果没有足够权限
可能失败。
-e 显示以太网统计信息。此选项可以与 -s
选项组合使用。
-n 以数字形式显示地址和端口号。
-o 显示与每个连接相关的所属进程 ID。
-p proto 显示 proto 指定的协议的连接;proto 可以是
下列协议之一: TCP、UDP、TCPv6 或 UDPv6。
如果与 -s 选项一起使用以显示按协议统计信息,proto 可以是下列协议
之一:
IP、IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 或 UDPv6。
-r 显示路由表。
-s 显示按协议统计信息。默认地,显示 IP、
IPv6、ICMP、ICMPv6、TCP、TCPv6、UDP 和 UDPv6 的统计信息;
-p 选项用于指定默认情况的子集。
-v 与 -b 选项一起使用时将显示包含于
为所有可执行组件创建连接或监听端口的
组件。
interval 重新显示选定统计信息,每次显示之间
暂停时间间隔(以秒计)。按 CTRL+C 停止重新
显示统计信息。如果省略,netstat 显示当前
配置信息(只显示一次)

C:\Documents and Settings\Administrator>^A

评论关闭
发表于: os/software | 作者: | 日期: 2008/11/03 01:11

Manipulates network routing tables.

ROUTE [-f] [-p] [command [destination] [MASK netmask] [gateway] [METRIC metric] [IF interface]

-f
Clears the routing tables of all gateway entries. If this is used in conjunction with one of the commands, the tables are cleared prior to running the command.

-p
When used with the ADD command, makes a route persistent across boots of the system. By default, routes are not preserved when the system is restarted. Ignored for all other commands, which always affect the appropriate persistent routes. This option is not supported in Windows 95.

command
One of these:
PRINT Prints a route
ADD Adds a route
DELETE Deletes a route
CHANGE Modifies an existing route

destination Specifies the host.

MASK
Specifies that the next parameter is the ‘netmask’ value.

netmask
Specifies a subnet mask value for this route entry.
If not specified, it defaults to 255.255.255.255.

gateway
Specifies gateway.

interface
the interface number for the specified route.

METRIC
specifies the metric, ie. cost for the destination.

All symbolic names used for destination are looked up in the network database file NETWORKS. The symbolic names for gateway are looked up in the host name database file HOSTS.

If the command is PRINT or DELETE. Destination or gateway can be a wildcard, (wildcard is specified as a star ‘*’), or the gateway argument may be omitted.

If Dest contains a * or ?, it is treated as a shell pattern, and only
matching destination routes are printed. The ‘*’ matches any string,
and ‘?’ matches any one char. Examples: 157.*.1, 157.*, 127.*, *224*.
Diagnostic Notes:
Invalid MASK generates an error, that is when (DEST & MASK) != DEST.
Example> route ADD 157.0.0.0 MASK 155.0.0.0 157.55.80.1 IF 1
The route addition failed: The specified mask parameter is invalid.
(Destination & Mask) != Destination.

Examples:

> route PRINT
> route ADD 157.0.0.0 MASK 255.0.0.0 157.55.80.1 METRIC 3 IF 2
destination^ ^mask ^gateway metric^ ^
Interface^
If IF is not given, it tries to find the best interface for a given
gateway.
> route PRINT
> route PRINT 157* …. Only prints those matching 157*
> route CHANGE 157.0.0.0 MASK 255.0.0.0 157.55.80.5 METRIC 2 IF 2

CHANGE is used to modify gateway and/or metric only.
> route PRINT
> route DELETE 157.0.0.0
> route PRINT

评论关闭
发表于: java/j2ee | 作者: | 日期: 2008/11/03 10:11
标签:

J2EE应用中与Oracle数据库的连接
在J2EE应用程序开发中,应用程序与数据库连接的建立是我们经常遇到的问题之一。在这里我主要谈谈在本地应用程序中通过OCI方式、thin方式和JdbcOdbc桥方式连接Oracle数据库,在iPlanet Application Server 6.5和Sun ONE Application Server 7中对Oracle数据库连接池的配置以及应用中如何从连接池中获得连接。
一、本地通过JDBC获得Oracle数据库连接
通过JDBC获得Oracle数据库连接,有三种方式:OCI方式、thin方式和JdbcOdbc桥方式。OCI方式依赖于本地的动态链接库,如果在本地安装了Oracle数据库客户端可以采用该方式;而thin方式为纯java的数据库连接方式;JdbcOdbc桥方式依赖于本地ODBC数据库源的配置,这种方式一般不太被采用。
1、OCI方式
先在本地安装Oracle客户端,安装完之后,在安装的路径中可以找到…/jdbc/lib/classes12.zip文件,我们在环境变量classpath中设置classes12.zip所在的路径。 然后通过以下的数据库连接类,在本地通过OCI方式获得Oracle数据库连接。
/**
* 在本地获得数据库连接
*/
package com.j2ee.db;
import java.util.*;
import java.sql.*; import javax.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
import javax.naming.*;
/**
* 通过OCI方式获得Oracle数据库连接
*/
public class DbConnection
{
  final static String sDBDriver = “oracle.jdbc.driver.OracleDriver”;
  final static String sConnStr = “jdbc:oracle:oci8:sr/sr@ora199”;
  /**
  *
  */
  public DbConnection() { }
  /**
  * 获得Oracle数据库连接
  */
  public java.sql.Connection connectDbByOci()
  {
   java.sql.Connection conn=null;
    try {
        Class.forName(sDBDriver);
        conn = DriverManager.getConnection(sConnStr);
      }
    catch (Exception e)
    {
        System.out.println(“ERROR:”+e.getMessage());
    }
    return conn;
  }
}
  在连接字符串 “jdbc:oracle:oci8:sr/sr@ora199” 中,”sr/sr”为Oracle用户的用户名和口令,”ora199″为数据库服务名。
2、thin方式
先到Oracle技术网(http://otn.oracle.com/global/cn/software/tech/java/sqlj_jdbc/index.html)下载Oracle JDBC Drivers,同样地将下载后的zip文件的路径设置在环境变量classpath。然后通过以下的数据库连接类,在本地通过thin方式获得Oracle数据库连接。
/**
* 在本地获得数据库连接
*/
package com.j2ee.db;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
import javax.naming.*;
/**
* 通过thin方式获得Oracle数据库连接
*/
public class DbConnection
{
    private String sConnStr = “”;
    /**
    * 缺省构造器
    */
    public DbConnection()
    {
         sConnStr = “jdbc:oracle:thin:@10.1.4.199:1521:ora199”;
    }
    /**
    * @param ip,serviceName
    */
    public DbConnection(String ip,String serviceName)
    {
       sConnStr = “jdbc:oracle:thin:@”+ip+”:1521:”+serviceName;
    }
    /**
    * 通过thin方式获得Oracle数据库的连接.
    */
    public java.sql.Connection connectDbByThin()
    {
         java.sql.Connection conn=null;
         try
         {
            Class.forName(sDBDriver);
            conn = DriverManager.getConnection(sConnStr,”sr”,”sr”);
         }
         catch (Exception e)
         {
            System.out.println(“ERROR:”+e.getMessage());
         }
         return conn;
    }
    /**
    *通过thin方式获得Oracle数据库的连接.
    * @param userId,password
    */
    public java.sql.Connection connectByJdbc(String userId,String password)
    {
        java.sql.Connection conn=null;
        try
        {
            Class.forName(sDBDriver);
            conn = DriverManager.getConnection(sConnStr,userId,password);
        }
        catch (Exception e)
        {
            System.out.println(“ERROR:”+e.getMessage());
        }
        return conn;
    }
}
这种方式运用起来比较灵活,简单,具有较强的移植性和适用性。只要注意连接字符串”jdbc:oracle:thin:@10.1.4.199:1521:ora199″中具体参数的设置即可。
3、JdbcOdbc桥方式
  先通过管理工具中的数据源来添加本地对Oracle数据库的连接,然后通过以下的数据库连接类,在本地通过JdbcOdbc桥方式获得Oracle数据库连接。
/**
* 在本地获得数据库连接
*/
package com.j2ee.db;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
import javax.naming.*;
/**
* 通过JdbcOdbc桥方式获得Oracle数据库连接
*/
public class DbConnection {
  /**
  *
  */
  public DbConnection()
  {
  }
  /**
  * 获得Oracle数据库连接
  */
  public java.sql.Connection connectDbByJdbcOdbcBridge()
  {
     java.sql.Connection conn=null;
     try
     {
         Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);          con=DriverManager.getConnection(“jdbc:odbc:ora199″,”sr”,”sr”);
     }
     catch (Exception e)
     {
         System.out.println(“ERROR:”+e.getMessage());
     }
     return conn;
  }
}
  在getConnection方法中第一个参数”jdbc:odbc:ora199″ 中的”ora199″为本地ODBC数据源的数据源名称,第二个参数和第三个参数分别为Oracle的用户名和口令。
二、通过连接池获得Oracle数据库连接
  这部分主要讲述在iPlanet Application Server 6.5和Sun ONE Application Server 7中Oracle数据库连接池的配置,以及在应用中如何通过连接池获得数据库的连接。
1、iPlanet Application Server 6.5连接池的配置
  先打开iPlanet Application Server 6.5的管理控制台,选中”database”面板,再选择”External JDBC Drivers”选项后,点击”Add…”按钮,在弹出的对话框中,添加一个名为”ora-type4″的JDBC Driver。

  Driver Classpath:该参数填写classes12.zip文件的物理路径。
  然后在”External JDBC DataSources”中选择”Add…”,在弹出的对话框中添加一个JNDI名称为”credit2″的数据源。

  DriverType:选择刚添加好的”ora-type4″;
  Datasource:ora199,为Oracle数据库服务名;
  Connection Pool Parameters:图中显示的是缺省设置,可以根据自己环境情况来更改这些设置。
  保存完设置后,在”DataSource Selection Box”中,选择刚添加的”credit2″数据源,再选择”Vendor Specific Properties”按钮。在对话中添加一个URL属性。

  至此,iPlanet Application Server 6.5中的数据库连接池配置完毕,重起服务使之生效。
2、Sun ONE Application Server 7连接池的配置
  在配置之前将classes12.zip文件置于…/server1/lib目录下。通过浏览器的4848端口打开Sun ONE Application Server 7的管理界面,选择”server1″->”JDBC”-> “Connection Pools”下的”New…”

  添加一个名称为”MyConnectionPool”的Oracle数据库连接池。”Next”下一步。

  在”General”中填写”Datasource Classname”。

  在”Properties”中将不需要的属性删除,同时添加”URL”属性。
  ”dataSourceName”中填写Oracle数据库服务名。
  以下连接池的缺省设置,可以根据自己环境的情况作相应的调整。

选择”Finish”完成连接池的设置。
下一步为”MyConnectionPool”连接池创建一个JNDI,以便应用程序能够通过该名称获得连接池中的连接。 “server1″->”JDBC”-> “JDBC Resources”下的”New…”

  至此,Sun ONE Application Server7中的数据库连接池配置完毕,重起服务使之生效。
3、通过连接池获得连接
  以上在iPlanet Application Server 6.5和Sun ONE Application Server7中配置的连接池都可以通过以下的数据库连接类,从连接池中获得Oracle数据库连接。
/**
* 从连接池中获得数据库连接
*/
package com.j2ee.db;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
import javax.naming.*;
/**
* 通过连接池方式获得Oracle数据库连接
*/
public class DbConnection {
  /**
  *
  */
  public DbConnection()
  {
  }
  /**
  * 获得Oracle数据库连接
  */
  public java.sql.Connection connectDbByConnectionPool()
  {
     java.sql.Connection conn=null;
     try
     {
        Context ctx = new InitialContext();
        DataSource ds = (DataSource)ctx.lookup(“jdbc/credit2”);
        conn=ds.getConnection();
     }
     catch (Exception e)
     {
        System.out.println(“ERROR:”+e.getMessage());
     }
     return conn;
  }
}
4、使用连接池的优点
使用连接池的优点主要体现在两个方面:
1. 对数据库的连接统一进行配置、管理、监控,以及对数据库连接池的参数进行优化调整,同时对应用中没有关闭或其他原因造成没有关闭的数据库连接由连接池统一进行管理。
2. 便于应用的移植和后端数据库的切换,因为在应用中通过统一的JNDI获得数据库的连接,而具体连接的是哪一台机器上的数据库与应用无关。
作者:洪建
URL:http://www.dbonline.cn/source/oracle/20040404/OTHER_J2EE%20CONNECT%20ORACLE.htm

评论关闭
发表于: java/j2ee | 作者: | 日期: 2008/11/03 10:11
标签:

JDBC编程学习笔记
1:JDBC概述
JDBC 是一种用于执行 SQL 语句的 Java API,JDBC 为工具/数据库开发人员提供了一个标准的 API,使他们能够用纯Java API 来编写数据库应用程序。简单地说,JDBC 可做三件事:(1)与数据库建立连接,(2)发送 SQL 语句,(3)处理结果。

2: JDBC驱动程序的类型

(1)JDBC-ODBC桥加ODBC驱动程序
JavaSoft桥产品利用ODBC驱动程序提供JDBC访问。注意,必须将ODBC二进制代码(许多情况下还包括数据库客户机代码)加载到使用该驱动程序的每个客户机上。因此,这种类型的驱动程序最适合于企业网(这种网络上客户机的安装不是主要问题),或者是用Java编写的三层结构的应用程序服务器代码。

(2)本地API
这种类型的驱动程序把客户机API上的JDBC调用转换为Oracle、Sybase、Informix、DB2或其它DBMS的调用。注意,象桥驱动程序一样,这种类型的驱动程序要求将某些二进制代码加载到每台客户机上。

(3)JDBC网络纯Java驱动程序
这种驱动程序将JDBC转换为与DBMS无关的网络协议,之后这种协议又被某个服务器转换为一种DBMS协议。这种网络服务器中间件能够将它的纯Java客户机连接到多种不同的数据库上。所用的具体协议取决于提供者。通常,这是最为灵活的JDBC驱动程序。有可能所有这种解决方案的提供者都提供适合于Intranet用的产品。为了使这些产品也支持Internet访问,它们必须处理Web所提出的安全性、通过防火墙的访问等方面的额外要求。几家提供者正将JDBC驱动程序加到他们现有的数据库中间件产品中。

(4)本地协议纯Java驱动程序
这种类型的驱动程序将JDBC调用直接转换为DBMS所使用的网络协议。这将允许从客户机机器上直接调用DBMS服务器,是Intranet访问的一个很实用的解决方法。由于许多这样的协议都是专用的,因此数据库提供者自己将是主要来源,有几家提供者已在着手做这件事了。

据专家预计第(3)、(4)类驱动程序将成为从JDBC访问数据库的首方法。第(1)、(2)类驱动程序在直接的纯Java驱动程序还没有上市前会作为过渡方案来使用。对第(1)、(2)类驱动程序可能会有一些变种,这些变种要求有连接器,但通常这些是更加不可取的解决方案。第(3)、(4)类驱动程序提供了Java的所有优点,包括自动安装(例如,通过使用JDBC驱动程序的applet来下载该驱动程序)。

3:JDBC数据库访问步骤
简单示例程序如下:
package employeetree.db.main;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class DbDriver {

//连接字符串
private static final String strDriver = “oracle.jdbc.driver.OracleDriver”;
private static final String strPassword = “duckbill61_a”;
private static final String strUrl = “jdbc:oracle:thin:@172.20.92.2:1521:ora9i”;
private static final String strUsername = “duckbill61_a”;

public static void main(String[] args){
Connection conn = null;
try{
Class.forName(strDriver);
conn = DriverManager.getConnection(strUrl,strUsername,strPassword);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(“select * from employee”);
while(rs.next()){
System.out.println(rs.getInt(1));
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}

(1)注册驱动程序
(2)建立连接
(3)发送SQL语句
(5)处理返回集
(6)善后处理

4:JDBC常用对象
DriverManager
DriverManager 类是 JDBC 的管理层,作用于用户和驱动程序之间。它跟踪可用的驱动程序,并在数据库和相应驱动程序之间建立连接。另外,DriverManager类也处理诸如驱动程序登录时间限制及登录和跟踪消息的显示等事务。
对于简单的应用程序,一般程序员需要在此类中直接使用的唯一方法是DriverManager.getConnection。正如名称所示,该方法将建立与数据库的连接。JDBC允许用户调用DriverManager的方法getDriver、getDrivers和registerDriver及Driver的方法connect。但多数情况下,让DriverManager类管理建立连接的细节为上策。

Connection
Connection 对象代表与数据库的连接。连接过程包括所执行的 SQL 语句和在该连接上所返回的结果。一个应用程序可与单个数据库有一个或多个连接,或者可与许多数据库有连接。2.1.1 打开连接与数据库建立连接的标准方法是调用DriverManager.getConnection方法。该方法接受含有某个 URL 的字符串。DriverManager 类(即所谓的 JDBC管理层)将尝试找到可与那个 URL 所代表的数据库进行连接的驱动程序。DriverManager 类存有已注册的 Driver 类的清单。当调用方法 getConnection 时,它将检查清单中的每个驱动程序,直到找到可与URL 中指定的数据库进行连接的驱动程序为止。Driver 的方法connect 使用这个 URL来建立实际的连接。

Statement
Statement对象用于将SQL语句发送到数据库中。实际上有三种Statement对象,它们都作为在给定连接上执行SQL语句的包装器:Statement、PreparedStatement(它从Statement继承而来)和CallableStatement(它从PreparedStatement继承而来)。它们都专用于发送特定类型的SQL语句:Statement对象用于执行不带参数的简单SQL语句;PreparedStatement对象用于执行带或不带IN参数的预编译SQL语句;CallableStatement对象用于执行对数据库已存储过程的调用。

Statement接口提供了执行语句和获取结果的基本方法;PreparedStatement接口添加了处理IN参数的方法;而CallableStatement添加了处理OUT参数的方法。

创建Statement对象
建立了到特定数据库的连接之后,就可用该连接发送SQL语句。Statement对象用Connection的方法createStatement创建,如下列代码段中所示:

Connection con = DriverManager.getConnection(url,”sunny”,””);
Statement stmt = con.createStatement();

为了执行Statement对象,被发送到数据库的SQL语句将被作为参数提供给Statement的方法:
ResultSet rs = stmt.executeQuery(”SELECT a,b,c FROM Table2″);

使用Statement对象执行语句
Statement接口提供了三种执行SQL语句的方法:executeQuery、executeUpdate和execute。使用哪一个方法由SQL语句所产生的内容决定。
方法executeQuery用于产生单个结果集的语句,例如SELECT语句。方法executeUpdate用于执行INSERT、UPDATE或DELETE语句以及SQL DDL(数据定义语言)语句,例如CREATE TABLE和DROP TABLE。INSERT、UPDATE或DELETE语句的效果是修改表中零行或多行中的一列或多列。executeUpdate的返回值是一个整数,指示受影响的行数(即更新计数)。对于CREATE TABLE或DROP TABLE等不操作行的语句,executeUpdate的返回值总为零。
执行语句的所有方法都将关闭所调用的Statement对象的当前打开结果集(如果存在)。这意味着在重新执行Statement对象之前,需要完成对当前ResultSet对象的处理。应注意,继承了Statement接口中所有方法的PreparedStatement接口都有自己的executeQuery、executeUpdate和execute方法。Statement对象本身不包含SQL语句,因而必须给Statement.execute方法提供SQL语句作为参数。PreparedStatement对象并不需要SQL语句作为参数提供给这些方法,因为它们已经包含预编译SQL语句。

CallableStatement对象继承这些方法的PreparedStatement形式。对于这些方法的PreparedStatement或CallableStatement版本,使用查询参数将抛出SQLException。

语句完成
当连接处于自动提交模式时,其中所执行的语句在完成时将自动提交或还原。语句在已执行且所有结果返回时,即认为已完成。对于返回一个结果集的executeQuery方法,在检索完ResultSet对象的所有行时该语句完成。对于方法executeUpdate,当它执行时语句即完成。但在少数调用方法execute的情况中,在检索所有结果集或它生成的更新计数之后语句才完成。
有些DBMS将已存储过程中的每条语句视为独立的语句;而另外一些则将整个过程视为一个复合语句。在启用自动提交时,这种差别就变得非常重要,因为它影响什么时候调用commit方法。在前一种情况中,每条语句单独提交;在后一种情况中,所有语句同时提交。

关闭Statement对象
Statement对象将由Java垃圾收集程序自动关闭。而作为一种好的编程风格,应在不需要Statement对象时显式地关闭它们。这将立即释放DBMS资源,有助于避免潜在的内存问题。

使用方法execute
execute方法应该仅在语句能返回多个ResultSet对象、多个更新计数或ResultSet对象与更新计数的组合时使用。当执行某个已存储过程或动态执行未知SQL字符串(即应用程序程序员在编译时未知)时,有可能出现多个结果的情况,尽管这种情况很少见。例如,用户可能执行一个已存储过程,并且该已存储过程可执行更新,然后执行选择,再进行更新,再进行选择,等等。通常使用已存储过程的人应知道它所返回的内容。

因为方法execute处理非常规情况,所以获取其结果需要一些特殊处理并不足为怪。例如,假定已知某个过程返回两个结果集,则在使用方法execute执行该过程后,必须调用方法getResultSet获得第一个结果集,然后调用适当的getXXX方法获取其中的值。要获得第二个结果集,需要先调用getMoreResults方法,然后再调用getResultSet方法。如果已知某个过程返回两个更新计数,则首先调用方法getUpdateCount,然后调用getMoreResults,并再次调用getUpdateCount。

对于不知道返回内容,则情况更为复杂。如果结果是ResultSet对象,则方法execute返回true;如果结果是Javaint,则返回false。如果返回int,则意味着结果是更新计数或执行的语句是DL命令。在调用方法execute之后要做的第一件事情是调用getResultSet或getUpdateCount。调用方法getResultSet可以获得两个或多个ResultSet对象中第一个对象;或调用方法getUpdateCount可以获得两个或多个更新计数中第一个更新计数的内容。

当SQL语句的结果不是结果集时,则方法getResultSet将返回null。这可能意味着结果是一个更新计数或没有其它结果。在这种情况下,判断null真正含义的唯一方法是调用方法getUpdateCount,它将返回一个整数。这个整数为调用语句所影响的行数;如果为-1则表示结果是结果集或没有结果。如果方法getResultSet已返回null(表示结果不是ResultSet对象),则返回值-1表示没有其它结果。也就是说,当下列条件为真时表示没有结果(或没有其它结果):

  ((stmt.getResultSet()==null)&&(stmt.getUpdateCount()==-1))

  如果已经调用方法getResultSet并处理了它返回的ResultSet对象,则有必要调用方法getMoreResults以确定是否有其它结果集或更新计数。如果getMoreResults返回true,则需要再次调用getResultSet来检索下一个结果集。如上所述,如果getResultSet返回null,则需要调用getUpdateCount来检查null是表示结果为更新计数还是表示没有其它结果。

  当getMoreResults返回false时,它表示该SQL语句返回一个更新计数或没有其它结果。因此需要调用方法getUpdateCount来检查它是哪一种情况。在这种情况下,当下列条件为真时表示没有其它结果:

  ((stmt.getMoreResults()==false)&&(stmt.getUpdateCount()==-1))

  下面的代码演示了一种方法用来确认已访问调用方法execute所产生的全部结果集和更新计数:

stmt.execute(queryStringWithUnknownResults);
while(true){
introwCount=stmt.getUpdateCount();
if(rowCount>0){//它是更新计数
System.out.println(”Rows changed=”+count);
stmt.getMoreResults();
continue;
}
if(rowCount==0){//DDL命令或0个更新
System.out.println(”No rows changed or statement was DDL command”);
stmt.getMoreResults();
continue;
}
//执行到这里,证明有一个结果集
//或没有其它结果
ResultSet rs=stmt.getResultSet();
if(rs!=null){
…//使用元数据获得关于结果集列的信息
while(rs.next()){
…//处理结果
stmt.getMoreResults();
continue;
}
break;//没有其它结果

评论关闭