第一,创建orcale中的java对象.
命令:
create or replace and compile java source named "TransMetaData"
as
/*
java code
*/
注意:1.不用写包名.
2.方法必须是static的
3.如果方法需要参数,则需要在第二步,创建带参数的存储过程.
如果方法需要返回值,则需要在第二步,创建带返回值的存储过程.
例如:
create or replace and compile java source named "TransMetaData"
as
import java.io.*;
import java.sql.*;
import java.util.Properties;
import oracle.jdbc.driver.OracleDriver;
public class TransMetaData {
/**
* @param args
* @throws SQLException
* @throws UnsupportedEncodingException
*/
public static void donow(String str) throws FileNotFoundException, IOException,SQLException, UnsupportedEncodingException {
str = "_"+str;
Properties props = new Properties();
props.load(new FileInputStream("c:/tables.properties"));
String DATABAST_SOURCE_URL = props.getProperty("DATABAST_SOURCE_URL"+str);
String DATABAST_SOURCE_USERNAME = props.getProperty("DATABAST_SOURCE_USERNAME"+str);
String DATABAST_SOURCE_PASSWORD = props.getProperty("DATABAST_SOURCE_PASSWORD"+str);
String DATABAST_TARGET_URL = props.getProperty("DATABAST_TARGET_URL"+str);
String DATABAST_TARGET_USERNAME = props.getProperty("DATABAST_TARGET_USERNAME"+str);
String DATABAST_TARGET_PASSWORD = props.getProperty("DATABAST_TARGET_PASSWORD"+str);
String SQL_SOURCE_TABLENAME = props.getProperty("SQL_SOURCE_TABLENAME"+str);
String SQL_TARGET_TABLENAME = props.getProperty("SQL_TARGET_TABLENAME"+str);
String SQL_TABLE_FIELD = props.getProperty("SQL_TABLE_FIELD"+str);
Connection conn = null;
Connection conn_to = null;
DriverManager.registerDriver(new OracleDriver());
conn = DriverManager.getConnection(DATABAST_SOURCE_URL,DATABAST_SOURCE_USERNAME,DATABAST_SOURCE_PASSWORD);
conn_to = DriverManager.getConnection(DATABAST_TARGET_URL,DATABAST_TARGET_USERNAME,DATABAST_TARGET_PASSWORD);
if (!conn.isClosed()&&!conn_to.isClosed()){
System.out.println("**源与目的数据库连接成功**");
conn.setAutoCommit(false);
conn_to.setAutoCommit(false);
}else{
new Exception("源与目的数据库连接不成功,请检查!");
}
PreparedStatement pstmt = conn.prepareStatement("SELECT "+SQL_TABLE_FIELD+" FROM "+SQL_SOURCE_TABLENAME);
ResultSet rs = pstmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
//numberOfColumns代表源表列的数量
String[] data = new String[numberOfColumns];
String mark = "";
String temp;
PreparedStatement pstmt2 = conn_to.prepareStatement("delete from "+SQL_TARGET_TABLENAME);
pstmt2.executeUpdate();
pstmt2.close();
while(rs.next()){
mark = "";
for(int i=0;i<numberOfColumns;i++){
if(rs.getString(i+1) != null){
temp = (rs.getString(i+1).trim());
}else{
temp="";
}
data[i] = new String(temp.getBytes("ISO-8859-1"), "GBK");
if (i!=(numberOfColumns-1)){
mark = mark + "?,";
}else{
mark = mark + "?";
}
}
String sql1 = "insert into "+SQL_TARGET_TABLENAME+" ( "+SQL_TABLE_FIELD+" ) values ( "+mark+" )";
PreparedStatement pstmt1 = conn_to.prepareStatement(sql1);
for(int i=0;i<numberOfColumns;i++){
pstmt1.setString(i+1,data[i]);
}
pstmt1.executeUpdate();
pstmt1.close();
}
conn.commit();
conn_to.commit();
System.out.println("**源与目的数据导出成功**");
}
}
/
第二,创建存储过程,带参数
create or replace procedure TransMetaData(p_str in varchar2)
as language java
name 'TransMetaData.donow(java.lang.String)';
/
注意:
1.如果第一步的java对象方法donow无参数,即为static donow()
则此处为create or replace procedure TransMetaData
as language java
name 'TransMetaData.donow()';
/
2.注意两个存储过程的不同,我们的参数在java代码里为String,
因此这里写java.lang.String.
3.如果需要有返回值,(java代码修改省略,返回double类型),则存储过程为
create or replace procedure TransMetaData(p_str in varchar2) return number
as language java
name 'TransMetaData.donow(java.lang.String) return double';
/
第三,执行存储过程
无参数:exec TransMetaData;
带参数:exec TransMetaData(1);
如果:通过pl/sql执行java代码时,在java代码里对数据库进行操作,出现类似如下错误:
ORA-29532: Java 调用被未捕获的 Java 例外终止:
java.security.AccessControlException: the Permission (java.net.SocketPermission
127.0.0.1:2002 connect,resolve) has not been granted to SINBOY. The PL/SQL to
grant this is dbms_java.grant_permission( 'SINBOY',
'SYS:java.net.SocketPermission', '127.0.0.1:2002', 'connect,resolve' )
ORA-06512: 在"SINBOY.TEST9", line 0
ORA-06512: 在"SINBOY.TRG", line 2
解决办法是:
权限不够
对os上的文件赋权限就可以了
grant javauserpriv to SINBOY;
序号<o:p></o:p> |
角色<o:p></o:p> |
说明<o:p></o:p> |
1 |
AQ-ADMINISTRATOR-ROLE |
队列管理员角色 |
2 |
AQ-USER-ROLE |
|
3 |
CONNECT |
连接 |
4 |
CTXAPP |
应用 |
5 |
DBA |
数据库管理员 |
6 |
DELETE-CATALOG-ROLE |
删除目录角色 |
7 |
EXECUTE-CATALOG-ROLE |
执行目录角色 |
8 |
EXP-FULL-DATABASE |
扩展整个数据库 |
9 |
GLOBAL_AQ_USER_ROLE |
全局队列用户角色 |
10 |
HS-ADMIN-ROLE |
HS管理角色 |
11 |
IMP-FULL-DATABASE |
IMP全局数据库 |
12 |
JAVADEBUGPRIV |
JAVA调试权限 |
13 |
JAVAIDPRIV |
JAVA ID权限 |
14 |
JAVASYSPRIV |
JAVA系统权限 |
15 |
JAVA用户权限 |
|
16 |
JAVA-ADMIN |
JAVA管理员 |
17 |
JAVA-DEPLOY |
JAVA调度 |
18 |
OEM-MONITOR |
OEM遥控器 |
19 |
OLAP_DBA |
联机分析数据库管理员 |
20 |
RECORVERY-CATALOG-OWNER |
恢复目录所有者 |
21 |
RESOURCE |
资源 |
22 |
SELECT-CATALOG-ROLE |
选择目录角色 |
23 |
WKADMIN |
WK管理员 |
24 |
WKUSER |
WK用户 |
25 |
WM_ADMIN_ROLE |
WK管理员角色 |
//-------------------------------附上一个自己写的简单的例子---------------------------------------
第一步:
create or replace JAVA SOURCE Named Js_Rand
AS
import java.util.Date;
public class showDate {
public static Date showNowDate(){
return new java.util.Date();
}
}
/
第二步.
CREATE OR REPLACE function rand return VARCHAR2
AS
language Java Name 'showDate.showNowDate() return Date';
/
第三步:
begin
dbms_output.put_line(rand);
End;
/
多谢指导