i have one problem with database in java
my code is ( its only one small part of my project)
public void Read_from_DB(int exhibition_id){
Statement stmt = null;
Connection connect = null;
try {
connect=MYConnection.new_connection();
stmt = connect.createStatement();
QuestionCatalog.get_QuestionCatalog_instance().setShow_quest(new ArrayList<Question>());
String sql = "SELECT * FROM question WHERE Selection=0 AND exhibition_id="+exhibition_id;
//System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql);
System.out.println("!");
System.out.println("->"+rs.getFetchSize());
while(rs.next()){
Question jd=new Question();
System.out.println("!!!");
jd.setQuestion_id(rs.getInt("Question_id"));
jd.setQuestion(rs.getString("Question"));
jd.setQuestion(rs.getString(exhibition_id));
jd.getOption_2().setContent(rs.getString("Content2"));
QuestionCatalog.get_QuestionCatalog_instance().getShow_quest().add(jd);
System.out.println("size"+QuestionCatalog.get_QuestionCatalog_instance().getShow_quest().size());
MYConnection.close_connection(stmt, connect);
}
}catch (Exception e) {
}
}
when i execute this code it dosent work
my database table name is "question"
but when i change the name in this query to "Question" , don't get any error
then i think it doesn't execute my query,my main is
public static void main(String[] args) {
DB_question d=new DB_question();
d.Read_from_DB(1);
}
and "MYConnection.new_connection();" in part on of code return a connection,( i test it in another class it work)
the result in console is :
SELECT * FROM Question WHERE Selection=0 AND exhibition_id=1
!
->0
it haven't show "!!!"that is result of "System.out.println("!!!");"
then i think it doesnt work :|
thanks
p.s the picture of my db
picture
What I understand from your question is improper output on case sensitive names on table names or column names. Am I right?
As far as I know, reserved words like SELECT, FROM, etc. are case in-sensitive in all OS's. And all other user defined object names are case-sensitive, in *ix OS environment. But not in in Windows OS environment.
But all RDBMS configurations should be allowing case-insensitivity for cross platform deployment. This is the reason why your change from question to Question did not throw an error.
And regarding the outcome of your query:
I fear you have tested your query on different databases or servers. They might not have same data and hence always not entering into while( rs.... loop.
Change your code as below and see what the output is:
ResultSet rs = stmt.executeQuery(sql);
System.out.println("!");
System.out.println("->"+rs.getFetchSize());
rs.beforeFirst();
rs.last();
int rowCount = rs.getRow();
System.out.println( "---> rowCount: " + rowCount );
rs.beforeFirst();
while( ...
Also refer to:
DBMS Identifiers and Case Sensitivity - MysQL
Related
I'm getting the SQLNonTransientException error when trying to update one of my rows in a H2 database.
public static void setNewServiceInformationsToShown() {
try (Connection conn = DriverManager.getConnection("jdbc:h2:" + Main.config_db_location,
Main.config_db_username, Main.config_db_password)) {
//read data from database
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM BCSTASKS_SERVICE");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
if(rs.getString("Status").equals("Neu") && rs.getBoolean("wasShown") == false) {
rs.updateBoolean("WASSHOWN", true);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
The error message already suggests that I should use conn.createStatement and set the ResultSet to CONCUR_UPDATABLE. The error occurs at the line with rs.updateBoolean(...);
Error Message:
The result set is readonly. You may need to use conn.createStatement(.., ResultSet.CONCUR_UPDATABLE). [90140-210]
The problem is I don't know where and how I should use this method. In the same function or at the start of the program?
Most DB code I see doesn't attempt to use the fact that resultsets are updatable, and will instead fire off an additional UPDATE query, which works fine.
However, sure, H2 supports updateable resultsets too. However, some of the features that ResultSets have actually have quite a cost; the DB engine needs to do a boatload of additional bookkeeping to enable such features which have a performance cost. Lots of database queries are extremely performance sensitive, so by default you do not get the bookkeeping and therefore these features do not work. You need to enable them explicitly, that's what the error is telling you.
You're currently calling the 'wrong' preparedStatement method. You want the more extended one, where you pick and choose which additional bookkeeping you want H2 to do for you, in order to enable these things. You want this one.
conn.prepareStatement(
"SELECT * FROM BCSTASKS_SERVICE",
ResultSet.TYPE_SCROLL_INSENSITIVE, // [edited]
ResultSet.CONCUR_UPDATABLE);
That CONCUR_UPDATABLE thing is just a flag you pass to say: Please do the bookkeeping so that I can call .update.
[edited] This used to read 0 before, but as #MarkRotteveel pointed out, that's not valid according to the documentation.
You have to put update query for update data in database but you are going with select query that is the problem.
Select query is used if you have to fetch data from database.
Update query is used for update data in database where data already stored in database but you just overwrite data.
Here down is modified code:
public static void setNewServiceInformationsToShown() {
try (Connection conn = DriverManager.getConnection("jdbc:h2:" + Main.config_db_location,
Main.config_db_username, Main.config_db_password)) {
PreparedStatement stmt = conn.prepareStatement("UPDATE BCSTASKS_SERVICE SET wasShown = ? WHERE status = ? AND wasShown = ?");
stmt.setBoolean(1, true);
stmt.setString(2, "Neu");
stmt.setBoolean(3, false);
stmt.executeUpdate();
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
You need to create a separate query/prepareStatement for an update. In your case as far as I can see you need only one update query:
conn.prepareStatement("UPDATE BCSTASKS_SERVICE SET WASSHOWN=true where
Status = 'Neu' and wasShown = false "
I have a table called "Transactions". It has 5 attributes: Date, Description, Amount, Clientname, Transaction_ID where Transaction_ID is the primary key. In the example Data, the Clientname, "John Smith" has two transactions where he spend 100.10 and 56.56 each. The SQL Query returns the expected result of 156.66 in PHPMyAdmin, but JDBC doesn't seem to recognize it in the ResultSet.
Here is my code:
public void calculate_client_spending() throws SQLException {
ConnectionClass Databaseloader = new ConnectionClass();
Databaseloader.getConnection();
String sql = "SELECT SUM(Amount) AS total FROM Transactions WHERE Clientname = 'John Smith';";
ResultSet rs = Databaseloader.executeSQLRequestCommand(sql);
// rs.next();
// System.out.println(sum);
ResultSetMetaData rsMetaData = rs.getMetaData();
int numberOfColumns = rsMetaData.getColumnCount();
System.out.println(numberOfColumns);
// get the column names; column indexes start from 1
for (int i = 1; i < numberOfColumns + 1; i++) {
String columnName = rsMetaData.getColumnName(i);
// Get the name of the column's table name
if ("total".equals(columnName)) {
System.out.println("Bingo!");
rs.last();
int count = rs.getRow();
rs.beforeFirst();
System.out.println(count);
while (rs.next()) {
Results_trasactions.setText("");
System.out.println("The total profits today are: " + rs.getString(1));
}
}
}
}
This Query returns null in this example, but if I did rs.getDouble(1), it would return 0. Any idea what the issue may be here? I am able to get similar SUM Query's to work, such as a SUM for all clients and the WHERE clause seems to work for my primary key, but this specific Query JDBC doesn't seem to like it even though the SQL is valid in PHPmyadmin which makes me want to believe that it is a Java issue and not a SQL issues. Any help would be greatly appreciated.
Since this is unfortunately way too long for a comment:
Not meaning to be mean, but maybe you shouldn't create a new account to answer your deleted question again (https://stackoverflow.com/questions/59570469) -> Google Cache - also, the Database Classes you're using give away your "real" account (How to retrieve the "total" variable representing a sum in a resultset) - so I'm voting to close this question yet again.
However, to be at least some hints:
ConnectionClass Databaseloader = new ConnectionClass();
Databaseloader.getConnection();
Databaseloader isn't any default JDBC class, but rather some (poorly) written static class, which looks like a weird wrapper to me. You can do it, but by any means you wouldn't do it statically. And by throwing the methods into Google, you find: almost nothing.
For mySQL you'd acquire a database connection like that:
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "sa", "sa")
and rather work with the connection object.
I'd recommend you to do the following:
Read how to connect your database in Java
Read how to create and execute a prepared statement
Read how to extract a result from a result set
Inform yourself about parameter binding (avoid SQL injections)
Profit!
All these topics are well covered on stackoverflow.
I am trying to calculate over time to add it to salary the overtime time stored in table attendance and the salary is stored in other table contain total basic hourly
I want to get the result from the 2 tables display them in java another store in another table for future reference
int Eid = Integer.parseInt(jTextField2.getText());
try{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/hr","root","adam");
String query="SELECT * FROM sallary where Eid ="+Eid +";"
java.sql.PreparedStatement preparedStatement = null;
preparedStatement = con.prepareStatement(query);
String select="select 83 *((time_to_sec(sum(overtime)) /60)/60)from att where Eid="+Eid +";";
java.sql.PreparedStatement preparedStatement2 = null;
preparedStatement2 = con.prepareStatement(select);
int eid;
double basic ,total,hourly;
ResultSet rs2 = preparedStatement2.executeQuery();
ResultSet rs = preparedStatement.executeQuery();
double overtime=rs2.getDouble(1);
// I tried this on MySQL command line it worked, however on java its error:
// the right syntax to use near 'sum(overtime)' at line 2
eid =rs.getInt("Eid");
basic =rs.getDouble("basic");
total=rs.getDouble("total");
hourly=rs.getDouble("hourly");
Object[] row = {eid,basic,total,hourly,overtime};
model = (DefaultTableModel) st.getModel();
model.addRow(row);
} catch (ClassNotFoundException | SQLException ex) {
Logger.getLogger(payroll.class.getName()).log(Level.SEVERE, null, ex);
}
The actual error message you got was something like "See the manual for your version of MySQL for the right syntax to use near 'sum(overtime)' at line 2." This error message tells you exactly what you need to do.
Looking at the manual:
https://dev.mysql.com/doc/refman/5.7/en/select.html
You can see that the SELECT statement syntax does not include a semicolon at the end.
The semicolon is a statement separator, useful when you give multiple statements at the console. JDBC queries are one statement at a time, so the semicolon makes no sense and is a syntax error.
By the way, you should leave out the statement Class.forName("com.mysql.jdbc.Driver");. There is simply no need for it. It was needed in earlier versions, but has been unnecessary for the last 15 years or so.
I am a newbie to Java and MySQL. Please pardon me if my question seems silly, I want to know the answer...
I have gone through many articles and questions asked in forums, but I didn't see a relevant answer for my question...
That is, I have made a switch statement in Java and I want to show the list of available tables in a database if I press 1( that is go into the case 1 and execute a query "show tables;" )
In MySQL Console, it is easy to check for available tables using the same query. But I want to know whether "show tables;" query or similar queries can be executed inside a Java Program...
Here's a sample snippet of my code,
Connection con=null;
String url = "jdbc:mysql://localhost:3306/giftson";
String dbName = "giftson";
String userName = "root";
String password = "password";
con=DriverManager.getConnection(url,userName,password);
Statement st=con.createStatement();
//String query;
Statement st=con.createStatement();
System.out.println("\tDatabase Connection for Various Operations");
System.out.println("\n1. Show list of tables\n2. Show contents of Table\n3. Create New Table\n4. Insert into table\n5. Update Table\n6. Delete From Table\n7. Exit\n");
System.out.println("Enter your option Number ");
DataInputStream dis=new DataInputStream(System.in);
int ch=Integer.parseInt(dis.readLine());
switch(ch)
{
case 1:
System.out.println(" You have selected to Show list of available tables");
//ResultSet rs=st.executeQuery("Show tables");
//while(rs.next())
//{
// System.out.println("List of Tables\n" +rs.getString("?????"));
//}
break;
}
from the above piece of code,
If I execute the query in ResultSet, How do I print the values inside the while loop..?
In rs.getString(); we can only pass either the column index or the column label as argument, but how do I get the list of tables...
what do I enter in place of "?????" inside print statement...?
please do help me, keeping in mind that you are explaining for a beginner...
Thanks in advance...!
We can use the console commands using,
DatabaseMetaData meta=getMetaData();
In the below code, it is shown that there are many ways (but I came to know two ways) of getting the list of tables
DatabaseMetaData meta = con.getMetaData();
ResultSet rs1 = meta.getTables(null, null, null,new String[] {"TABLE"});
ResultSet rs2 = meta.getTables(null, null,"%", null);
System.out.println("One way of Listing Tables");
while (rs1.next())
{
System.out.println(rs1.getString("TABLE_NAME"));
}
System.out.println("Another way of Listing Tables");
while(rs2.next())
{
System.out.println(rs2.getString(3));
}
A small example would be
String tableNamePattern = "%_Assessment_" + session + "_" + year;
DatabaseMetaData databaseMetaData = conn.getMetaData();
ResultSet rs = databaseMetaData.getTables(null, null, tableNamePattern,
null);
while(rs.next()) {
String tableName = rs.getString("TABLE_NAME");
...
}
Check the source
I have a java web application that selects one column from table (with 6 million rows) and it takes a lot of CPU time. This select (SELECT id FROM mytable WHERE filename = 'unique_filename') takes significantly less time when executed in query browser.
What can cause this?
Where should I start to look for bottlenecks?
Database is MSSQL 2005 Standard
Java container is Tomcat 5.5 (with sqljdbc 1.2)
More details:
1.Java code
ResultSet rs = null;
PreparedStatement stmt = null;
Connection conn = null;
Integer myId=null;
String myVeryUniqueFileName = strFromSomeWhere;
try
{
conn = Database.getConnection();
stmt = conn.prepareStatement("SELECT id FROM mytable WHERE filename = ?");
stmt.setString(1, myVeryUniqueFileName);
rs = stmt.executeQuery();
if (rs.next())
{
myId= new Integer(rs.getInt(1));
} }
if (rs.next())
{
throw new DBException("Duplicate myId: " + myId);
}
return myId;
} catch (Exception e) {
// handle this
}
The Database object uses DriverManager to receive connection object.
2.SQL table has about 30 columns.
CREATE TABLE [dbo].[calls](
[id] [int] NOT NULL,
...
[filename] [varchar](50) NOT NULL,
...
CONSTRAINT [PK_xxxxxxxxxxxx] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY],
CONSTRAINT [UQ_xxxxxxxxxxxx] UNIQUE NONCLUSTERED
(
[filename] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
filename column is unique so result set from is allways 1 or null.
With help of way smarter developer I was able to solve this problem. Turns out I was misusing PreparedStatement (aricle).
Based on this I changed java code to:
ResultSet rs = null;
Statement stmt = null;
Connection conn = null;
Integer myId=null;
String myVeryUniqueFileName = strFromSomeWhere;
try
{
conn = Database.getConnection();
stmt = conn.createStatement()
//
rs = stmt.executeQuery("SELECT id FROM mytable WHERE filename = '"
+ myVeryUniqueFileName + "'");
if (rs.next())
{
myId= new Integer(rs.getInt(1));
}
if (rs.next())
{
throw new DBException("Duplicate myId: " + myId);
}
return myId;
} catch (Exception e) {
// handle this
}
After this dababase load fell from average 70% to 13%
Can you post your java code where you're executing this query and retrieving the results?
Possible factors causing Java code to appear to take significantly longer are:
Your query returns a large number of records and you're trying to retrieve them all in Java whereas query browser would only show the first 100 (whatever that number may be) and load others on demand.
You're comparing different times, for example "query took X ms" shown by your query browser with time it takes Java from obtaining the connection till closing it.
Your objects (holding the results) may be expensive to create or they may be doing some processing behind the scenes as they're populated.
I can't speak to MSSQL 2005 specifically, but there can be a difference in execution plan between a prepared statement where you're using bind variables and the equivalent statements where values are embedded.
To test this theory, drop the bind parameter, and instead concatenate the SQL query in Java with the actual filename (in quotes). This way you're comparing apples to apples.
Also, it would be useful with an indication of the difference in CPU time you're experiencing. Is it several orders of magnitude or less than 100%.
The symptoms you describe are most often caused by an incorrectly cached query plan.
Rebuild your indexes or update your statistics.
You are using a statement probably and not a prepared statement. A statement does not get precompiled and cached so the query optimizer has to do the work everytime. If you use a prepared statement it will try and find the best way to execute your query and it will store that. The next time you use it it won't bother to try and work out a good way to get your results it will just the execution plan it already has.