when I connect to database and execute a query, then if there occurs any exception then I want to fetch only the reason of exception not the full message , so that in my log I can log only the reason of exception for example. one exception is below by applying getMessage() on exception object in catch block
[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid object name 'tty'.
So I want to fetch only "Invalid object name 'tty'".
The exception will occur only due to executeUpdate() method. so exception may be anything related to database or sqlquery not just Invalid object name 'tty'.
I can't see anything obvious in SQLException, but I can think of two options:
Remove everything in square brackets, possibly with a regex.
If you're always using the same driver, just remove the leading predictable leading substring
Sample code for the second option:
private static final String MESSAGE_PREFIX =
"[Microsoft][ODBC SQL Server Driver][SQL Server]";
...
String message = exception.getMessage();
if (message.startsWith(MESSAGE_PREFIX))
{
message = message.substring(MESSAGE_PREFIX.length());
}
That's likely to be considerably easier than the first option, but is obviously rather more brittle in the face of driver changes. I wouldn't be surprised to see the message format change for different drivers anyway though...
as #Jon Skeet suggested I think better to use first option for regex and apply following code in catch block
Pattern p=Pattern.compile("\[.*\]");
Matcher m=p.matcher(e.getMessage());
int end=0;
while(m.find()){
end=m.end();
System.out.println(m.start()+" "+m.end());
}
System.out.println(e.getMessage());
System.out.println(e.getMessage().substring(end));
then it gives following output
0 47
[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid object name 'tty'.
Invalid object name 'tty'.
Related
I want to handle exceptions, which are thrown from a query (find(...).first()) to MongoDB (Driver 3.7) in Java (the database is not stored locally). However there are no possible exceptions named in the JavaDocs and also in the MongoDB documentaton itself. Can there really occur no exceptions? I doubt that, because I think there could occur e.g. some network errors.
My queries look something like this:
final MongoCollection<Document> collection = database.getCollection("my-collection");
final Bson bsonFilter = Filters.eq("someName", "test");
final Document result = collection.find(bsonFilter).first();
Consider the following code. It connects to a MongoDB instance locally and gets a collection named "test" from the database named "users".
final String connectionStr = "mongodb://localhost/";
MongoClient mongoClient = MongoClients.create("mongodb://localhost/");
MongoDatabase database = mongoClient.getDatabase("users");
MongoCollection<Document> collection = database.getCollection("test");
If you provide a wrong host name for the connectionStr value, like "mongodb://localhostXYZ/" (and no such host exists) the code will throw an exception, like:
com.mongodb.MongoSocketException: localhostXYZ},
caused by {java.net.UnknownHostException: localhostXYZ}}],
..., ...
com.mongodb.MongoSocketException is a MongoDB Java driver exception. It is a runtime exception. It is also a sub-class of MongoException. From the MongoDB Java API:
public class MongoException extends RuntimeException
Top level Exception for all Exceptions, server-side or client-side, that come
from the driver.
The documentation also lists the following are sub-classes (all are runtime exceptions)
MongoChangeStreamException, MongoClientException, MongoExecutionTimeoutException, MongoGridFSException, MongoIncompatibleDriverException, MongoInternalException, MongoInterruptedException, MongoServerException, MongoSocketException.
So, all the exceptions thrown by MongoDB Java driver APIs are runtime exceptions. These are, in general, not meant to be caught and handled (but, you know how to use try-catch, and a runtime exception can be caught and handled).
Let us consider your code:
final MongoCollection<Document> collection = database.getCollection("my-collection");
final Bson bsonFilter = Filters.eq("someName", "test");
final Document result = collection.find(bsonFilter).first();
The first statement database.getCollection("my-collection"), when it runs the code is looking for a collection named "my-collection".
If you want to make sure the collection exists in the database, then verify using the listCollectionNames​() and check the collection name exists in the returned list. In case the collection name doesn't exist, you can throw an exception (if you want to). This exception is what you have figure:
if you want to tell the user or the application that there was no
such collection named "my-collection", you can show or print a
message saying so (and then abort the program) or throw a runtime
exception with an appropriate message.
So, the code might look like this:
if listCollectionNames​() doesn't contain "my-collection"
then
print something and abort the program
-or-
throw a runtime exception
else
continue with program execution
Your code final Document result = collection.find(bsonFilter).first(); is not correct. collection.find returns a FindIterable<TDocument> not a Document. So, the query output can be determined by further examining the FindIterable object; it may have documents or none. And, the find method doesn't throw any exceptions.
Based on if there are any documents returned or not you can show a message to the client. This is not a case you throw an exception.
String sql="insert into return (Student_ID,S_Name,F_Name,Course,Branch,Year,Semester,Book_ID,B_Name,Edition,Publisher,Price,Pages,Date_Of_Issue,Date_Of_Return) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
Error Says:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'return values-->
stm=con.prepareStatement(sql);
stm.setString(1,jTextField1.getText());
stm.setString(2,jTextField2.getText());
stm.setString(3,jTextField3.getText());
stm.setString(4,jTextField4.getText());
stm.setString(5,jTextField5.getText());
stm.setString(6,jTextField6.getText());
stm.setString(7,jTextField7.getText());
stm.setString(8,jTextField8.getText());
stm.setString(9,jTextField9.getText());
stm.setString(10,jTextField10.getText());
stm.setString(11,jTextField11.getText());
stm.setString(12,jTextField12.getText());
stm.setString(13,jTextField13.getText());
stm.setString(14,jTextField14.getText());
stm.setString(15, ((JTextField)jDateChooser1.getDateEditor().getUiComponent()).getText());
stm.execute();
JOptionPane.showMessageDialog(null,"Book Returned");
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, e);
First rename the "return" table in something else, it will prevent you about many error that can occur in the database or into java. Return is a reserved keyword in many cases.
In order to execute an insert you should use the stmt.executeUpdate() function.
Furthermore you should use named parameters to ensure each parameter is what it should be.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
private void subtractCredit(String accountType){ //subtract credit by 1
String CREDITS = "UPDATE CUSTOMERS SET "+accountType+" = "+accountType+" -1, CREDITSUSED=CREDITSUSED+1 WHERE USERNAME='"+username+"'";
try{
ps=con.prepareStatement(CREDITS);
ps.executeUpdate();
}catch(Exception e){
System.out.println(e);
}
}
public String[] getAccount(String accountType){ //Generate a random account.
accountType = "Select * FROM "+accountType+" ORDER BY RAND()";
String[] arr = new String[2];
try{
ps = con.prepareStatement(accountType);
rs = ps.executeQuery();
if(rs.next()){
arr[0] = rs.getString("USERNAME");
arr[1] = rs.getString("PASSWORD");
subtractCredit(accountType);
}
}catch(Exception e){
System.out.println(e);
}
return arr;
}
Here is the catch exception.
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'Select * FROM
TABLE ORDER BY RAND() = Select * FROM TABLE ORDER BY RAND() -1' at
line 1
PLEASE HELP!
What's wrong with my SQL update?
The problem is not in your SQL update!!
Look at the SQL in the error message:
Select * FROM TABLE ORDER BY RAND()
Questions you should ask yourself:
Does that look anything like the update SQL? Nope!!
And what is missing from the 'select'? There is no table name!
If getAccount() is the method that is responsible for this error, then the cause should be obvious to anyone who bothers to read the code. The value of accountType is wrong. If the code is excactly as you have shown us, accountType must contain the string "TABLE". That is not going to work because TABLE is an SQL reserved word. A table called TABLE is a schema design error, because it leads to SQL syntax errors.
The other possibility is that the code actually says this:
accountType = "Select * FROM TABLE " +
accountType + " ORDER BY RAND()";
If so, the problem is that you have called the method with an empty string as the account type.
When you have fixed that, I want you to focus on a number of other significant problems in your code:
Assembling SQL by string bashing like this:
accountType = "Select * FROM "+accountType+" ORDER BY RAND()";
is potentially dangerous. If the value of accountType can come from user input, an HTTP request parameter, or anything else that is not under your control, then this code is vulnerable to an SQL injection attack.
The normal solution is to use a constant SQL string with ? placeholders, and then inject the actual parameter values using PreparedStatement.setXxxx method calls. Unfortunately, a table name can't be injected that way.
Catching Exception like you are doing is a BAD IDEA. Sure, it catches the SQLException that you are anticipating. The problem is that it also catches a bunch of other exceptions that you may not be anticipating. For example, if the code in the try block had a bug that caused it to throw a NullPointerException ... you would catch that too.
Using System.out.println(e) to output a "diagnostic" is bad:
For an end user, the exception message is opaque an alarming.
For a developer, you really need a stacktrace.
Sending developer diagnostics to standard output is generally a bad idea. Use a logging framework.
Your error recovery is almost certainly wrong. If the SQL query fails, then your getAccount method returns an String[2] containing null strings. If the calling code doesn't test for this, then you are likely to get an NPE when you try to use the (bogus) account details.
The correct thing to do is most likely to throw another exception, or if you don't want to add code to handle this up-stack, then allow the SQLException to propagate by removing the try catch ... and declaring the exception in the method signature.
This is minor, but most people think that updating the value of a method parameter is bad style. You are doing this when you assign a new value to accountType. Better style would be to declare a local variable and use that to hold the SQL string.
Consider this sequence of statements (drawn from two methods, but the variable names correspond):
getAccount("TABLE"); // inferred
accountType = "Select * FROM "+accountType+" ORDER BY RAND()";
String CREDITS = "UPDATE CUSTOMERS SET "+accountType+" = "+accountType
+ " -1, CREDITSUSED=CREDITSUSED+1 WHERE USERNAME='"+username+"'";
ps=con.prepareStatement(CREDITS);
ps.executeUpdate();
The error indeed occurs in your UPDATE statement, but only part of it appears in the message. The sequence of statements above explains how it got that way. In particular, consider the effect of the assignment to accountType on the subsequent statements.
I have follwinig code for search data.
public void advanceSearchMethod(String advanceName, int advanceTpNumber, String advanceAddress, String advanceDescription){
Connection connection=null;
try{
//for connect to database.
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost/contactbook","root","time1");
//for communicate with database.
Statement stmt=(Statement)connection.createStatement();
String searchQuery="SELECT * FROM Contacts WHERE Name LIKE '%'"+advanceName+"'%' AND TelePhoneNumber LIKE '"+advanceTpNumber+"%' OR Address LIKE '%'"+advanceAddress+"'%' OR Description LIKE '%'"+advanceDescription+"'%'";
rs=stmt.executeQuery(searchQuery);
contactTableInDefaultForm.setModel(DbUtils.resultSetToTableModel(rs));
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Sorry! Connection Failed");
}
}
No errors in this code.but work catch block. I cannot imagine what I should do. How can I search them?
You have a major bug -- when you build the WHERE clause, you have spurious ' apostrophes after '% opening-quote & wildcard and before %' closing-wildcard & quote.
Your broken code: "WHERE Name LIKE '%'"+advanceName+"'%'"
Corrected: "WHERE Name LIKE '%"+advanceName+"%'"
But the whole code is not good code, at all -- every single thing is wrong with it.
WHERE clauses should be built up only with the conditions you actually need to search on. And should use PreparedStatement and ? bound parameters, rather than building string-literals into the SQL. (You have built a well-known security flaw.)
PhoneNumbers are strings, not integers. The LIKE pattern for TelePhoneNumber doesn't have a starting %.
DB connection should be provided from one class & method, rather than in every method in your application.
Errors in separate operations (getting the connection/ vs. executing the query and reading results) should be checked & reported separately. Exceptions and stacktraces should always be logged (use Log4J) or, at the worst case, output to the console.
The single only thing you got right here, was the variable & parameter naming.
To be honest, you ought to be using Hibernate rather than writing this rickety nonsense.
String searchQuery="SELECT * FROM Contacts WHERE Name LIKE '%'"+advanceName+"'%' AND TelePhoneNumber LIKE '"+advanceTpNumber+"%' OR Address LIKE '%"+advanceAddress+"%' OR Description LIKE '%"+advanceDescription+"%'";
U have added addition single quatation..
Hope this is right answer..
I am trying to doing some SQL queries out of Oracle 11g and am having issues using ora:contains. I am using Spring's JDBC implementation and my code generates the sql statement:
select *
from view_name
where column_a = ?
and column_b = ?
and existsNode(xmltype(clob_column),
'record/name [ora:contains(text(), "name1") > 0]',
'xmlns:ora="http://xmlns.oralce.com/xdb"') = 1
I have removed the actual view / column names obviously, but when I copy that into sqlplus and substitute in random values, the select executes properly. When I try to run it in my DAO code I get this stack trace:
org.springframework.jdbc.UncatergorizedSQLException: PreparedStatementCallback;
uncatergorizedSQLException for SQL [the big select above]; SQL state [99999];
error code [31011];
ORA-31011: XML parsing failed.
ORA-19202: Error occured in XML processing
LPX-00607: Invalid reference: 'contains';nested exception is java.sql.SQLException:
ORA-31011: XML parsing failed
ORA-19202: Error occured in XML processing
LPX-00607: Invalid reference: 'contains'
(continues on like this for awhile....)
I think it is worth mentioning that I am using Maven and it is possible I am missing some dependency that is required for this. Sorry the post is so long, but I wanted to err on the side of too much info.
Thanks for taking the time to read this at least =)
-Windle
You appear to have a spelling mistake in your namespace declaration:
'xmlns:ora="http://xmlns.oralce.com/xdb"'
^^
If that really is a typo in your code (rather than just in your posting here) it can't hurt to fix it.