I am trying to add a new row in my table inside mysql db , i tried to use executeUpdate(); and executeQuery(); but both did not work, I am taking columns values from multiple JTextField and adding every one of them to a single Librarian object and then i call setLibrarian() method in main.
But I get the following error message:
java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '#gmail.com , 14 , cairo , 4.6565486E7 )' at line 1
here is my code:
public static void setLibrarian(Librarian lib){
Connection con = null;
Statement st = null;
String dbURL = "jdbc:mysql://localhost:3306/universitysystem";
String username = "root";
String password = "";
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(dbURL , username , password);
st = (Statement) con.createStatement();
st.executeUpdate("INSERT INTO librarians(username , password , email , address , city , contactno)"
+ " VALUES("+lib.getName()+" , "+lib.getPassword()+" , "+lib.getEmail()+" , "+lib.getAddress()+" , "+lib.getCity()+" , "+lib.getContactNo()+" ); ");
con.close(); //closing connection
}
catch(ClassNotFoundException e){
e.printStackTrace();
}
catch(SQLException e){
e.printStackTrace();
}
}
You have a security leak, you must never put user input into a query statement like this. What if someone enters as password:
thisIsMyPassword'; DROP TABLE librarians CASCADE; EXECUTE 'FORMAT C: /force'; --
You'd be quite screwed.
The proper answer is PreparedStatement, which lets you write a single constant as a query (INSERT INTO librarians(...) VALUES (?, ?, ?, ?) - with the question marks) and then provide the value for each question mark separately, and then you're safe from the above issue (then that will simply be their password, verbatim).
This, in passing, also fixes your problem here, which is either that the double isn't working out, or more likely that there are ' symbols in that gmail address.
While you're at it, look at 'try with resources java', because the way you are closing your connections isn't safe either and results in memory leaks. Finally, exception handling with e.printStackTrace() is broken. Fix your IDE; the proper 'I do not care' content is throw new RuntimeException("Uncaught", e); - what you are doing results in many errors and code in unknown states (also a security issue).
Related
here my objective is to call a procedure over a database link in java. procedure takes one input and has got cursor as an output.
to check if my code is working properly, I created dummy procedure in my database and tried executing. it is working, able to get cursor and play with it.
however when i am calling some procedure over database link, getting error as
java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00201: identifier 'HR_CLICK_GET_EMP_DETAILS#IBSLUAT1.WORLD' must be declared
I had a call with developer who had created these procedure. according to him procedures exist at this end and access is already given to my user.
Now my questions and queries are
is there something different, i have to do while calling a procedure over database link(code is below)
what are the things i should be asking to sql developer. by the way database link is right.
String prc_name = "HR_CLICK_GET_CM_AND_ABOVE#IBSLUAT1.WORLD(?,?)";
String runSP = "{ call "+prc_name+" }";
String runSP1 = "{ call get_user_by_userId(?,?) }"; this one is working
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:#xx.xx.xxx.xx:port:SERVICE", "username", "password"); // uat
CallableStatement cs = conn.prepareCall(runSP);
cs.setString(1, "705151");
cs.registerOutParameter(2, OracleTypes.CURSOR);
cs.execute();
// get refcursor and convert it to ResultSet
ResultSet resultSet = (ResultSet) cs.getObject(2);
ResultSetMetaData rsmd = resultSet.getMetaData();
int columnCount = rsmd.getColumnCount();
System.out.println("Total Columns in ResultSet : "+columnCount);
System.out.println("Now Analyzing column one by one:\n\n-----------------------------------------------");
for (int i = 1; i <= columnCount; i++ ) {
String name = rsmd.getColumnName(i);
System.out.println("Column No:"+i+">>>>>>>>"+name);
}
}
catch(SQLException s)
{
s.printStackTrace();
}
catch(ClassNotFoundException s)
{
s.printStackTrace();
}
thanks in advance
Ashish
Try to use the Oracle user's name who owns the procedure as a prefix:
username.HR_CLICK_GET_EMP_DETAILS#IBSLUAT1.WORLD
Answer is "synonym".
SQL Developer has created a synonym for HR_CLICK_GET_EMP_DETAILS as HR_CLICK_GET_EMP_DETAILS#IBSLUAT1.WORLD
that is what he informed me, I could not quite wrap my head around that but able to hit the procedure.
but now , able to get get the metadata of a result set but unable to traverse rows.
I'm getting an error:
java.sql.SQLException: ORA-24338: statement handle not executed
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:207)
at oracle.jdbc.driver.T4CStatement.fetch(T4CStatement.java:1018)
at oracle.jdbc.driver.OracleResultSetImpl.close_or_fetch_from_next(OracleResultSetImpl.java:291)
at oracle.jdbc.driver.OracleResultSetImpl.next(OracleResultSetImpl.java:213)
at ashishtest.StoredProcedureCursor.main(StoredProcedureCursor.java:80)
I guess, new forum is required for this error.
also I am not marking this as solved as not sure how solution works.
I'm currently adding data to a PostgreSQL database via executeUpdate based on input from the client side of a Spring Boot application. I'm adding a comment, longitude, latitude, address, and username to a Review table using the following code in a java method.
I pass the information in a method in a controller class using this line :
addReviewMethod.addReview( comment, longitude, latitude, address, username);
And this will pass the data to another java class and insert it into a table like so:
public void addReview(String comment, double longitude, double latitude, String address, String username) {
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.postgresql.Driver");
c = DriverManager
.getConnection("jdbc:postgresql://localhost:5432/arearatingpgdb",
"postgres", "root");
c.setAutoCommit(false);
stmt = c.createStatement();
int rs = stmt.executeUpdate( "INSERT INTO reviews VALUES (nextval('reviews_id_seq'::regclass), '" +comment +" '," +longitude+"," +latitude+", '"+address+"', '"+username+"');" );
System.out.println("Successfully added: " + comment + longitude + latitude + address + username);
/* while ( rs.next() ) {
Review review = rs.getDouble("price");
System.out.println();
housePrices.add(price);
}*/
//rs.close();
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName()+": "+ e.getMessage() );
System.exit(0);
}
}
I've included print debuggers in both the controller class and the class that executes the insert and they print the correct information that shows me everyting shold be working correctly.
The issue I'm having is when I review the contents of the table i.e. select * from reviews in pgAdmin4 the only rows in the table are the ones I've hardcoded in. Even more confusingly when I hardcode another row into the table via the query tool the id columns reflect that the rows have actually been added from the java side but they are not displaying in the table. For example I hard coded in 2 rows, then I tried to run the methods 4 times then I hard coded in another 2 rows and the database looks like this.
id | val
----+-----
1 | foo
2 | bar
6 | foo
7 | bar
Am I doing something wrong here?
you have to commit those changes.
so do c.commit() before stmt.close() or just change c.setAutoCommit(false); to c.setAutoCommit(true);
Connections in Java are auto-commit by default. In your code, you have deliberately setup your connection's auto commit to false. You can fix the code in two ways:
Comment out below code segment
c.setAutoCommit(false);
Commit your changes before closing the statement
c.commit();
You've to add c.commit() just before closing your Connection object. Because this statement will flush your changes to the database permanently. setAutoCommit(false) changes the behaviour of implicit commit of transaction and the transaction needs to be explicitly committed by using commit().
I have a problem with reading the content of the rows in the database.
I want to show the information (in the console for the moment) about the employee with given position and name. I have built the path ,started the database in H2 but I am not sure I have used PreparedStatement right .
Table "MyTable" not found
I removed the try/catch to be more readable.
static public void Search (JButton a , JFormattedTextField name, JComboBox<String> b ) {
a.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e ) {
Connection con = null;
con = DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test" + "sa" + "");
Statement stm = null;
String ime = name.getText();// reads the name
String poz = (String) b.getSelectedItem();// reads the position
Class.forName("org.h2.Driver");
String sql1 = String.format("SELECT * FROM RABOTNICI WHERE IME = '%s' OR POZICIA = '%s'", ime, poz);
PreparedStatement prstm = null;
prstm = con.prepareStatement(sql1);
ResultSet rs = null;
rs = prstm.executeQuery(sql1);
}
});
}
jdbc:h2:tcp:...
You are using TCP connection but not starting H2 TCP server like this:
http://www.h2database.com/html/tutorial.html#using_server
Normally H2 database is used as embedded without TCP server like this:
http://www.h2database.com/html/tutorial.html#connecting_using_jdbc
jdbc:h2:/path/to/dbfile
I think you had some sources of information and something went wrong down the way.
The way you created a preparedStatement, even if it's parsed correctly, is prone to SQL Injections.
You should first create the statement and only then inject the values.
String sql1 = "SELECT * FROM RABOTNICI WHERE IME = ? OR POZICIA = ?"
PreparedStatement prstm = con.prepareStatement(sql1);
prstm.setString(1, ime);
prstm.setString(2, poz);
Please consult this doc page for correct usage of PreparedStatements
Also, getConnection's argument looks a bit messed up.
con = DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test" + "sa" + "");
The following line should appear before the connection creation.
Class.forName("org.h2.Driver");
I suggest using this tutorial for instruction regarding connection to H2 DB
And last, I'm not sure how do you get the error about "MyTable" its never mentioned in your code snippet.
My code quotes were not tested but I believe are clear enough to get the idea.
My code :
try{ Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/lentele", "root", "");
String select = "SELECT * FROM darbuotojai WHERE 1";
String ID = infoID.getText();
String Vardas = infoV.getText();
String Pavardė = infoP.getText();
String Pareigos = infoPar.getSelectedItem().toString();
String Alga = infoAlg.getText();
String Premija = infoPre.getText();
String insert = "INSERT INTO `darbuotojai`(`ID`, `Vardas`, `Pavardė`, `Pareigos`, `Alga`, `Premija`) VALUES ('"+ID+"','"+Vardas+"','"+Pavardė+"','"+Pareigos+"','"+Alga+"','"+Premija+"',)";
stm.executeUpdate(insert);
JOptionPane.showMessageDialog(null, "Užklausa sėkminga");
infoID.setText("");
infoV.setText("");
infoP.setText("");
infoPar.setSelectedItem("");
infoAlg.setText("");
infoPre.setText("");
display();
} catch (Exception e) {JOptionPane.showMessageDialog(null, e.getMessage()); }
And i get errors like this:
you have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1.
And ones more: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Access denied for user ''#'localhost' to database 'lentele'.
Please, explain these problems for beginner in the easiest way.
This code is for the add button, which would help to insert info into my table.
Remove the comma before your closing bracket:
Premija+"',)";
becomes
Premija+"')";
Except don't build your query by hand, unless you want to be vulnerable to SQL injection attacks: use a PreparedStatement.
I have to use JDBC to write to a database (hibernate/ibatis is not an option) and my database is Oracle 11g.
I create the following query: insert into user(user_id, username, age, creation_ts) values(seq_userid.NEXTVAL, 'Jack', 19,TO_TIMESTAMP('14/12/2010 15/09/46', 'DD/MM/RR HH24/MI/SS'));
However my statetement.execeuteUpdate(above sql). generates an invalid sign exception.
But when I perform the query in squirrel it gets commited just fine.
Does anyone know why this is happening?
Edit:
user table:
id: number : not null
username varchar2(30) not null
age number(10) not null
creation_ts timestamp not null
Error:
ORA-00911: invalid character
Java snippet:
try
{
DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
String url = "privatized";
Connection conn = DriverManager.getConnection(url, "username", "password");
Statement st = conn.createStatement();
Format formatter = new SimpleDateFormat(dateTimeFormatString);
String formattedDate = formatter.format(Calendar.getInstance(TimeZone.getDefault()).getTime());
StringBuilder insertQuery = new StringBuilder("insert into user(user_id, username, age, creation_ts) values(seq_userid.NEXTVAL,");
insertQuery.append(username);
insertQuery.append(",");
insertQuery.append(age);
insertQuery.append(",TO_TIMESTAMP('");
insertQuery.append(formattedDate);
insertQuery.append("', 'DD/MM/RR HH24/MI/SS'));");
System.err.println(insertQuery.toString());
st.executeUpdate(insertQuery.toString());
conn.close();
} catch (SQLException ex){
System.err.println(ex.getMessage());
System.err.println(ex.getCause().toString());
ex.printStackTrace();
System.out.println("=========================================");
} catch(Exception ex) {
System.err.println(ex.getMessage());
}
As I put in a comment above, the issue could be due to the extra Semicolon at the end of your SQL statement. see this article
You may also want to look at PreparedStatments to make your life easier. Here would be a rough translation of your above code. I have left some parts, and there are most likely errors.
String query = "insert into user(user_id, username, age, creation_ts) values(?,?,?,?)";
PreparedStatement pstmt = conn.prepareStatement(query);
... //fill in all your parameters
pstmt.setTimestamp(4, new Timestamp(System.currentTimeMillis()) );
... //execute here
TO_TIMESTAMP('14/12/2010 15/09/46', 'DD/MM/RR HH24/MI/SS')
You send a 4-digit year but the format string defines a 2-digit year (no century)
Give this a try:
insertQuery.append("', 'DD/MM/RRRR HH24/MI/SS'));");
Are you sure the value of the username variable is 'Jack' and not Jack? (the ORA-00911 error doesn't look like a typical date format error).
Also you should learn about PreparedStatement. They are more efficient, easier to read and debug and not susceptible to SQL injection.
My java is a bit rusty, but this would look something like this with a PreparedStatement:
String query = "insert into user(user_id, username, age, creation_ts) values "
+ "(seq_userid.NEXTVAL, ?, ?, ?)";
Statement st = conn.prepareStatement(query);
st.setString(1, username);
st.setInt(2, age);
st.setTimestamp(3, new java.sql.Timestamp(
Calendar.getInstance(
TimeZone.getDefault()).getTimeMillis()));
st.executeUpdate(insertQuery.toString());
This way you don't need to convert a date to a string to get it converted back by the DB. Also you may find the statement easier to read and you will never have to worry about user's naming their account with a ' (single-quote) :)