I have the following SQL line (within a loop):
ResultSet rs = stmt.executeQuery("SELECT * FROM item WHERE itemName='"+ string.get(1) +"'");
string.get(1) contains a different string each time the loop goes.
in the current SQL line I will revive only the lines that are equal to string.get(1),
but I'd like to get all lines that string.get(1) is a sub string of itemName
I know it should go: %string.get(1)% however I don't know the exact syntax.
Anyone can help?
Use the LIKE clause in SQL.
ResultSet rs = stmt.executeQuery
("SELECT * FROM item WHERE itemName LIKE '%"+ string.get(1) +"%'");
you mean this?
SELECT * FROM TABLE WHERE COL LIKE '%SOME_TEXT%';
Related
When I use the following code it runs perfectly.
PreparedStatement st = con.prepareStatement("select * from users where username=?");
st.setString(1, userId);
ResultSet rs = st.executeQuery();
But when I am using the following code, I get an error that userId (that I pass as parameter) is an invalid column name.
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from users where username="+userId);
Why statement method doesn't work and I have to use PreparedStatement?
User ID is a string (SQL calls this type CHAR or VARCHAR), it must be put in quotes if used in the SQL requests. Like this:
select * from users where username='12345'
PreparedStatement is much better solution because of the SQL injection. You CANNOT just write:
ResultSet rs = st.executeQuery("select * from users where username=\""+userId+"\"");
WRONG CODE - ^^^^^^^^^^^^^^^
because user ID can contains control characters like ['], ["] or [\]. It depends on the SQL server and sometimes are more sophisticated than it looks like. If using PreparedStatement, it is automatically managed by the JDBC driver.
First of all, is better to use the first one. But if you really want to use the second one, you need to put your value into quotes. Simple add the quotes to the value. But is good to create a function to it, if you are going to use it a loot. Like:
public String doubleQuoted(String value){
return "\"" + value + "\"";
}
or
public String singleQuoted(String value){
return "'" + value + "'";
}
and use
ResultSet rs = st.executeQuery("select * from users where username="+singleQuoted(userId));
You need to put strings into quotes:
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from users where username=\'"+userId+"\'");
\ is the escape character.
Note:
Your prepared statement is the preferred way of handling SQL queries. See #30thh answer as to why (SQL Injection attacks).
I'm searching on the web for several times but did not found anything which could help me (in java).
In fact I need to search in a sql table some rows from some reference which contains an hyphen. The issue made is that the sql replace my reference by the result of a substraction. The type of the columns are string.
Statement stmt = con.createStatement();
String query = "SELECT * FROM WAREHOUSE WHERE REF LIKE('96-18')" ;
Statement statement = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = statement.executeQuery(query);
while (rs.next()) {
System.out.println(rs.getString("S_FAMILY"));
}
In this code, it replaces my reference by 78 and does not naturaly return the good result.
I've searched for an escape char but did not found.
Try sending the String as parameter on the query. Doing this requires to change the Statement into PreparedStatement:
String query = "SELECT * FROM WAREHOUSE WHERE REF LIKE(?)" ;
PreparedStatement pstatement = con.prepareStatement(query,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
pstatement.setString(1, "96-18");
ResultSet rs = pstatement.executeQuery();
Note: you should send "96-18" as value of a String variable, do not hard code it.
You can try
SELECT * FROM WAREHOUSE WHERE REF LIKE('96\-18') ESCAPE '\'
Hope it helps
Example query:
SELECT country
FROM data
WHERE city LIKE
(SELECT LEFT ('jakartada',7));
Example in JDBC:
String sql = " SELECT country FROM data WHERE city LIKE (SELECT LEFT ('?',7)) ";
PreparedStatement ps = koneksi.prepareStatement(sql);
ps.setString(1, city );
ResultSet rs = ps.executeQuery();
Why this doesn't work properly?
There is no parameter within the prepared statement, however the code attempts to set a parameter. Try adding a parameter to the statement.
String sql = " SELECT country FROM data WHERE city LIKE (SELECT LEFT (?,7)) ";
PreparedStatement ps = koneksi.prepareStatement(sql);
ps.setString(1, city );
ResultSet rs = ps.executeQuery();
Or try removing the statement setting the parameter:
String sql = " SELECT country FROM data WHERE city LIKE (SELECT LEFT ('jakartada',7)) ";
PreparedStatement ps = koneksi.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
I believe you're making this harder than it needs to be, and at the same time you're missing something. Is this what you're trying to do?
SELECT country FROM data WHERE city LIKE 'jakarta%'
That is, are you looking for the country column from every row where the city name starts with 'jakarta'? If so, don't forget the % sign. If you don't include the % sign, then
SELECT country FROM data WHERE city LIKE 'jakarta'
and
SELECT country FROM data WHERE city = 'jakarta'
mean exactly the same thing as each other, and the LIKE operator is pointless; you may as well use the = operator.
So, it seems to me the MySQL query you want is
SELECT country FROM data WHERE city LIKE CONCAT(LEFT('jakartada',7),'%')
to add the % sign. You don't need the subselect in this case.
Like you pointed out, the Java code you need then is:
String sql = "SELECT country FROM data " .
"WHERE city LIKE CONCAT(LEFT(?,7),'%')";
PreparedStatement ps = koneksi.prepareStatement(sql);
ps.setString(1, city );
ResultSet rs = ps.executeQuery();
... process the rs records ...
rs.close(); /* please don't forget to close your result sets */
use this link for your solution and this query
http://sqlfiddle.com/#!2/c79ab/10
SELECT country FROM data
WHERE city LIKE CONCAT(LEFT('jakartada',7),'%')
Don't you quotes in your prepared statement when setting values at runtime... Otherwise it will take it as input only not for ps position... Remove single quotes from your question mark...
I am trying to use a SQL Select statement for a query in Java. I currently have the following:
ResultSet rs = stmt.executeQuery("SELECT *" +
" FROM " + table +
" WHERE " + selection +
" VALUES " + selectionArgs);
where "selection" is a string and "selectionArgs" is a string array.
String selection = "documentFK=?";
String[] selectionArgs = { ... };
Is it possible to use the VALUES command to replace the ? like in with the INSERT command? Either way, what would be the correct syntax?
Thanks for the help.
I believe what you're looking for is the IN statement. Your query should look like this:
SELECT *
FROM table
WHERE documentFK IN ('doc1', 'doc2', 'doc3')
AND userFK IN ('user1', 'user2', 'user3')
This is (obviously) going to make your code a bit more ugly. You'll have to ensure that the WHERE keyword is used for the first clause, but the AND keyword is used for every other clause. Also, each list will have to be comma-delimited.
no, that is not the way it's done. first you create the statement from the query, using the question marks as place holders for the real values you want to put there. then you bind these values to the statement.
//the query
String sql = "SELECT " + "*" +
" FROM " + table +
" WHERE documetFK = ?";
//create the statement
PreparedStatement stmt = connection.prepareStatement(sql);
//bind the value
stmt.setInt(1, 4); //1 is "the first question mark", 4 is some fk
//execute the query and get the result set back
ResultSet rs = stmt.executeQuery();
now, if you want this thing with selection string and some args, then you're going to have a loop in your java code. not sure what your array looks like (you're not giving me that much to go on), but if it's made up from strings, it would be something like this:
//the query
String sql = "SELECT " + "*" +
" FROM " + table +
" WHERE " + selection;
//create the statement
PreparedStatement stmt = connection.prepareStatement(sql);
//bind the values
for(int i = 0; i < selectionArgs.length; i++) {
stmt.setString(i, selectionArgs[i]); //i is "the nth question mark"
}
//execute the query and get the result set back
ResultSet rs = stmt.executeQuery();
Can you use a PreparedStatement?
First of all SELECT .. WHERE .. VALUES is incorrect SQL syntax. Lose the VALUES part.
Then you're looking for prepared statements.
In your example it's going to look something like this:
String sql = "SELECT * FROM myTable WHERE documentFK=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "myDocumentFK"); // parameters start from 1, not 0. also we're assuming the parameter type is String;
ResultSet rs = pstmt.executeQuery();
Or with multiple parameters:
String sql = "SELECT * FROM myTable WHERE documentFK=? AND indexTerm=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "myDocumentFK"); // parameters start from 1, not 0. also we're assuming the parameter type is String;
pstsm.setInt(2, 100); // assume indexTerm can be 100 and is an integer
ResultSet rs = pstmt.executeQuery();
However, all of this doesn't worth your while since you can simply do the same by concatenating the value into the statement. But be aware of the SQL injections, so don't forget to escape the parameters that you're passing into the database.
PS: I was typing this way too long. You already have the answers :-)
As a side note, you may want to take a look at this to prevent SQL injections:
https://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java
Sormula can select using "IN" operator from a java.util.Collection of arbitrary size. You write no SQL. It builds the SQL SELECT query with correct number of "?" parameters. See example 4.
G'day!
I have one million different words which I'd like to query for in a table with 15 million rows. The result of synonyms together with the word is getting processed after each query.
table looks like this:
synonym word
---------------------
ancient old
anile old
centenarian old
darkened old
distant far
remote far
calm gentle
quite gentle
This is how it is done in Java currently:
....
PreparedStatement stmt;
ResultSet wordList;
ResultSet syns;
...
stmt = conn.prepareStatement("select distinct word from table");
wordList = stmt.executeQuery();
while (wordList.next()) {
stmt = conn.prepareStatement("select synonym from table where word=?");
stmt.setString(1, wordList.getString(1));
syns = stmt.executeQuery();
process(syns, wordList.getString(1));
}
...
This is incredible slow. What's the fastest way to do stuff like this?
Cheers,
Chris
Ensure that there is an index on the 'word' column.
Move the second prepareStatement outside the word loop. Each time you create a new statement, the database compiles and optimizes the query - but in this case the query is the same, so this is unnecessary.
Combine the statements as sblundy above has done.
Two ideas:
a) How about making it one query:
select synonym from table where word in (select distinct word from table)
b) Or, if you process method needs to deal with them as a set of synonyms of one word, why not sort them by word and start process anew each time word is different? That query would be:
select word, synonym
from table
order by word
Why are you querying the synonyms inside the loop if you're querying all of them anyway? You should use a single select word, synonym from table order by word, and then split by words in the Java code.
PreparedStatement stmt;
ResultSet syns;
...
stmt = conn.prepareStatement("select distinct " +
" sy.synonm " +
"from " +
" table sy " +
" table wd " +
"where sy.word = wd.word");
syns = stmt.executeQuery();
process(syns);
related but unrelated:
while (wordList.next()) {
stmt = conn.prepareStatement("select synonym from table where word=?");
stmt.setString(1, wordList.getString(1));
syns = stmt.executeQuery();
process(syns, wordList.getString(1));
}
You should move that preparestatement call outside the loop:
stmt = conn.prepareStatement("select synonym from table where word=?");
while (wordList.next()) {
stmt.setString(1, wordList.getString(1));
syns = stmt.executeQuery();
process(syns, wordList.getString(1));
}
The whole point of preparing a statement is for the db to compile/cache/etc because you're going to use the statement repeatedly. You also may need to clean up your result sets explicitly if you're going to do that many queries, to ensure that you don't run out of cursors.
You should also consider utilizing the statement object's setFetchSize method to reduce the context switches between your application and the database. If you know you are going to process a million records, you should use setFetchSize(someRelativelyHighNumberLike1000). This tells java to grab up to 1000 records each time it needs more from Oracle [instead of grabbing them one at a time, which is a worst-case-scenario for this kind of batch processing operation]. This will improve the speed of your program. You should also consider refactoring and doing batch processing of your word/synonyms, as
fetch 1
process 1
repeat
is slower than
fetch 50/100/1000
process 50/100/1000
repeat
just hold the 50/100/1000 [or however many you retrieve at once] in some array structure until you process them.
The problem is solved. The important point is, that the table can be sorted by word. Therefore, I can easily iterate through the whole table. Like this:
....
Statement stmt;
ResultSet rs;
String currentWord;
HashSet<String> syns = new HashSet<String>();
...
stmt = conn.createStatement();
rs = stmt.executeQuery(select word, synonym from table order by word);
rs.next();
currentWord = rs.getString(1);
syns.add(rs.getString(2));
while (rs.next()) {
if (rs.getString(1) != currentWord) {
process(syns, currentWord);
syns.clear();
currentWord = rs.getString(1);
}
syns.add(rs.getString(2));
}
...