I'm connecting Java to Oracle database, everything's is going pretty okay, except the following problem:
This works okay when I write the whole string within one couple of quotes:
String command =
"SELECT FIRST_NAME, PHONE_NUMBER, SALARY FROM EMPLOYEES WHERE SALARY < 5000";
BUT as the one above doesn't look well-designed code I wanted to split the lines:
String command = new StringBuilder(
"SELECT FIRST_NAME, PHONE_NUMBER, SALARY\n")
.append("FROM EMPLOYEES\n")
.append("WHERE SALARY < 5000;")
.toString();
And meanwhile, I tried plus (+) instead of StringBuilder, but again messed up...
Please help((
String command = new StringBuilder(
"SELECT FIRST_NAME, PHONE_NUMBER, SALARY ")
.append("FROM EMPLOYEES ")
.append("WHERE SALARY < 5000")
.toString();
Using StringBuilder.append() for a constant value is less efficient than writing the constant directly:
String command =
"SELECT FIRST_NAME, " +
" PHONE_NUMBER, \n " +
" SALARY \n " +
"FROM EMPLOYEES \n" +
"WHERE SALARY < 5000";
Salaam,
Why use newline character [\n] which is not understood by sql engines?
It should work without it
Related
I posted a while back a question asking how to implement a search with the following criteria:
On the "Searching" page, the customer can search for movies by any of the following attributes or their combination (logical "AND" operation):
title;
year;
director;
star's first name and/or last name. This means you need to do both: a) first name or last name if only one of the two names is provided; b) first name and last name, if both names are provided.
I then have to spit back out information about that movie from my database given the search input. People suggested I use FullText Search, and I did. This is the solution I have come up with.
String searchInput = request.getParameter("searchInput");
String query = "";
// First see if there is a number in their search
// Note: doesn't consider more specific searches, because it only searches
// based on the given number
if (searchInput.matches("\\d+")) {
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(searchInput);
if (m.find()) {
String number = m.group();
int n = Integer.parseInt(number);
query = "SELECT title, year, director, id " +
"FROM movies " +
"WHERE year = " + n + " " +
"OR title LIKE '%" + n + "%'";
}
} else {
query = "SELECT title, year, director, r.id " +
"FROM movies AS r, stars AS s " +
"WHERE MATCH(title, director) AGAINST('" + searchInput + "*') " +
"OR MATCH(first_name, last_name) AGAINST('" + searchInput + "*') " +
"AND r.id IN (SELECT sim.movie_id " +
"FROM stars_in_movies AS sim " +
"WHERE sim.star_id = s.id " +
"AND sim.movie_id = r.id) " +
"GROUP BY title";
}
ResultSet rs = statement.executeQuery(query);
// Query again, this time ANDing the matches to see if
// there is a more specific search result
Statement statement2 = dbcon.createStatement();
query = "SELECT title, year, director, r.id " +
"FROM movies AS r, stars AS s " +
"WHERE MATCH(title, director) AGAINST('" + searchInput + "*') " +
"AND MATCH(first_name, last_name) AGAINST('" + searchInput + "*') " +
"AND r.id IN (SELECT sim.movie_id " +
"FROM stars_in_movies AS sim " +
"WHERE sim.star_id = s.id " +
"AND sim.movie_id = r.id) " +
"GROUP BY title";
ResultSet rs2 = statement2.executeQuery(query);
if (rs2.next()) {
// If there is a more specific match (ANDing the matches), use that instead
rs2.beforeFirst();
rs = rs2;
}
Now, I know this is REALLY bad code, since I'm executing almost the same query twice, with the only difference being that I AND the matches in the second query. I can't seem to figure out a way to combine the two queries or also reduce the amount of matching done to speed up the query. I also don't have a good way to deal with the year of the movie that the user may or may not input.
Here is what I have tried:
I have tried searching up the FullText Search documentation for some functions that can be included in my search to make my SQL query return the more specific result if it matches more things, but the only thing that comes closest to such a thing is the Boolean Full-Text Search. However, I don't think I can use such a function because I have to distinguish between the different user's keyword inputs.
I have also tried Googling AND/OR operations in MySQL that allows AND when possible, and if not possible, then ORs the query. However, it doesn't seem possible to do this.
UPDATE: I have nested subqueries now and the search is MUCH faster. However, I still need help with improving my code to return the more specific match and only the more specific match, if it exists. Else, return the more general match (if anything at all matches).
Run each sub query separately. You can AND and OR results in code as required, assuming the size of the results are reasonable. Bit more coding, but you only run the necessary queries once.
So the program is the connecting to a .mdb file as our data base. I have written all the other code to the program and know it works fine but I am now having trouble with a complex SQL statement being passed as a parameter to a createQuery(Sring, int) method.
There are two tables
Person, which has Name, Id, City, State
Classes, which has Id, Course, Grade
The intended purpose of this line is to print out "Name and Id" from a table of Persons and also print "Course and Grade" from the Classes table. The query only prints entries with matching Id's(Person.Id = Classes.Id), in a specific Course('CSC 225'), and that have a Grade > 70.
We never were taught the SQL statements in any depth so my basic understanding has concocted the following lines of code.
String s = "SELECT " + personTableTitle + ".Name, " + personTableTitle + ".Id, " +
classesTableTitle + ".Course, " + classesTableTitle + ".Grade FROM " +
personTableTitle + " " + classesTableTitle + " WHERE " +
personTableTitle + ".ID = " + classesTableTitle + ".Id AND " +
"Course = 'CIS 225' AND " + classesTableTitle + ".Grade > 70 AND " +
personTableTitle + ".Id = ? AND " + classesTableTitle + ".Id = ?";
System.out.print(s); // Double check of my SQL Statement before passing
db.createQuery(s, 4);
I have been playing with this SQL statement since Wednesday night and haven't been having much luck.
I only see two problems. Sql needs commas between the table names in the FROM clause, i.e. ...FROM table1, table2 WHERE.... So change your line to
personTableTitle + ", " + classesTableTitle + " WHERE " +
This next one might not be a problem, but it's a good idea to include the table name in front of every field reference.
classesTableTitle + ".Course = 'CIS 225' AND " + classesTableTitle + ".Grade > 70 AND " +
You should definitely try your query directly on the database (console or GUI). Once your query is valid, you'll be able to translate it very quickly back into Java.
Otherwise, it's good practice to add an alias to tables; for example:
select *
from Person P, Classes C
where P.Name = 'joe' and P.id = C.id
You may also need to do an outer join to get your data (look at how to do joins for your database).
Here's what I would suggest for SQL code
String s = "SELECT P.Name, P.Id, ";
s = s + "C.Course, C.Grade ";
s = s + "FROM Person P ";
s = s + "JOIN Classes C ";
s = s + "ON P.ID = C.ID ";
s = s + "WHERE Course = 'CIS 225' AND C.Grade > 70;";
I split up each assignment into its own line.
Solved it everyone, thanks for the help.
I started rewriting it using the suggestions posted and came up with this as the string:
String s = "SELECT Person2.Name, Person2.Id, Classes.Course, Classes.Grade FROM Person2, Classes WHERE Classes.Id = Person2.Id AND Classes.Course = 'CIS 225' AND Classes.Grade >70";
It works so I can make it more presentable now. The reason I am using my variable names from java in the original post was that is what the teacher wanted. She is very stubborn and has taken off points from my material for things as simple as writings += whatever; instead of s = s + whatever;
I am using postgres 9.1 and java code for jdbc.
I may use a order by clause in my sql query string
I just want to get the meta data information of the query to find whether the query has order by clause or not. If it has then how many fields has been specified in the order by clause.
Ex:
order by age
order by age, name
order by age asc, name desc
In these example I just want to retrieve the number of parameters that are specified in the order by clause and their column names.
If your are getting your query as string you could simply parse it.
i.e. To figure out that ORDER BY is there
"SELECT * FROM MyTable ORDER BY SomeColumn".toLowerCase().indexOf("order by") // if it's return -1 query does not contains order by section otherwise it returns start index for first occurence "ORDER BY" in given string
For more complex searching in string you may need to use RegExp
You can do it by breaking an SQL query into part and then reassigning.
Like
String sql="SELECT NAME,COMPANY,FNAME,AGE FROM COMP_DATA JOIN PERSONAL_DATA WHERE (1=1) AND FNAME='Vaibs' ORDER BY AGE";
While writing in JAVA do as below.
Break Whole query into String parts and recombine it like this.
String strSQL = "SELECT " + "NAME"+",COMPANY"+",FNAME"+",AGE" + "FROM "
+ getTableName1(); //getTableName1() return tablename
strSQL+="JOIN "+ getTable2()+"";//getTable2() return tablename as well
String strWhere = " WHERE (1=1) " + " and FNAME='" + fname+ "';
String orderBySQL = " Order by " + i_will_return_string_to_order_by();
//return AGE in our case
String FinalString= strSQL +strWhere +orderBySQL ;
SOP order by to get what you want.
Hope that helped.
Hi I am searching for a name combination in database. I am passing the combination as follows
"firstName='" + firstName + "'", "middleName='" + middleName + "'", "lastName='" + lastName + "'"
This works fine. But the problem comes where there are some " ' " in names how can i rectify it? eg: Johns' or Jerry's etc causes exception
use preparedStatement it is easy for you
ps.executeUpdate("INSERT INTO tb_name values(?,?) WHERE id=?");
ps.setString(1,firstName);
ps.setString(2,middleName);
ps.setInt(3,id);
ps.execute();
At least for MySQL, you have to put another ' before:
INSERT INTO table (column) VALUES ('this isn''t it');
If you're using Hibernate, you should use like this:
Query query = session.createQuery("from Something s where s.firstName = :firstName and s.middleName = :middleName and s.lastName = :lastName");
query.setString("firstName", firstName);
query.setString("middleName", middleName);
query.setString("lastName", lastName);
List<?> list = query.list();
Hope this can help you!
You can see more at here and here
String firstName="X";
String middleName="Y";
String lastName="Z";
"firstName='" + firstName + "',middleName='" + middleName + "',lastName='" + lastName + "'";
You can use this to get output as
firstName='X',middleName='Y',lastName='Z'
You can ignore sinqle quotation characters (') in SQL by escaping them with a backslash \'.
Try this:
firstName = firstName.replace("'" , "''");
Use PreparedStatement instead , you would be better with that.
I guess the following also works (at least for MySQL):
SELECT login FROM usertable WHERE lastname="O'Neil";
I am trying to use a MapSqlParameterSource to create a query using a Like clause.
The code is something like this. The function containing it receives nameParam:
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE :pname ";
String finalName= "'%" +nameParam.toLowerCase().trim() + "%'";
MapSqlParameterSource namedParams= new MapSqlParameterSource();
namedParams.addValue("pname", finalName);
int count= this.namedParamJdbcTemplate.queryForInt(namecount, namedParams);
This does not work correctly, giving me somewhere between 0-10 results when I should be receiving thousands. I essentially want the final query to look like:
SELECT count(*) FROM People WHERE LOWER(NAME) LIKE '%name%'
but this is evidently not happening. Any help would be appreciated.
Edit:
I have also tried putting the '%'s in the SQL, like
String finalName= nameParam.toLowerCase().trim();
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE '%:pname%' "
;
but this does not work either.
You don't want the quotes around your finalName string. with the named parameters you don't need to specify them. This should work:
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE :pname ";
String finalName= "%" + nameParam.toLowerCase().trim() + "%";
MapSqlParameterSource namedParams= new MapSqlParameterSource();
namedParams.addValue("pname", finalName);
int count= this.namedParamJdbcTemplate.queryForInt(namecount, namedParams);
This solution worked for me. I put the "%" on the Object[] parameters list:
String sqlCommand = "SELECT customer_id, customer_identifier_short, CONCAT(RTRIM(customer_identifier_a),' ', RTRIM(customer_identifier_b)) customerFullName "
+ " FROM Customer "
+ " WHERE customer_identifier_short LIKE ? OR customer_identifier_a LIKE ? "
+ " LIMIT 10";
List<Customer> customers = getJdbcTemplate().query(sqlCommand, new Object[] { query + "%", query + "%"}, new RowMapper<Customer>() {
public Customer mapRow(ResultSet rs, int i) throws SQLException {
Customer customer = new Customer();
customer.setCustomerFullName(rs.getString("customerFullName"));
customer.setCustomerIdentifier(rs.getString("customer_identifier_short"));
customer.setCustomerID(rs.getInt("customer_id"));
return customer;
}
});
return customers;
Have you tried placing the % wild cards in your sql string (not the bind variable value itself):
String finalName= nameParam.toLowerCase().trim();
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE '%:finalName%'";
We can use simple JdbcTemplate instead of NamedParamJdbcTemplate
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE ? ";
String finalName= "%" +nameParam.toLowerCase().trim() + "%"; //Notes: no quote
getJdbcTemplate().queryForInt(namecount, new Object[] {finalName});
Hope it helpful for someone using JdbcTemplate