I want to save two values as one in a database how can I do that?
Here's my code:
try{
String v = "Voila";
String c = "Magic";
String url = "jdbc:mysql://localhost:3306/lemon";
Connection conn = DriverManager.getConnection(url,"r","s");
Statement st = conn.createStatement();
st.executeUpdate("INSERT INTO rtype set RType = '" + v + "'"); // how can I add 'c' in the same column?
conn.close();
}
catch (Exception e) {
System.err.println("Got an exception! ");
JOptionPane.showMessageDialog(null,"Please enter some values");
System.err.println(e.getMessage());
}
As you can see, I have two strings that I should combine as one then save in a database.
The column should have "Voila Magic" if successful.
Just concatenate them at the Java level before the insert:
st.executeUpdate("INSERT INTO rtype set RType = '" + v + " " + c + "'");
// Here ----------------------------------------------^^^^^^^^^^
If either v or c comes from an end user, beware that your code is wide open to SQL injection attacks; here's a humorous, but serious, illustration of them:
Even if they don't, if either could contain ', your statement would end up being invalid SQL and failing. Use PreparedStatement and parameter placeholders instead:
PreparedStatement ps = conn.prepareStatement("INSERT INTO rtype set RType = ?");
ps.setString(1, v + " " + c);
ps.executeUpdate();
try this with modification to your code:
try{
String v = "Voila";
String c = "Magic";
String rType = v + " " + c;
String url = "jdbc:mysql://localhost:3306/lemon";
Connection conn = DriverManager.getConnection(url,"r","s");
Statement st = conn.createStatement();
st.executeUpdate("INSERT INTO rtype set RType = '" + rType + "'"); // how can I add 'c' in the same column?
conn.close();
}
catch (Exception e) {
System.err.println("Got an exception! ");
JOptionPane.showMessageDialog(null,"Please enter some values");
System.err.println(e.getMessage());
}
My suggestion is to use a separator while concatenate the two strings by using any specific character like #, ^ etc., (space likely to occur more common in the strings and avoiding space as a separator by any of the two methods suggested by Crowder.
So that you can split the values you fetch it back from the database in order to show those 2 values in 2 separate fields (probably 2 text fields on a web page) basing on you requirement.
Related
I have the following code:
try {
userPasswordNew = new String(ChangePW.passwordFieldconfirm.getPassword());
PreparedStatement prepStmt = connection.prepareStatement(
"UPDATE " + TABLE_NAME + " SET password = " + userPasswordNew + " WHERE username = " + username);
prepStmt.setString(2, BCrypt.hashpw(userPasswordNew, BCrypt.gensalt(bcryptRounds))); //2 represents number of column in database starting with 0
System.out.println(prepStmt);
return prepStmt.executeUpdate() != 0;
} catch (SQLException e) {
e.printStackTrace();
}
I tried 1 2 and 3 as indexes but everytime it throws an Index out of range exception. Is there another way to get the column, maybe adressed with its name? Or what am I doing wrong?
Could somebody please help?
To use prepared statements - please use ? instead provided values. Like in this sample:
String updateString =
"update " + dbName + ".COFFEES " +
"set SALES = ? where COF_NAME = ?";
updateSales = con.prepareStatement(updateString);
To get more, please look here. In your case that could be:
PreparedStatement prepStmt = connection.prepareStatement(
"UPDATE " + TABLE_NAME + " SET password = ? WHERE username = ?");
prepStmt.setString(1, "that new password");
prepStmt.setString(2, "user_name");
I assume password and username are textual values. Hence you will have to enclose the values by quotes.
That is the query will be
"UPDATE " + TABLE_NAME + " SET password = " + userPasswordNew + " WHERE username = " + username
Also, as you are using PreparedStatement, you must not mention the variables in the query. A neater approach would be to use ? instead. Something like this.
"UPDATE " + TABLE_NAME + " SET password = ? WHERE username = ?
And then use .setString() etc methods with userPasswordNew and username.
Check this, https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
When you use PreparedStatement, you define the parameters to pass in the sql statement by placing 1 or more ?.
Then you pass values to these parameters with methods like setString(), setInt(),... The order of the parameters is not 0 based but 1 based.
try {
userPasswordNew = new String(ChangePW.passwordFieldconfirm.getPassword());
PreparedStatement prepStmt =
connection.prepareStatement("UPDATE " + TABLE_NAME +" SET password = ? WHERE username = ?");
prepStmt.setString(1, userPasswordNew);
prepStmt.setString(2, username);
System.out.println(prepStmt);
return prepStmt.executeUpdate() != 0;
} catch (SQLException e) {
e.printStackTrace();
}
In your code there is this line:
prepStmt.setString(2, BCrypt.hashpw(userPasswordNew, BCrypt.gensalt(bcryptRounds)));
I don't know if this is a parameter that you want to pass.
If it is I can't see a ? placeholder in the sql statement.
I'm trying to check if the "Username" and "Email" arguments in my constructor are existed in the SQL Table.
this is my code:
public DB(String usr, String eml, String pwd) {
this.usr = usr;
this.eml = eml;
this.pwd = pwd;
String jdbcUrl = "jdbc:mysql://localhost:3306/registered";
String jdbcUser = "....";
String jdbcPassword = "....";
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(jdbcUrl, jdbcUser,
jdbcPassword);
statement = connection.createStatement();
now , if i use SELECT with two columns, like this:
String command = "SELECT UserName,Email FROM users WHERE UserName LIKE '" + this.usr.toString() + "';";
resultSet = statement.executeQuery(command);
and then do my loop for resultSet... like this:
while (resultSet.next()) {
if (usr.equalsIgnoreCase(resultSet.getString("UserName"))) {
System.out.println("UserName : " + this.usr + " is taken!");
}
else if (eml.equalsIgnoreCase(resultSet.getString("Email"))) {
System.out.println("Email : " + this.eml + " is taken!");
}
else {
System.out.println("Email : " + this.eml + " and UserName : " + this.usr + " are AVAILABLE!");
command = "INSERT users SET UserName = '" + this.usr.toString() + "',Email = '" + this.eml.toString() + "',Password = '" + this.pwd.toString() + "',Status = '0' ,Connected = '1';";
statement.executeUpdate(command);
}
}
} catch (SQLException e) {
System.out.println("SQLException: " + e.getMessage());
System.out.println("Vendor error: " + e.getErrorCode());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
the
resultSet.next()
only runs over the "FIRST" column which means
if the "usr" exists in the table it works,
but if the "usr" does not exist in the table, the other two if statements does-not work ..
,... i want to check both first column and second,.. and maybe third or more soon.. , any help?
Your WHERE clause only tests for the UserName, so if the UserName doesn't match this.usr.toString(), the resultSet will be empty, so the while loop won't be entered.
You should change the query to match all the fields you care about - something like - "SELECT UserName,Email FROM users WHERE UserName = ... OR Email = ..."
If the resultSet is empty, you'll know that you can insert the new record. Otherwise, you can check which of the fields (UserName, Email) is already taken.
One more thing you should be aware of - executing a SQL statement without PreparedStatement makes your code vulnerable to SQL injection attacks.
You should change your code to something like this :
PreparedStatement pstmt = con.prepareStatement("SELECT UserName,Email FROM users WHERE UserName = ? OR Email = ?");
pstmt.setString(1, this.usr);
pstmt.setString(2, this.eml);
resultSet = pstmt.executeQuery();
You should change your INSERT statement similarly to use PreparedStatement.
I'm working on a project where a user can assemble the components of a yoga class. It's spread across several files and thus too large to put it all here. The trouble I'm having is in one method where I need to iterate over the horizontal columns of a result set that is returning only ONE ROW from a MySQL database.
I understand that I have to position the cursor on the first row of the result set (which I believe I am doing). Since I have only one row in the result set (my variable is rset), I should be using rset.next() only one time, correct? And then I should be able to use a simple loop to iterate over each column and append the value to my String Builder. I want to skip the first column and append each subsequent value until the loop reaches columns with null values. I cannot find why my code keeps returning a "Before start of result set" exception.
Can anyone spot anything wrong?
I'll post the method as well as the method called by this method. (I posted this in a different question, but I believe the nature of my question has changed, so I'm re-posting this with a different title.)
// Query that returns the poses within a specific section
public String listPosesInSection(String tableName, String sectionName) {
String strList;
StringBuilder strBuilderList = new StringBuilder("");
// Run the query
try {
statement = connection.createStatement();
// Query will collect all columns from one specific row
rset = statement.executeQuery("SELECT * FROM " + tableName + " WHERE " + tableName + "_name = '" + sectionName + "'");
rset.next();
System.out.println("Column count is " + countColumnsInTable(tableName));
for (int i = 2; i <= countColumnsInTable(tableName); i++) {// First value (0) is always null, skip first column (1)
System.out.println("test");
strBuilderList.append(rset.getString(i) + "\n"); // This is line 126 as indicated in the exception message
}
} catch (SQLException e) {
e.printStackTrace();
}
strList = strBuilderList.toString();
return strList.replaceAll(", $",""); // Strips off the trailing comma
}
// Method for getting the number of columns in a table using metadata
public int countColumnsInTable(String sectionType) {
int count = 16;
try {
statement = connection.createStatement();
rset = statement.executeQuery("SELECT * FROM " + sectionType);
rsMetaData = rset.getMetaData();
count = rsMetaData.getColumnCount();
} catch (SQLException e) {
e.printStackTrace();
}
return count;
}
And here is the first part of the exception message:
Column count is 26
java.sql.SQLException: Before start of result set
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
at com.mysql.jdbc.ResultSetImpl.checkRowPos(ResultSetImpl.java:855)
at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5773)
at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5693)
at YogaDatabaseAccess.listPosesInSection(YogaDatabaseAccess.java:126)
at YogaSectionDesigner$5.actionPerformed(YogaSectionDesigner.java:231)
Looks to me like you're re-using the rset between your two methods. So when countColumnsInTable has completed, the rset variable is pointing to a different result set than it was before, in listPosesInSection. And that result set has not been advanced with next, hence the error message you're getting. You probably want to assign it to a local ResultSet within that method instead.
public int countColumnsInTable(String sectionType) {
int count = 16;
try {
Statement statement = connection.createStatement();
ResultSet rset = statement.executeQuery("SELECT * FROM " + sectionType);
ResultSetMetaData rsMetaData = rset.getMetaData();
count = rsMetaData.getColumnCount();
} catch (SQLException e) {
e.printStackTrace();
}
// Remember to clean up
return count;
}
try this
public String listPosesInSection(String tableName, String sectionName) {
String strList;
StringBuilder strBuilderList = new StringBuilder("");
// Run the query
try {
statement = connection.createStatement();
// Query will collect all columns from one specific row
rset = statement.executeQuery("SELECT * FROM " + tableName + " WHERE " + tableName + "_name = '" + sectionName + "'");
while (rset.next()){
System.out.println("Column count is " + countColumnsInTable(tableName));
for (int i = 2; i <= countColumnsInTable(tableName); i++) {// First value (0) is always null, skip first column (1)
System.out.println("test");
strBuilderList.append(rset.getString(i) + "\n");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
strList = strBuilderList.toString();
return strList.replaceAll(", $",""); // Strips off the trailing comma
}
rset is a ResultSet object
i think you are using the same ResultSet object in listPosesInSection and also in countColumnsInTable
so what is happening here is in listPosesInSection rset holds a result and you have also move the cursor but again in countColumnsInTable you are using the same rset so it is overwritten ie it holds a new result now, you are getting the number of columns but since it holds a new result now the cursor will be before the 1st record so use different Resultset object in countColumnsInTable
m trying to loop through 3 resultsets and compare their values. bt its throwing this exception...could someone help me on where am going through?
here is the piece of code:
java.lang.Object[] reconciledPaymentDetails = null;
java.util.Vector shiftsVector = new java.util.Vector(1, 1);
String status = "";
try {
Class.forName("org.postgresql.Driver");
}
catch (ClassNotFoundException ex) {
Logger.getLogger(DBConnection.class.getName()).log(Level.SEVERE, null, ex);
}
try {
connDB = DriverManager.getConnection("jdbc:postgresql://" + hostName + ":" + portNumber + "/" + dbName, userName, password);
System.out.println("Connection established : [" + connDB.toString() + "]");
java.sql.Statement pstmt = connDB.createStatement();
java.sql.Statement pstmtShifts = connDB.createStatement();
java.sql.ResultSet rset = pstmt.executeQuery("SELECT DISTINCT payment_mode,transaction_type, credit FROM ac_cash_collection WHERE shift_no = '" + shiftNumber + "'");
while (rset.next()) {
java.sql.ResultSet rsetShifts = pstmtShifts.executeQuery("SELECT DISTINCT amount, shift_amount FROM ac_shift_collections WHERE shift_no = '" + shiftNumber + "' AND pay_mode ilike '"+rset.getString(1) +"'");
while (rsetShifts.next()) {
java.sql.ResultSet rset2 = pstmt.executeQuery("select debit from ac_cash_book where shift_no='"+shiftNumber+"'");
while (rset2.next()){
double debit =rset2.getDouble("debit");
if((rset2.getDouble("debit")<=0 ))
status = "no_banked";
else if((rset2.getDouble("debit")==rsetShifts.getDouble("amount"))
&& (rsetShifts.getDouble("amount"))< rsetShifts.getDouble("shift_amount"))
status= "BntClosed";
else if (rset2.getDouble(1)==rsetShifts.getDouble("shift_amount"))
status ="bClosed";
shiftsVector.addElement(rset.getString(1)+":"+rsetShifts.getString(1)+":"+status);
}
}
}
The documentation provides a clear explanation of this:
By default, only one ResultSet object per Statement object can be open
at the same time. Therefore, if the reading of one ResultSet object is
interleaved with the reading of another, each must have been generated
by different Statement objects. All execution methods in the Statement
interface implicitly close a statment's current ResultSet object if an
open one exists.
So your options would be:
Use a different Statement instance for each query.
Collect all the results from each ResultSet (i.e. into a Set or a List) before moving on to the next one, and then run the comparison on the collected results instead of directly on the result-sets.
I have some problems with JDBC's rs.getString("column_name") basically it would not assign the value recieved from the query result, I have a String ris which is supposed to get the row name from rs.getString, for semplicity of the question I'm using ris and my query returns only one row. This is the code:
//It returns null, or any other values I use to initialize the variable
String ris=null;
q = "SELECT DISTINCT nome FROM malattia WHERE eta='" + age + "' AND sesso='" + sexstr + "' AND etnia='" + etniastr + "' AND sintomi IN(" + tes + ")";
ResultSet rs = st.executeQuery(q);
if (!rs.last()) {
ris = "no";
}
else {
//This is the place where I'm having problems
while(rs.next()){
//ris is supposed to get the name of the query result having column "nome"
ris=rs.getString("nome");
}
}
conn.close();
} catch (Exception e) {
ris = e.toString();
}
return ris;
I semplified the code, so it would be easy to focus on where the problem is.
Thanks in advance!
if (rs.last())
while (rs.next())
That won't work, because after you have called last , you are at the last row and next will always return false (it would return true and take you to the next row if there was one left).
And please use a prepared statement with bind variables!
And finally close ResultSet and Connection (or use Jakarta Commons DbUtils).
try this, just remove the rs.last() call in the if condition.. also i agree with #Thilo about using prepared statements.
String ris=null;
q = "SELECT DISTINCT nome FROM malattia WHERE eta='" + age + "' AND sesso='" + sexstr + "' AND etnia='" + etniastr + "' AND sintomi IN(" + tes + ")";
ResultSet rs = st.executeQuery(q);
rs.first(); // go to first record.
//This is the place where I'm having problems
while(rs.next()){
//ris is supposed to get the name of the query result having column "nome"
ris=rs.getString("nome");
}
}
conn.close();