2010年1月14日 星期四

How to call Java in Oracle

任何转载,请尊重版权。(作者:iihero on csdn)

一、如何创建java存储过程?
通常有三种方法来创建java存储过程。

1. 使用oracle的sql语句来创建:

e.g. 使用create or replace and compile java source named "" as
后边跟上java源程序。要求类的方法必须是public static的,才能用于存储过程。

SQL> create or replace and compile java source named "javademo1"
2 as
3 import java.sql.*;
4 public class JavaDemo1
5 {
6 public static void main(String[] argv)
7 {
8 System.out.println("hello, java demo1");
9 }
10 }
11 /

Java 已创建。

SQL
> show errors java source "javademo1"
没有错误。

SQL
> create or replace procedure javademo1
2 as
3 language java name 'JavaDemo1.main(java.lang.String[])';
4 /

过程已创建。

SQL
> set serveroutput on
SQL
> call javademo1();

调用完成。

SQL
> call dbms_java.set_output(5000);

调用完成。

SQL
> call javademo1();
hello, java demo1

调用完成。

SQL
> call javademo1();
hello, java demo1
调用完成。

2. 使用外部class文件来装载创建
e.g. 这里既然用到了外部文件,必然要将class文件放到oracle Server的某一目录下边。

public class OracleJavaProc
{
public static void main(String[] argv)
{
System.out.println("It
's a Java Oracle procedure.");
}
}


SQL> grant create any directory to scott;

授权成功。

SQL> conn scott/tiger@iihero.oracledb
已连接。
SQL> create or replace directory test_dir as
'd:\oracle';

目录已创建。

SQL> create or replace java class using bfile(test_dir,
'OracleJavaProc.CLASS')
2 /

Java 已创建。

SQL> create or replace procedure testjavaproc as language java name
'OracleJavaProc.main(java.lang.String[])';
2 /

过程已创建。

SQL> call testjavaproc();

调用完成。

SQL> execute testjavaproc;

PL/SQL 过程已成功完成。

SQL> set serveroutput on size 5000
SQL> call dbms_java.set_output(5000);

调用完成。

SQL> execute testjavaproc;
It
's a Java Oracle procedure.

3. 我推荐的一种方法,直接使用loadjava命令远程装载并创建。
先创建一个类, e.g.

import java.sql.*;
import oracle.jdbc.*;

public class OracleJavaProc {

//Add a salgrade to the database.
public static void addSalGrade(int grade, int losal, int hisal) {

System.out.println(
"Creating new salgrade for EMPLOYEE...");

try {
Connection conn
=
DriverManager.getConnection(
"jdbc:default:connection:");

String sql
=
"INSERT INTO salgrade " +
"(GRADE,LOSAL,HISAL) " +
"VALUES(?,?,?)";
PreparedStatement pstmt
= conn.prepareStatement(sql);
pstmt.setInt(
1,grade);
pstmt.setInt(
2,losal);
pstmt.setInt(
3,hisal);
pstmt.executeUpdate();
pstmt.close();
}

catch(SQLException e) {
System.err.println(
"ERROR! Adding Salgrade: "
+ e.getMessage());
}

}

}

使用loadjava命令将其装载到服务器端并编译:

D:eclipse3.1workspacedbtest>loadjava -u scott/tiger@iihero.oracledb -v -resolve Or
acleJavaProc
.java
arguments: '-u' 'scott
/tiger@iihero.oracledb '-v' '-resolve' 'OracleJavaProc.java'
creating : source OracleJavaProc
loading : source OracleJavaProc
resolving: source OracleJavaProc

查询一下状态:

连接到:
Oracle9i Enterprise Edition Release
9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release
9.2.0.1.0 - Production

SQL
> SELECT object_name, object_type, status FROM user_objects WHERE object_type LIKE 'JAVA%';

OBJECT_NAME
--------------------------------------------------------------------------------

OBJECT_TYPE STATUS
------------------------------------ --------------
OracleJavaProc
JAVA CLASS VALID

OracleJavaProc
JAVA SOURCE VALID

测试一下存储过程:

SQL> create or replace procedure add_salgrade(id number, losal number, hisal num
ber)
as language java name 'OracleJavaProc.addSalGrade(int, int, int)';
2 /

过程已创建。

SQL
> set serveroutput on size 2000
SQL
> call dbms_java.set_output(2000);

调用完成。

SQL
> execute add_salgrade(6, 10000, 15000);
Creating new salgrade
for EMPLOYEE...

PL
/SQL 过程已成功完成。

SQL
> select * from salgrade where grade=6;

GRADE LOSAL HISAL
---------- ---------- ----------
6 10000 15000

二、如何更新你已经编写的java存储过程?

假如要往类OracleJavaProc里添加一个存储过程方法,如何开发?
正确的步骤应该是先dropjava, 改程序,再loadjava。

e.g.修改OracleJavaProc类内容如下:

import java.sql.*;
import oracle.jdbc.*
;

public class OracleJavaProc
{

// Add a salgrade to the database.

public static void addSalGrade(int grade, int losal, int hisal) {

System.out.println(
"Creating new salgrade for EMPLOYEE..."
);

try
{
Connection conn
=

DriverManager.getConnection(
"jdbc:default:connection:");

String sql
=

"INSERT INTO salgrade " +
"(GRADE,LOSAL,HISAL) " +
"VALUES(?,?,?)";
PreparedStatement pstmt
=
conn.prepareStatement(sql);
pstmt.setInt(
1
,grade);
pstmt.setInt(
2
,losal);
pstmt.setInt(
3
,hisal);
pstmt.executeUpdate();
pstmt.close();
}

catch(SQLException e) {
System.err.println(
"ERROR! Adding Salgrade: "

+
e.getMessage());
}

}


public static int getHiSal(int grade)
{
try
{
Connection conn
=

DriverManager.getConnection(
"jdbc:default:connection:");
String sql
= "SELECT hisal FROM salgrade WHERE grade = ?"
;
PreparedStatement pstmt
=
conn.prepareStatement(sql);pstmt.setInt(1, grade);
ResultSet rset
=
pstmt.executeQuery();
int res = 0
;
if
(rset.next())
{
res
= rset.getInt(1
);
}

rset.close();
return res;
}
catch
(SQLException e)
{
System.err.println(
"ERROR! Querying Salgrade: "

+
e.getMessage());
return -1;
}

}


}

如何更新呢?

D:eclipse3.1workspacedbtest>dropjava -u scott -v OracleJavaProc

D:
/
tiger@iihero.oracledbeclipse3.1workspacedbtest>loadjava -u scott -v -resolve Or
acleJavaProc
/
tiger@iihero.oracledb.java
arguments: '-u' 'scott
/tiger@iihero.oracledb' '-v' '-resolve' 'OracleJavaProc.
java'
creating : source OracleJavaProc
loading : source OracleJavaProc
resolving: source OracleJavaProc

后边的应用示例:

SQL> create or replace function query_hisal(grade number) return number as langu
age java name
'OracleJavaProc.getHiSal(int) return int'
;
2 /


函数已创建。

SQL
> set serveroutput on size 2000
SQL
> call dbms_java.set_output(2000);

调用完成。
SQL
> select query_hisal(5) from
dual;

QUERY_HISAL(
5
)
--------------

9999



Source: http://blog.csdn.net/iihero

2010年1月13日 星期三

測試oracle直接call java程式

當初oracle提供這個功能是為了讓java的程式師可方便寫的一些功能在oracle中使用,這樣子也就可不必學pl/sql了
但我暫時還沒有找到效能上的差別是多少的官方資料。
不過有做過就記錄一下,以免以後真的遇到還要上網找資料


1、先寫一個很簡單的java程式 (檔名叫 test.java,請注意大小寫)
public class test
{
public static void main(String[] a) {
System.out.println("this is java");
}
}

2、編譯成class
D:\>javac test.java

3、查看一下是否ok
D:\>dir test.*
磁碟區 D 中的磁碟是 本機磁碟
磁碟區序號: 7098-7819

目錄: D:\

2007-03-14 11:38a 414 test.class
2007-03-14 11:37a 120 test.java
2 個檔案 534 位元組
0 個目錄 9,290,588,160 位元組可用

4、進sqlplus了
D:\>sqlplus sys/binhu as sysdba

SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 3月 14 11:41:20 2007

Copyright (c) 1982, 2005, Oracle. All rights reserved.

連線至閒置的執行處理.

SQL> startup
ORACLE 執行處理已啟動.

Total System Global Area 201326592 bytes
Fixed Size 1248092 bytes
Variable Size 92275876 bytes
Database Buffers 104857600 bytes
Redo Buffers 2945024 bytes
資料庫已掛載.
資料庫已開啟.

5、建立相關的別名跟設定
SQL> create or replace directory java_dir as 'd:\';

已建立目錄.

SQL> create or replace java class using bfile(java_dir,'test.class');
2 /

已建立 Java.

SQL> create or replace procedure test_java as language java name 'test.main(java.lang.String[])';
2 /

已建立程序.

6、準備測試了
SQL> set serveroutput on size 2000
SQL> call dbms_java.set_output(2000);

已完成呼叫.

SQL> execute test_java;
this is java

已順利完成 PL/SQL 程序.

SQL> call test_java();
this is java

已完成呼叫.


心得:
使用上還算簡單,但真正上線的db會有多少人讓java在上面跑呢,因為這又多了一個變數
到時db掛了,還要多花心力去查看是否是由java引起的問題=.="
除非oracle有大力推行跟公司有規定使用的話,不然我還是不會讓java跑在db上的


source: http://blog.roodo.com/mywork/archives/2851269.html

2010年1月6日 星期三

溫哥華2010奧運會網站選擇使用的JavaFX來創建其網站

溫哥華2010奧運會網站選擇使用的JavaFX來創建其網站

強大得用戶界面和出色的應用,展現JavaFX的在數據可視化方面的潛力。

http://www.vancouver2010.com/olympic-medals/geo-view/

2010年1月5日 星期二

關閉某個用戶的Oracle連接

最近開髮用的Weblogic的JNDI數據源連接,可是JNDI沒有自動回收連接的功能!
項目不知道哪裡代碼寫的時候沒有關閉連接,造成有些連接是死連接
這樣很容易造成數據庫崩潰或者沒連接

思路就是想把這個項目的用戶都關閉,回收資源

運行PL/SQL命令

SELECT s.Sid, s.Serial#,p.spid, s.USERNAME,s.OSUser,
s.Program FROM V$Process p,V$session s WHERE p.addr=s.paddr(+) ORDER BY s.Sid


有人用
alter system kill session 'sid,serial#' ;這個命令來殺死,可是資源不立刻回收


運行下面的語句就可以回收資源
查出連接用戶後,在CMD中輸入orakill 數據庫名SPID(EXP:orakill orcl XXX)


source: http://www.blogjava.net/czmchen/