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

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.

Related

capture sql developer script output in 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();
}
}

Java mysql next result from stored procedure

I have following stored procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `blast10`()
BEGIN
SELECT concat("ROUND ",draws.izvlacenje_id,": ", draws.1,",",draws.2,",",draws.3,",",draws.4,",",draws.5,",",draws.6,",",draws.7,",",draws.8,",",draws.9,",",draws.10,",",draws.11,",",draws.12,",",draws.13,",",draws.14,",\n",draws.15,",",draws.16,",",draws.17,",",draws.18,",",draws.19,",",draws.20,",",
draws.21,",",draws.22,",",draws.23,",",draws.24,",",draws.25,",",draws.26,",",draws.27,",",draws.28,",",draws.29,",",draws.30,",",draws.31,",",draws.32,",",draws.33,",",draws.34,",",draws.35,"")
rzlt from macau.draws order by iddraws desc limit 10;
END`
This procedure returns 10 rows of data and i want to send that data through TCP/IP communication, this is what i achieved by now:
public void blastTen() throws SQLException {
String blastTen = "";
String bl10 = "LAST 10 RESULTS";
try {
Statement st = Conex.conn.createStatement();
String SQLEdit = "{ call blast10() }";
ResultSet rs = st.executeQuery(SQLEdit);
while (rs.next()) {
blastTen = bl10 + "\n" + rs.getString("rzlt") + "\n";
}
os.println(blastTen + "\n");
}
catch (Exception e2) {
System.out.println(e2);
}
}
The problem is I can send only one row and can't seem to get the other rows.
Any help is appreciated
The code
while (rs.next())
{
blastTen=bl10+"\n"+rs.getString("rzlt")+"\n";
}
won't assign anything to bl10 so you'll always only get the latest row... Try
...
bl10 = bl10 + "\n" + rs.getString( "rzlt" );
}
os.println( bl10 );
instead.
Cheers,

BatchUpdateException: Unknown column in where clause

When writing to a mySQL db, i get the following error:
java.sql.BatchUpdateException: Unknown column 'ALFA' in 'where clause'
this is my java code:
public void pushWinner(String game, String teamW) throws SQLException{
String[] t1 = game.split("-");
String statement = "update games set winner=(?) where team1 = "+t1[0]+" AND team2 = "+t1[1];
try (PreparedStatement pstmt = conn.prepareStatement(statement)) {
pstmt.setString(1, teamW);
pstmt.addBatch();
pstmt.executeBatch();
pstmt.close();
} catch (SQLException ex) {
System.out.println(ex);
}
}
I realy can't see what's wrong with the where clause...
EDIT
See my comment, forgot to mention what 'ALFA' is.
Data types for team1 and team2 are both VARCHAR(45).
try this: since datatype of column team1 and team2 are VARCHAR so put single quote to compare it.
queryString= "update games set winner=(?) where team1 = '"+t1[0]+"' AND team2 = '"+t1[1]+"'";
If your datatype is string that you need Single Quote around your passed variable values
something like this...
String statement = "update games set winner=(?) where team1 = '"+t1[0]+"' AND team2 = ' "+ t1[1] + "'";
Your asking for trouble making sql like this. use a prepared statement with seperate parameters instead of inline param building. will stop issues like this and take care of parameter escaping. So use ? in the main sql to denoate location of a parm and use .setString(1, value); to set first (yes its 1 based). Or setInt(1, intValue) ... depending on data type. For date use java.sql.Timestamp - can convert a calendar to date and java.util.Date to sql timestamp OR new javax.time or joda. But dont use inline.
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
Why
ease of programming and
https://www.owasp.org/index.php/SQL_Injection
Copied from the java tutorial :
String updateString =
"update " + dbName + ".COFFEES " +
"set SALES = ? where COF_NAME = ?";
String updateStatement =
"update " + dbName + ".COFFEES " +
"set TOTAL = TOTAL + ? " +
"where COF_NAME = ?";
try {
con.setAutoCommit(false);
updateSales = con.prepareStatement(updateString);
updateTotal = con.prepareStatement(updateStatement);
for (Map.Entry<String, Integer> e : salesForWeek.entrySet()) {
updateSales.setInt(1, e.getValue().intValue());
updateSales.setString(2, e.getKey());
updateSales.executeUpdate();
updateTotal.setInt(1, e.getValue().intValue());
updateTotal.setString(2, e.getKey());
updateTotal.executeUpdate();
con.commit();
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
if (con != null) {
try {
System.err.print("Transaction is being rolled back");
con.rollback();
} catch(SQLException excep) {
JDBCTutorialUtilities.printSQLException(excep);
}
}
} finally {
if (updateSales != null) {
updateSales.close();
}
if (updateTotal != null) {
updateTotal.close();
}
con.setAutoCommit(true);
}
}

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.

i want to display special characters from mysql to jtextfield using jbutton.my code is working only numbers

private void jbutton1ActionPerformed(java.awt.event.ActionEvent evt) {
try
{
MainClass mc=new MainClass();
Connection connection;
connection=DriverManager.getConnection(mc.StrUrl,mc.StrUid,mc.StrPwd);
ResultSet rs;
String StrQr="";
if (prid.getText().trim().length()>0 )
{
StrQr=StrQr + " and pid = " + prid.getText().trim() + " ";
}
if (StrQr.length()==0)
{
JOptionPane.showMessageDialog(null,"Enter search critaria.");
return;
}
PreparedStatement st=connection.prepareStatement("select pid, pname,pslno,pcategory,pqty,ppurcst,plpurcst,psalprc,pcmprc from addproducts where 1=1 " + StrQr + " order by pid");
rs = st.executeQuery();
JOptionPane.showMessageDialog(null,"connected");
while (rs.next()) {
purcst.setText(rs.getString("ppurcst"));
salprc.setText(rs.getString("psalprc"));
prid.setText(rs.getString("Pid"));
prname.setText(rs.getString("Pname"));
category.setText(rs.getString("Pcategory"));
cprc.setText(rs.getString("Pcmprc"));
qnty.setText(rs.getString("Pqty"));
slno.setText(rs.getString("Pslno"));
lpurcst.setText(rs.getString("plpurcst"));
}
rs.close();
}
catch (Exception e)
{
System.err.println(e);
//System.exit(1);
}
}
code display only pid = 104 like numbers .
it cant display special charectors( _,- )pid= A_1103like anybody can help me.
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Unknown column 'A' in 'where clause'
i declare pid as varchar in mysql
A_1103 needs to be quoted, otherwise MySQL will try and resolve it to a column value.
... pid = 'A_1103' ...
In fact, you should be relying on PreparedStatement in order to prevent possible SQL injection problems.
See Using Prepared Statements for more details
For example...
Connection connection;
connection=DriverManager.getConnection(mc.StrUrl,mc.StrUid,mc.StrPwd);
ResultSet rs;
// I'm assuming there are other elements to this query that
// may be included, otherwise this is a lot of overhead
// for little benifi...
List values = new ArrayList(5);
String StrQr="";
if (prid.getText().trim().length()>0 )
{
StrQr += " and pid = ? ";
values.add(prid.getText().trim());
}
if (StrQr.length()==0)
{
JOptionPane.showMessageDialog(null,"Enter search critaria.");
return;
}
PreparedStatement st=connection.prepareStatement("select pid, pname,pslno,pcategory,pqty,ppurcst,plpurcst,psalprc,pcmprc from addproducts where 1=1 " + StrQr + " order by pid");
// Bind the values to the parameters
for (int index = 0; index < values.size(); index++) {
st.setObject(index + 1, values.get(index));
}
rs = st.executeQuery();
JOptionPane.showMessageDialog(null,"connected");
In prepared statement you have to set a ? or any parameter and bind the value.
String StrQr="";
if (prid.getText().trim().length()>0 )
{
StrQr=StrQr + " and pid = ? ";
}
...
PreparedStatement st=connection.prepareStatement("select pid, pname,pslno,pcategory,pqty,ppurcst,plpurcst,psalprc,pcmprc from addproducts where 1=1 " + StrQr + " order by pid");
if (prid.getText().trim().length()>0 )
st.bind(1prid.getText().trim() )
rs = st.executeQuery();
JOptionPane.showMessageDialog(null,"connected");

Categories

Resources