Реализация хранимой процедуры Java IBM DB2 for i (AS400)
Я создал хранимую процедуру Java следующим образом, способный генерировать .class
файл с использованием интерпретатора команд Qshell AS400.
import java.sql.*;
public class sample
{
public sample(){
super();
}
/**
* @param args
*/
public static void Test(int test) throws SQLException, Exception {
// TODO Auto-generated method stub
try
{ Class.forName ("com.ibm.as400.access.AS400JDBCDriver").newInstance ();
String url = "jdbc:as400://ilava;naming=system;prompt=false;user=IPGUI;password=IPGUI;libraries=IPSRFILI,IPTSFILI,IPWMFILI,IPPAFILI,IPASFILI,IPSAFILI,IPTSUTL;translate binary=true";
Connection con = DriverManager.getConnection(url);
PreparedStatement ps = con.prepareStatement("INSERT INTO IPTSFILI.TEMP VALUES ('IP', 'WELCOME TO SQLJ')");
ps.executeUpdate();
ps.close();
con.close();
}
catch (Exception e)
{
System.out.println (e);
System.exit(1);
}
}
}
создал соответствующую процедуру магазина как
CREATE procedure IPTSFILI.SPSAMPLE (
IN TEST INTEGER )
LANGUAGE JAVA
SPECIFIC IPTSFILI.SPSAMPLE
DETERMINISTIC
MODIFIES SQL DATA
CALLED ON NULL INPUT
EXTERNAL NAME 'sample!Test'
PARAMETER STYLE JAVA ;
Когда процедура вызывается (с помощью вызываемого оператора в JAVA), она выдает ниже ошибку как
java.sql.SQLException: [SQL4304] Java stored procedure or user-defined function SPSAMPLE, specific name SPSAMPLE could not load Java class Ä?_ÑÂ_À¦ÀÂÄ/øøàâàÊÑÎÁÊ for reason code 3.
at com.ibm.as400.access.JDError.throwSQLException(JDError.java:687)
at com.ibm.as400.access.JDError.throwSQLException(JDError.java:653)
at com.ibm.as400.access.AS400JDBCStatement.commonExecute(AS400JDBCStatement.java:920)
at com.ibm.as400.access.AS400JDBCPreparedStatement.execute(AS400JDBCPreparedStatement.java:1018)
at Exec.main(Exec.java:23)
Разместил .class
файл в QIBM\UserData\OS400\SQLLib\Function
каталог.
Любые предложения о том, как решить эту проблему?
2 ответа
Возможно, вы не указали правильную процедуру. Глядя на документацию по OS400 и хранимым процедурам Java (см. Главу 7), я думаю, что вам не хватает нескольких шагов здесь. Я советую взять код из документа и запустить его, а затем заменить его собственной реализацией.
У вас есть некоторые проблемы с вашим кодом Java.
Вы не должны использовать System.out в вашей хранимой процедуре Java. Из-за особенностей системы System.out не работает должным образом, если хранимая процедура Java вызывается в переработанном задании QZDASOINIT или QSQSRVR.
Вы не должны использовать System.exit(1) в своем звонке. Этот вызов завершит работу JVM, и после завершения JVM его нельзя будет перезапустить.
Возможно, вам следует использовать собственный драйвер JDBC, если вы обращаетесь к таблицам в той же системе, где определена хранимая процедура Java. Чтобы получить соединение JDBC, которое использует собственный драйвер, вы должны вызвать DriverManager.getConnection("jdbc:default:connection");
Если вы не перехватите исключение, большинство исключений JDBC вернутся правильно, если вы вызовите хранимую процедуру с помощью клиента JDBC.
Я обновил программу, чтобы она выглядела следующим образом.
import java.sql.*;
public class sample
{
public sample(){
super();
}
/**
* @param args
*/
public static void Test(int test) throws SQLException, Exception {
String url = "jdbc:default:connection";
Connection con = DriverManager.getConnection(url);
PreparedStatement ps = con.prepareStatement("INSERT INTO IPTSFILI.TEMP VALUES ('IP', 'WELCOME TO SQLJ')");
ps.executeUpdate();
ps.close();
con.close();
}
}
Когда я позвонил, я получил следующее исключение (так как я не создавал файл в моей системе).
SQLState: 42704
Message: [SQL0204] TEMP in IPTSFILI type *FILE not found.
Vendor: -204
Вам также нужно проверить, что CCSID JOB задания сервера базы данных не 65535. Вы должны были получить следующую ошибку, если CCSID JOB был 65535, но я подозреваю, что выпуски более ранних, чем 6.1, могли не обнаружить это правильно.
CALL QSYS.QCMDEXC('Chgjob ccsid(65535) ',000000020.00000)
call SPSAMPLE(3)
*** SQLException caught ***
Statement was call SPSAMPLE(3)
SQLState: 57017
Message: [SQL0332] Character conversion between CCSID 65535 and CCSID 1200 not valid.
Vendor: -332