Hi my aim is to load combobox with vaules from a database the code below works fine with one issue i get two of the first item so what must i do to prevent this
public void loadCombos() {
try {
try {
String cs = "jdbc:mysql://localhost:3307/booksalvation6";
String user = "root";
String password = "letmein";
jComboBox2.removeAllItems();// make sure old data gone
PreparedStatement pstpost;
ResultSet rspost;
conCombos = DriverManager.getConnection(cs, user, password);
for (int i = 1; i < 11; i++) {
String querypost = "select * from post "
+ "WHERE postage_id =" + i;
// load postage selections
pstpost = conCombos.prepareStatement(querypost);
rspost = pstpost.executeQuery();
while (rspost.next()) {
String Mypost = rspost.getString(6);
jComboBox2.addItem(Mypost);
}
}
} catch (SQLException ex) {
Logger.getLogger(BasicFrame.class.getName()).log(Level.SEVERE, null, ex);
}
conCombos.close();
} catch (SQLException ex) {
Logger.getLogger(BasicFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
You are using PreparedStatement but not in proper way.
Since you are looking only for one column to fetch all the column values which have postage_id between 1 to 10.
You can achieve it in single query:
select unique(combo_value_column_name) from post
where postage_id>=? and postage_id<=?
set the parameter via calling PreparedStatement#setInt(index,value) set it 1 and 10.
Just fetch single column and only unique values.
It's better explained under Java Tutorial on Using Prepared Statements
Instead of calling JComboBox#addItem() first prepare the whole list then finally set it once.
Read more...
Final Note: Follow Java Naming Convention.
Related
I have a class called "Database" that is working perfectly well. It queries a database and returns the results as a string. When I call the class from my "Test" class it returns the results string and I can print it with System.out.println().
I'm trying to use this class on a JSP page using the same two lines of code to instantiate the class and get the string output. When I try to output on the JSP page I get nothing. What am I doing wrong? I'm completely stumped.
Class Code:
public class Database {
static String[][] reservations = new String[7][20];
public Database (String theDate) {
String url = "jdbc:mysql://myurl.com:3306/";
String driver = "com.mysql.cj.jdbc.Driver";
String user = "myusername";
String pass = "mypassword";
String db = "class";
String options = "?useSSL=false";
try (Connection conn = DriverManager.getConnection(url + db + options, user, pass);
Statement statement = conn.createStatement()) {
String query = "select reservation.first, reservation.last, startday, numberofdays, guides.first as guidefirst, guides.last as guidelast, locations.location from reservation left join guides on reservation.guide = idguides left join locations on reservation.location = idlocations where StartDay >= " + theDate;
ResultSet rs = statement.executeQuery(query);
int row = 0;
while (rs.next()) {
reservations[0][row] = rs.getString("first");
reservations[1][row] = rs.getString("last");
row++;
}
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public String getStringRes () {
String returnString = "";
for(int i=0; i<20; i++) {
if (reservations[0][i] != null) {
returnString += i + " " + reservations[0][i];
returnString += " " + reservations[1][i] + "\n";
}
}
return returnString;
} }
JSP Code:
<%# page import="mypackage.Database" %>
<%
Database db = new Database("2015-07-01");
String str = db.getStringRes();
%>
<%= str %>
Your code contains 3 mistakes.
The most problematic
} catch (SQLException e) {
e.printStackTrace();
}
Don't ever do that. Go into your IDE settings and eliminate this template. It should be throw new RuntimeException("Unhandled", e); instead.
Here's what happened: Your SQL statement is erroneous (in two ways, even). This causes an exception. Your code handles this by ignoring it (it's printed, but, your code finishes normally). Hence, the string result remains blank (because it starts out that way and the code that is supposed to give it its real value never ran, due to the exception that you ignored).
Your SQL is broken.
The actual explanation is that date literals need to be in quotes, in SQL. Yours is not.
But that's not how you pass parameters into SQL.
The bigger issue is that passing any value like this into an SQL means your machine will be hacked in a matter of days. That's called 'SQL injection'. You don't want it. The solution is preparedstatements, where you let the JDBC driver and/or the database take care of escaping or otherwise passing string data without the SQL db engine trying to interpret it as SQL (Because, obviously, letting arbitrary users type stuff in that your DB engine then treats as SQL means you're just waiting for someone to construct some SQL such that your db engine ends up executing DROP TABLE reservation CASCADE; EXECUTE 'FORMAT C: /Y'; --.
Minor style nit
Doing business logic in constructors is a bad idea. The query should be done from getStringRes, most likely. That's also a bit of a crazy method name. Not very informative.
Which gets us to...
try (Connection conn = DriverManager.getConnection(url + db + options, user, pass);
PreparedStatement statement = conn.prepareStatement("SELECT reservation.first, .... FROM .... WHERE StartDay >= ?")) {
statement.setString(1, theDate);
try (ResultSet rs = statement.executeQuery()) {
...
}
} catch (SQLException e) {
throw new RuntimeException("unhandled", e);
}
This is the code where I'm trying to execute a second query on the resultSet of my first lengthy query. I need to upload this
data somewhere.
Is it the right thing to do?
Or is there a better approach apart from querying the database again?
public String createQuery() throws SQLException {
StringBuilder Query = new StringBuilder();
try {
Query.append(" SELECT ...... ")
} catch (Exception e) {
e.printStackTrace();
}
return Query.toString();
}
private void openPreparedStatements() throws SQLException {
myQuery = createQuery();
try {
QueryStatement = dbConnection.prepareStatement(myQuery);
} catch (SQLException e) {
e.printStackTrace();
return;
}
}
public ResultSet selectData(String timestamp) throws SQLException {
openConnection();
ResultSet result = null;
ResultSet rs_new=null;
try {
result = QueryStatement.executeQuery();
while (result.next()) {
String query = "SELECT * FROM " + result + " WHERE " + "ID" + " =" + "ABC";
rs_new =QueryStatementNew.executeQuery(query);
System.out.print(rs_new);
}
} catch (SQLException e) {
LOGGER.info("Exception", e);
}
return result;
}
Instead of running two separate queries (when you don't need the intermediate one) you can combine them.
For example you can do:
SELECT *
FROM (
-- first query here
) x
WHERE ID = 'ABC'
You cannot use two statement objects within one database connection. So you can either open another database connection and execute the second statement in the 2nd connection, or iterate through the resultset from first statement and store the value you need (e.g. in an array/collection) then close that statement and run the second one, this time retrieving the value from the array/collection you saved them in. Refer to Java generating query from resultSet and executing the new query
Make Db2 keep your intermediate result set in a Global Temporary Table, if you have an ability to use it, and you application uses the same database connection session.
DECLARE GLOBAL TEMPORARY TABLE SESSION.TMP_RES AS
(
SELECT ID, ... -- Your first lengthy query text goes here
) WITH DATA WITH REPLACE ON COMMIT PRESERVE ROWS NOT LOGGED;
You may send the result of subsequent SELECT ... FROM SESSION.TMP_RES to FTP, and the result of SELECT * FROM SESSION.TMP_RES WHERE ID = 'ABC' to elastic.
I have a phonebook project I'm trying to make for school.
I want to be able to change a value of a certain field.
I print the field that are changeable.
before i had PRIMARY KEY it changed everyone for example if i changed the name, it would change everyone that is on the list name.
Now I tried to catch a specific one with a id as primary key and it throws this exception:
Parameter index out of range (2 > number of parameters, which is 1).
(this code now works if someone will see it in the future :)
I incremented the contactNum in the editConatct() to match it with the id field in my MySQL data base )
my edit code:
protected void editContawct(){
System.out.print("Which One You Want To Edit: ");
ArrayList<String> fields = editContactHelper();
ArrayList<Person> people = checkMoreThanOne();
int contactNum = menu(people);
int option = menu(fields);
System.out.println("Please Enter The Changes");
String changes = MyUtills.readStringFromUser();
String sql = "UPDATE " + DB_NAME + " SET " + fields.get(option) + " = ? WHERE ID = ?";
try {
statement = db.prepareStatement(sql);
statement.setString(1, changes);
statement.setInt(2,contactNum + 1); //contactNum `incremented to match 'id' field in my MySQL.`
statement.executeUpdate();
System.out.println("worked ?");
} catch (SQLException e) {
e.printStackTrace();
}
}
//todo add a param that accepts a String that is the data base name.
private ArrayList<String> editContactHelper(){ // should accept data base name
ArrayList<String> fieldsName = new ArrayList<>();
//todo switch the constant to the accepted argument (data base name). so if someone else wants to use this method :)
String sql = "SELECT * FROM " + DB_NAME; // should be databaseName;
try {
ResultSet resultSet = db.prepareStatement(sql).executeQuery();
ResultSetMetaData meta = resultSet.getMetaData();
for (int i = 1; i <= meta.getColumnCount(); i++) {
if(meta.getColumnName(i).equals("id")){
continue;
}
fieldsName.add(meta.getColumnName(i));
}
System.out.println("it worked Homie");
return fieldsName;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
Each ? is your query should relate to one parameter
But you have a mismatch
statement.setString(1, changes);
statement.setInt(2,contactNum);
as you only have one ?
I want compare to the data sent with all data in the db. this coce compare the date insert only with the last row. how can I compare with all row in the db?
................................................................................................
String sData= request.getParameter("idatadata");
String sAzienda= request.getParameter("idazienda");
String sCommessa= request.getParameter("idcommessa");
String date = "";
String company = "";
String order = "";
Connect con = new Connect();
try {
Connection connection = con.createConnection();
Statement statement = connection.createStatement();
String sql ="SELECT * FROM table";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()) {
date = resultSet.getString("iddata");
company = resultSet.getString("idazienda");
order = resultSet.getString("idcommessa");
}
if((sData.equals(date) && sAzienda.equals(company)) && sCommessa.equals(order)) {
out.print("already sent");
con.closeConnection(connection);
}
else {
DbConnect.insertInDb(connection, sData, sOre, sMinuti, sAzienda, sCommessa, sRifInterno);
dbc.closeConnection(connection);
response.getWriter().append("ok! ");
}
} catch (Exception e) {
e.printStackTrace();
}
}
The reason why you are checking only the last row, is that your while loop keeps overwriting your local variables each time you retrieve a row:
while(resultSet.next()) {
// these lines overwrite the local vars for each row
date = resultSet.getString("iddata");
company = resultSet.getString("idazienda");
order = resultSet.getString("idcommessa");
}
But you don't actually check the local vars inside the loop before moving on to the next row from the db. You should add the check into the loop:
while(resultSet.next()) {
date = resultSet.getString("iddata");
company = resultSet.getString("idazienda");
order = resultSet.getString("idcommessa");
// add your check here
if((sData.equals(date) && sAzienda.equals(company)) && sCommessa.equals(order)) {
out.print("already sent");
break;
}
}
Preferably, just perform a select based on the data you are looking for. If you get no results, then the data isn't in the db. This method is much more efficient. If you do decide to go down this path (which is a good idea), use a prepared statement so that you don't introduce a SQL injection vulnerability into your code.
My JAVA script consists of 2 JAVA classes: RMS, queryRMS
In the RMS class I call the method in the queryRMS class
RMS Java Class (I left out the start execution part, below is just the method)
for (int i = 1; i <= itemCount; i++) {
GlobalVariables.numberRow = i;
JavaDatapool.settings();
String item = queryRPM.connectDB_Multi(configFile,"SELECT ITEM FROM ORDSKU WHERE ORDER_NO = '" + orderNo + "' ORDER BY ITEM ASC",i);
JavaDatapool.writeXLS("item",item,GlobalVariables.sheetXLS);
sleep(1);
}
queryRMS JAVA class
public static String connectDB_Multi(String configFile, String query, int i) throws FileNotFoundException, IOException, SQLException, ClassNotFoundException{
Properties p = new Properties();
p.load(new FileInputStream(configFile));
String serverName = (p.getProperty("RMS_DBServerName"));
String portNumber = (p.getProperty("RMS_PortNumber"));
String sid = (p.getProperty("RMS_SID"));
String url = "jdbc:oracle:thin:#//" + serverName + ":" + portNumber + "/" + sid;
String username = (p.getProperty("RMS_Username"));
String password = (p.getProperty("RMS_Password"));
// jdbc:oracle:thin:#//localhost:1521/orcl
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connection = DriverManager.getConnection(url,username,password);
String setr = null;
try {
Statement stmt = connection.createStatement();
try {ResultSet rset = stmt.executeQuery(query);
try {
while(rset.absolute(i))
setr = rset.getString(1);
return setr;
}
finally {
try { rset.close();
}
catch (Exception ignore) {}
}
}
finally {
try { stmt.close();
}
catch (Exception ignore) {}
}
}
finally {
try { connection.close();
}
catch (Exception ignore) {}
}
}
So what it does is call the connectDB_multi class and then returns the String where the next part is saving it inside an Excel worksheet.
The loop should return all rows, one at a time and then save it inside the Excel worksheet.
In the second time in loop the query is faulted, eventhough the query should return 1 column consisting of 2 rows.
the original contained the part while(rset.next()) instead of while(rset.absolute(i))
but next only return the first row everytime. so the script works when only one column and row is retrieved from the Database.
Your logic looks a bit messed up.
Look at the first loop you posted. You are, effectivly, executing:
SELECT ITEM FROM ORDSKU WHERE ORDER_NO = '" + orderNo + "' ORDER BY ITEM ASC
itemCount number of times. Each time you execute it, you are attempting to access the n:th row, n being loop counter. Do you see a problem there? How do you know that the query will return itemCount number of rows? Because if it doesn't, it will fail since you are attempting to access a row that doesn't exist.
What I suspect you WANT to do is something like this
Statement stmt = connection.createStatement();
ResultSet rset = stmt.executeQuery(query);
while(rset.next()) {
JavaDatapool.writeXLS("item",rset.getString(1),GlobalVariables.sheetXLS);
}
You should also seriously consider using some form of connection pooling to avoid having to re-open new connections all the time as that is a pretty time-consuming operation.
This code seems very inefficient, for each row you want to fetch from the database you read a property file, create a connection, select all matching rows, skip ahead to the row you want and return just that row. (Or at least I think that is what you are trying to do).
Your code
while(rset.absolute(i))
setr = rset.getString(1);
is probably an infinite loop as it will continue to go to the same row as long as it is ok to go to that row, so either that row does not exist (and the while exists) or the row does exist (and while continues forever).
You should probably restructure your program to only do one select and read all rows that you want and store them in your excel file. While doing this, you can debug to see if you actually are getting the data you expect.
Apart from the inefficient code of creating new connections and querying once for each row, how do you know how many rows you want?
I think in the end you want something like this
....
while(rset.next()) {
JavaDatapool.writeXLS("item",item,GlobalVariables.sheetXLS);
}
And what is the sleep(1) support to accomplish?
FYI: if you open and close statement too often as your logic or pap's solution, you can get the " java.sql.SQLException: ORA-01000: maximum open cursors exceeded" error message.
I suggest you to not do 'too much generalize'. I saw a lot of OOP programmers overdid generalization and that is painful. You should design by a goal and the goal should not be 'just alignment' nor 'code look beautiful', it has to have a purpose for designing.