capture sql developer script output in java - java

As part of my java application, I have to create oracle packages from java code. Sometimes, the package code might have issues and compilation might fail. However, I am unable to capture simple failures from java. So, i have to compile > 350 oracle packages from java, and if there are errors in the package, I need to inform the user to fix them. I have pasted oracle package and java code below.
CREATE OR REPLACE PACKAGE plat_test IS
FUNCTION getmsg (
p_empno IN NUMBER
) RETURN VARCHAR2;
END plat_test;
/
CREATE OR REPLACE PACKAGE BODY plat_test AS
FUNCTION getmsg (
p_empno IN NUMBER
) RETURN VARCHAR2 IS
BEG
RETURN 'sss';
END getmsg;
END plat_teest;
Compiling / running the above code in sql developer throws:
LINE/COL ERROR
--------- -------------------------------------------------------------
0/0 PL/SQL: Compilation unit analysis terminated
1/14 PLS-00201: identifier 'PLAT_TEEST' must be declared
1/14 PLS-00304: cannot compile body of 'PLAT_TEEST' without its specification
Errors: check compiler log
I want to create the above package in java and get the result. So that I can inform the user on the failure. In java I am not able to capture the errors and the program always succeeds.
How can I capture the output in java
The java code I have:
import java.sql.*;
public class NewJDBCTester {
public static void one() {
String s_sql = "CREATE OR REPLACE PACKAGE BODY plat_test AS\n" +
" FUNCTION getmsg (\n" +
" p_empno IN NUMBER\n" +
" ) RETURN VARCHAR IS\n" +
" BEG" +
" RETURN 'ret_val';\n" +
" END getmsg;\n" +
"\n" +
"END plat_test\n" +
"/";
// String s_sql ="alter table Metric_idf from ssssssss_ssst";
// System.out.println(" SQL Stmt: " + sql);
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection conn = null;
Statement stmt = null;
try {
conn = DriverManager.getConnection("jdbc:oracle:thin:bhasoor/password#10.100.1.61:34171/ssssssssssdb");
stmt = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
try {
stmt.execute (s_sql);
System.out.println(" SQL Executed Successfully ");
} catch (SQLException sqe) {
System.out.println("Error Code = " + sqe.getErrorCode());
// sqe.
System.out.println("SQL state = " + sqe.getSQLState());
System.out.println("Message = " + sqe.getMessage());
System.out.println("printTrace /n");
sqe.printStackTrace();
}
}
public static void main(String[] args) throws ClassNotFoundException {
one();
}
}

You can know if an error occurs by this way:
boolean result = stmt.execute(s_sql);
System.out.println(result ? " SQL Executed Successfully " : " SQL Executed with error ");
Then, the following query give you the error:
select *
from ALL_ERRORS
where owner = 'METRICSTREAM'
and name = 'PLAT_TEST'
--and type = 'PACKAGE BODY'
order by sequence
Here, there is no SQLException because the compilation has been completed, but with some errors.
You should use try-with-resource like this to avoid memory leaks:
try ( //
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:#10.100.1.61:34171/pdb", "metricstream", "password"); //
Statement stmt = conn.createStatement(); //
) {
boolean result = stmt.execute(s_sql);
System.out.println(result ? " SQL Executed Successfully " : " SQL Executed with error ");
}
catch (SQLException sqe) {
System.out.println("Error Code = " + sqe.getErrorCode());
System.out.println("SQL state = " + sqe.getSQLState());
System.out.println("Message = " + sqe.getMessage());
System.out.println("printTrace /n");
sqe.printStackTrace();
}

You could have a look at this blog from a few years ago.
You can use the libraries from Oracle SQLDeveloper or Oracle SQLcl to run scripts like you would on the command line.
https://barrymcgillin.blogspot.com/2018/04/run-your-sql-script-from-java-now.html
In your script, you can do simple sqlplus things like
Begin
my stuff;
end;
/
show errors
You can also get the errors from the executor object after it has run.

So finally I acheived this like this. Execute the create or replace package then get the errors from dba_errors...
Posting code here...
import java.sql.*;
public class NewJDBCTester {
public static void one() throws ClassNotFoundException {
String s_sql = "CREATE OR REPLACE PACKAGE BODY plat_test AS\n" +
" FUNCTION getmsg (\n" +
" p_empno IN NUMBER\n" +
" ) RETURN VARCHAR2 IS\n" +
" BEGIN\n" +
// " RETURN 'sss';\n" +
" END getmsg;\n" +
"END plat_test;\n";
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;
try {
conn = DriverManager.getConnection("jdbc:oracle:thin:user/password#10.100.1.61:34171/somedb");
stmt = conn.createStatement();
System.out.println("EXECUTING QUERY");
rset = stmt.executeQuery(s_sql);
rset.close();
stmt.close();
stmt = conn.createStatement();
rset = stmt.executeQuery("SELECT line, text FROM DBA_ERRORS WHERE OWNER = 'Bhasoor' AND NAME = 'PLAT_TEST' ORDER BY SEQUENCE desc");
while (rset.next()) {
System.out.println("ERROR AT LINE ::: " + rset.getString("line"));
System.out.println("\n");
System.out.println("ERROR DETAILS::: " + rset.getString("text"));
}
} catch (SQLException sqe) {
System.out.println("Error Code = " + sqe.getErrorCode());
System.out.println("SQL state = " + sqe.getSQLState());
System.out.println("Message = " + sqe.getMessage());
System.out.println("printTrace \n");
sqe.printStackTrace();
}
}
public static void main(String[] args) throws ClassNotFoundException {
one();
}
}

Related

Printing the ASM code to generate the given class

I am using eclipse for executing the java program for simple JDBC connection with MySQL with the code as follows:
package samm;
import java.sql.*;
public class Sd {
public static void main(String args[]) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sam", "root", "1234");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from sam1");
while (rs.next()) {
System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getString(3));
}
con.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
I am unable to execute and get the desired result but instead, I'm getting an error message as:" Prints the ASM code to generate the given class.
Usage: ASMifier [-debug] "
This line can make a problem :
System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getString(3));
Why because this way is used when you define the name of the attributes in your query so instead of :
select * from sam1
Your query should look like this :
select attribute1, attribute2, attribute3 from sam1
Second solution instead of defining the index of the attribute you can use your query as it is but you have to change :
rs.getInt(1)
To this :
rs.getInt("name_of_the_attribute");// for example rs.getInt("id")

java sqlite - Error: function not yet implemented for SQLite

I created the following class in java to make using SQLite easier when I code.
import java.sql.*;
public class Dbm {
//We want to use the connection througout the whole class so it is
//provided as a class level private variable
private Connection c = null;
//This constructor openes or creates the database provided by the arguement
//NameOfDatabase
public Dbm(String NameOfDatabase){
try {
//Database is checked for in project folder, if doesnt exist then creates database
c = DriverManager.getConnection("jdbc:sqlite:" + NameOfDatabase);
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Opened database successfully");
}
public void CloseDB(){
try{
c.close();
System.out.println("Closed Database Successfull");
}
catch (Exception e){
System.out.println("Failed to close Database due to error: " + e.getMessage());
}
}
public void ExecuteNoReturnQuery(String SqlCommand){
//creates a statment to execute the query
try{
Statement stmt = null;
stmt = c.createStatement();
stmt.executeUpdate(SqlCommand);
stmt.close();
System.out.println("Sql query executed successfull");
} catch (Exception e){
System.out.println("Failed to execute query due to error: " + e.getMessage());
}
}
// this method returns a ResultSet for a query which can be iterated throughd
public ResultSet ExecuteSqlQueryWithReturn(String SqlCommand){
try{
Statement stmt = null;
stmt = c.createStatement();
ResultSet rs = stmt.executeQuery(SqlCommand);
return rs;
}catch (Exception e){
System.out.println("An Error has ocured while executing this query" + e.getMessage());
}
return null;
}
}
Here is the main code in the program
import java.sql.*;
public class InstaText {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Dbm db = new Dbm("people.db");
ResultSet rs = db.ExecuteSqlQueryWithReturn("select * from people;");
try{
String name = "";
int age = 0;
String address = "";
while (rs.isLast() == false){
name = rs.getString("name");
age = rs.getInt("age");
address = rs.getString("address");
System.out.println("Name is " + name +" age is " + age + " Address is " + address);
rs.next();
}
}catch (Exception e ){
System.out.println("Error: " + e.getMessage());
}
db.CloseDB();
}
}
But when I execute it I get the following output:
Opened database successfully
Error: function not yet implemented for SQLite
Closed Database Successfull
So how do I solve the Error "Error: function not yet implemented for SQLite"?
I am running the NetBeans Ide with the latest JDBC on mac os sierra.
Edit: Here is the output after adding e.printstacktrace(); in the catch block:
Opened database successfully
Error: function not yet implemented for SQLite
java.sql.SQLException: function not yet implemented for SQLite
Closed Database Successfull
at org.sqlite.jdbc3.JDBC3ResultSet.isLast(JDBC3ResultSet.java:155)
at instatext.InstaText.main(InstaText.java:24)
The problem is not your select query but the isLast() method you are using on the ResultSet instance to retrieve the result. Try the next() method, it should work :
while (rs.next()){
name = rs.getString("name");
age = rs.getInt("age");
address = rs.getString("address");
System.out.println("Name is " + name +" age is " + age + " Address is " + address);
rs.next();
}
You can read here :
https://github.com/bonitasoft/bonita-connector-database/issues/1
that with SQLLite, you may have some limitations with the isLast() method :
According to JDBC documentation
(http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html)
calls to isLast() and first() methods are forbidden if the result set
type is TYPE_FORWARD_ONLY (e.g SQLite).

Java Client doesn't get ResultSet from Stored Procedure (written in Java - SQLJ) on DB2 zOS

I'm trying to recieve a ResultSet from a SQLJ Java Stored Procedure. The Client doesn't get the ResultSet. So I don't know if there is anything wrong with my create, transfer or receive of the ResultSet.
This is how I create the Procedure:
CREATE PROCEDURE SCHEMA.JOBNAMENGET
(IN FILTER CHARACTER(8))
EXTERNAL NAME 'STPDFIDB.JOBNAMENGET
(java.lang.String,java.sql.ResultSet[])'
DYNAMIC RESULT SETS 1
LANGUAGE JAVA
PARAMETER STYLE JAVA
NO COLLID
PACKAGE PATH 'SCHEMA,NULLID'
PROGRAM TYPE SUB
WLM ENVIRONMENT XXXXXXXX;
The Code of the external Java Procedure:
import java.sql.*;
import com.ibm.db2.jcc.DB2Connection;
import java.util.Properties;
import sqlj.runtime.ExecutionContext;
#sql iterator Cursor1 (String, String);
public class STPDFIDB {
#sql static context STPD2FIDB_Ctx;
public static void JOBNAMENGET (
String filter,
ResultSet[] outRS)throws SQLException {
Connection conndb2 = null;
STPD2FIDB_Ctx ctx = null;
Cursor1 cursor1 = null;
System.out.println("Vor dem Try");
try {
System.out.println("in dem try");
// Establish Connection; if type-2 z/OS this will trigger load of DLL
System.out.println ();
conndb2 = DriverManager.getConnection("jdbc:default:connection" );
conndb2.setAutoCommit(false);
ctx = new STPD2FIDB_Ctx ( conndb2 );
#sql [ctx] cursor1 = {
SELECT JOBNAME, KURZBESCHREIBUNG
FROM SCHEMA.JOBNAMEN
WHERE JOBNAME LIKE :filter
};
System.out.print("cursor durchgeführt");
} catch (SQLException ex) {
System.err.println("SQLException information");
System.err.println("Error msg: " + ex.getMessage());
System.err.println("SQLSTATE: " + ex.getSQLState());
System.err.println("Error code: " + ex.getErrorCode());
ex.printStackTrace();
}
catch ( Exception e ) {
System.out.println ( " ***** ERROR - Unable to load DB2 Universal Driver, " + e );
}
outRS[0] = cursor1.getResultSet();
System.out.println("Whileschleife");
//
// while (outRS[0].next()){
// System.out.println("Jobname = " + outRS[0].getString(1));
// }
}
}
And the call from the Client:
String ergebnis = "";
ResultSet rs1;
CallableStatement statement;
try {
// create data source
com.ibm.db2.jcc.DB2SimpleDataSource ds = new com.ibm.db2.jcc.DB2SimpleDataSource();
// set connection properties
ds.setServerName("XXXXXXXXXXXXXXXXXXXXXXXXXX");
ds.setPortNumber(XXXX);
ds.setDatabaseName("XXX");
ds.setDriverType(4);
// set trace properties
ds.setTraceDirectory("c:\\temp");
ds.setTraceFile("trace");
ds.setTraceFileAppend(false);
ds.setTraceLevel(com.ibm.db2.jcc.DB2BaseDataSource.TRACE_ALL);
// get connection
Properties db2_auth = new Properties();
db2_auth.put("user", userName);
db2_auth.put("password", password);
Connection con = ds.getConnection(userName, password);
//Now, issue the CALL statement to invoke the stored procedure
statement = con.prepareCall("{CALL SCHEMA.JOBNAMENGET(?)}",ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);
statement.setString(1, "BAAAA%%%");
System.out.println("\nAbout to invoke StProc");
boolean result = statement.execute();
rs1 = statement.getResultSet();
while (rs1.next()) {
System.out.println("In der rs1.next While Schleife");
System.out.println("Jobname = " + rs1.getString(1));
System.out.println("Beschr. = " + rs1.getString(2));
}
System.out.println("\nJust returned from StProc");
System.out.println("\nValue returned by stored procedure is " + ergebnis);
//statement.close();
//con.close();
System.out.println("\nInvocation of JAVASPJ was successful!");
} catch (SQLException e) {
System.out.println("**SQLException in cjavaspj**");
System.out.println("Error Message: " + e.getMessage()+ " " + e.getSQLState()+ " " );
} catch (Exception e) {
System.out.println("**Non-SQLException in cjavaspj**");
e.printStackTrace();
}
return ergebnis;
}
I've already tested the connection and WLM Environment by using single Strings as Output Parameters. Everything worked.
Please can someone advise what am I missing?
Thanks!
EDIT :
After the Call from the Stored Procedure the WLM Environment says:
Default EBCDIC encoding is 273; as CCSID char: 'Cp273'
** Explicit signature provided: '(java.lang.String, java.sql.ResultSetݨ)'
Generated signature before convert: (Ljava/lang/String;ÝLjava/sql/ResultSet;)V
Processing IN and INOUT parameters of the Java method
parm 1 is String: 'BAAAA%%%' CCSID: 273
Processing dynamic result set parameters of the Java method
parm 2 is of type ÝLjava/sql/ResultSet;
invoking class: STPDFIDB, method: JOBNAMENGET
Back from Call: Processing time was 0.148300
Processing OUT and INOUT parameters of the Java method
Processing dynamic result set parameters of the Java method
parm 2 is a dynamic result set, partial description:
Package name: 'STPDFIDB'
Collection name: ''
Section number: 1
Number of result sets is 1
Return Status: Execution=0, Debug=0
Everything looks fine.
The Client gets a java.lang.NullPointerException at while (rs1.next())

JDBC update using prepared statement

I am trying to update a table using Java JDBC. The method I am using does not throw any errors but the table is not updating. The create table method is below:
public static void Table()
{
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db");
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "CREATE TABLE IF NOT EXISTS CUSTOMERS2 " +
"(PHONE TEXT PRIMARY KEY NOT NULL," +
" SURNAME TEXT NOT NULL, " +
" FIRSTNAME TEXT NOT NULL, " +
" HOME TEXT, " +
" ADDRESS TEXT, " +
" POSTCODE Text)";
stmt.executeUpdate(sql);
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Customers2 created successfully");
}
The update method is below:
public static void updateCustomers()
{
Connection c = null;
PreparedStatement pstmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db");
c.setAutoCommit(false);
System.out.println("Opened database successfully");
String query = "UPDATE CUSTOMERS2 set ADDRESS = ? where PHONE = ? ";
pstmt = c.prepareStatement(query); // create a statement
pstmt.setString(1, "1"); // set input parameter 1
pstmt.setString(2, "DOES THIS WORK"); // set input parameter 2
pstmt.executeUpdate(); // execute update statement
pstmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Update Completed successfully HELLO");
}
I have tried to find some clear instructions on this but cant find any. I do not really understand JDBC and prepared statement very well
When autoCommit is false (c.setAutoCommit(false);), you must manually commit the transaction...
Add...
c.commit()
After pstmt.executeUpdate();
You code also has a flaw, in that if some kind of error occurs during the preparation or execution of the statement, both the Connection and PreparedStatement could be left open, causing a resource leak
If you're using Java 7+ you can use the try-with-resources feature, for example...
try {
Class.forName("org.sqlite.JDBC");
try (Connection c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db")) {
c.setAutoCommit(false);
System.out.println("Opened database successfully");
String query = "UPDATE CUSTOMERS2 set ADDRESS = ? where PHONE = ? ";
try (PreparedStatement pstmt = c.prepareStatement(query)) {
pstmt.setString(1, "1"); // set input parameter 1
pstmt.setString(2, "DOES THIS WORK"); // set input parameter 2
pstmt.executeUpdate(); // execute update statement
c.commit();
}
} catch (SQLException exp) {
exp.printStackTrace();
}
} catch (ClassNotFoundException exp) {
exp.printStackTrace();
System.out.println("Failed to load driver");
}
This will ensure that regardless of how you leave the try block the resource will be closed.
You might also consider taking a look at the JDBC(TM) Database Access
Your update method will set ADDRESS to 1 if there is any row in table with PHONE = does this work.
Try to put Address in 1st Input parameter and Phone 2nd Input parameter
When a connection is created, it is in auto-commit mode.
We need to use [setAutoCommit] method only when we need to make Auto Commit false and make it manual commit after executing the query.
More details at Oracle site on JDBC Transaction.

Exception when trying to create a trigger using SQLQuery [duplicate]

i've got some code that is triggering a syntax error because of some misplaced semicolons. if this was running on the command line, i'd solve this with a delimiter. unfortunately, the jdbc4 driver doesn't seem to recognize delimiters. anyway to get this to run?
delimiter |
CREATE TRIGGER obs_update BEFORE UPDATE ON obs
FOR EACH ROW
BEGIN
IF OLD.voided = 0 AND NEW.voided = 1 THEN
DELETE FROM clinic_obs WHERE id = OLD.obs_id;
ELSE
UPDATE clinic_obs SET clinic_obs.revision_token = NOW()
WHERE NEW.obs_id = clinic_obs.id;
END IF;
END;
|
delimiter ;
Delimiter is a command for SQL client. There is no need to use delimiter in JDBC.
Example below shows it:
import java.sql.*;
public class TriggerExample {
public static void main(String args[]) {
String connectionURL = "jdbc:mysql://localhost:3306/test";
Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(connectionURL, "login",
"password");
Statement stmt = con.createStatement();
stmt.execute("CREATE TRIGGER obs_update BEFORE UPDATE ON obs "
+ "FOR EACH ROW "
+ "BEGIN "
+ "IF OLD.voided = 0 AND NEW.voided = 1 THEN "
+ " DELETE FROM clinic_obs WHERE id = OLD.obs_id; "
+ "ELSE "
+ " UPDATE clinic_obs SET clinic_obs.revision_token = NOW() "
+ " WHERE NEW.id = clinic_obs.id; "
+ "END IF; "
+ "END;");
con.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
Try removing the semi colon after the final END word. so it looks like this:
delimiter |
CREATE TRIGGER obs_update BEFORE UPDATE ON obs
FOR EACH ROW
BEGIN
IF OLD.voided = 0 AND NEW.voided = 1 THEN
DELETE FROM clinic_obs WHERE id = OLD.obs_id;
ELSE
UPDATE clinic_obs SET clinic_obs.revision_token = NOW()
WHERE NEW.obs_id = clinic_obs.id;
END IF;
END|
It should work because I have done a similar trigger/procedure using jdbc driver.

Categories

Resources