SELECT query not passing parameters - mysql

I have an select query with inner join, and the where clause is in the second Query,
Here is the code :
static String Showplan = "SELECT * From plan_audit INNER JOIN (SELECT Du,Au From Programme_audit Where Du = '?' AND Au = '?')AS T ";
public void buttonClick(ClickEvent event) {
try{
Class.forName("com.mysql.jdbc.Driver");
Core.con = DriverManager.getConnection(Core.db,Core.dbUsername,Core.dbPassword);
PreparedStatement st;
st = Core.con.prepareStatement(Core.Showplan);
st.setString(1,select.getValue().toString());
st.setString(2,select1.getValue().toString());
ResultSet rs = st.executeQuery();
while(rs.next()){
table.addItem(new Object[]{rs.getInt(1),rs.getString(2),rs.getDate(3),rs.getString(4), rs.getString(5),rs.getString(6),rs.getString(7),rs.getString(8),rs.getDate(9),rs.getString(10),rs.getString(11),rs.getDate(12),rs.getString(13),rs.getString(14),rs.getString(15)},rs.getInt(1));
}
}catch(Exception e){
e.printStackTrace();
}
}
});
and the exception being raised is the following:
java.sql.SQLException: Parameter index out of range (1 > number of
parameters, which is 0).

Don't put single quotes after the parameter markers ?. In fact, don't do anything to them, rather let Java insert the data as it sees fit:
String sql = "SELECT * From plan_audit INNER JOIN ";
sql += "(SELECT Du, Au From Programme_audit Where Du = ? AND Au = ?) t ";
PreparedStatement st = con.prepareStatement(sql);
st.setString(1, select.getValue().toString());
st.setString(2, select1.getValue().toString());
ResultSet rs = st.executeQuery();
The whole point of prepared statements is to let Java worry about how to bring your data into the query. In this case, since you are binding strings, they would be surrounded by single quotes, but you do not need to be concerned with this.
As a side note, your query is actually doing a cross join, since you never specify a join condition. This may or may not be what you intend, but most likely you want to have some kind of join condition here.

Have you tried the parameter indexes 0 and 1 instead of 1 and 2?
st.setString(0,select.getValue().toString());
st.setString(1,select1.getValue().toString());
The single quotes are correct.

Related

issue with checking already existing values in table

I want to check of the values in my 3 textfield already exist in my table before proceeding further in my statement but it does not work in eclipse but work in heidisql? prepareStatement and resultset are properlt initislise at the top.
I already try using ? and preStatement.setString(1, get_status_update) but it gave me the same error result.
String get_status_update = stats_status_txta.getText();
String get_username= friend_username_txtf.getText();
String get_friendname= friend_list_txta.getText();
DB_connection db_connection = new DB_connection();
try{
if(get_username.length() < 3) {
JOptionPane.showMessageDialog(statusPanel,"You need to insert a username here","Post Lodge Status Error", JOptionPane.INFORMATION_MESSAGE);
} else if (get_status_update.length() < 3) {
JOptionPane.showMessageDialog(statusPanel,"Please insert the status update you wish to like","Post Lodge Status Error", JOptionPane.INFORMATION_MESSAGE);
} else {
String sql = " SELECT sut.status_update_id, up.user_id , fd.friend_id "
+ "FROM tb_logde_status_update as tsu "
+ "INNER JOIN status_update_tb as sut ON sut.status_update_id = tsu.status_update_id "
+ "INNER JOIN user_profile as up ON tsu.user_id = up.user_id "
+ "INNER JOIN friend_details as fd ON tsu.friend_id = fd.friend_id "
+ "WHERE sut.status_update_msg='"+get_status_update+"' AND up.username='"+get_username+"' AND fd.friend_username='"+get_friendname+"' ";
preStatement = db_connection.connect().prepareStatement(sql);
res = preStatement.executeQuery();
boolean send_logde_status = false;
while (res.next()) {
if(res.getString("status_update_msg").equalsIgnoreCase(get_status_update)
&& res.getString("username").equalsIgnoreCase(get_username)
&& res.getString("friend_username").equalsIgnoreCase(get_friendname)) {
JOptionPane.showMessageDialog(statusPanel, "Status update has already been like by you, choose another one!");
send_logde_status = true;
break; // Get out of the loop. No more need for it.
// Maybe the error is around here?
}
} ...
When I use the query directly from the database query it work!
SELECT sut.status_update_id, up.user_id , fd.friend_id
FROM tb_logde_status_update as tsu
INNER JOIN status_update_tb as sut ON sut.status_update_id = tsu.status_update_id
INNER JOIN user_profile as up ON tsu.user_id = up.user_id
INNER JOIN friend_details as fd ON tsu.friend_id = fd.friend_id
WHERE sut.status_update_msg="not hallo world" AND up.username="username" AND fd.friend_username="paul";
I am inserting the exactly values from my 3 textfields. I am getting the status_update_id, user_id, friend_id when i use the query from the database but not in my action listener button
Error: Column 'status_update_msg' not found.
Maybe the parameters are not exactly the same as the ones passed in the direct query, I would suggest the following:
Log the parameters values in console
Try using trim() and/or toLowerCase() if parameter values need to be in lower case only
Also, using setXXX() methods for preparedStatement is better approach than appending parameter values to a String query.

MySQL to HQL query

How should I convert this MySQL query to HQL to retrieve some data I need?
SELECT pu.url, count(sen.content)
FROM Sentence sen JOIN ProcessedUrl pu
ON sen.PROCESSED_URL_ID=pu.url_id
GROUP BY pu.url ORDER BY 2;
In my code there is POJO ProcessedUrl which have id/url/date/set(of Sentence) fields mapped. I wanted to do something like:
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
List<ProcessedUrl> result = session.createQuery("proper HQL query", ProcessedUrl.class).getResultList();
transaction.commit();
session.close();
return result;
and then iterate over this result to print result.getUrl() & result.getSentences().size() for each url.
I know my query should return fields which are inside ProcessedUrl then how I can return some grouped query and retrieve data from it that is not kept directly inside the table? Like this count() for every url?
Thanks for help.
I have found out right HQL query so no need help anymore.
List<Object[]> result = session.createQuery("select pu.url, count(sen.content)"
+ " FROM ProcessedUrl pu"
+ " JOIN pu.sentences sen "
+ " GROUP BY pu.url "
+ " ORDER BY 2", Object[].class).getResultList();

How to Select records with over 4 criteria

Select records based on the criteria shown
Is there any way i can select records from MySQL based on this criteria apart using the many if else statements.
Actually what i have in mind is below
if CurrentLevel.SelectedItem <> Nothing AND Programme.SelectedItem = Nothing AND Gender.SelectedItem = Nothing Then
myconnection.Open()
Dim SelCmd as SqlCommand = New SqlCommand("Select * From StudentsList Where CurrentLevel = '"& CurrentLevel.SelectedItem &"'",myconnection)
And I'll have to do it for all the possible outcomes.
Which makes the code very lengthy and tiresome to write.
Is there a shorter way of performing this search because I'll perform another search with almost 16 criteria.
The question is not entirely clear to me. You won't need a new if statement for all the criteria. You can achieve this by modifying the SQL query itself. One of the main purpose of SQL is to get data that match certain criteria.
SELECT * FROM StudentsList WHERE `CurrentLevel` = "level" AND `gender` = "male" AND `programme` = "something"
The above SQL query should give you a basic idea. It will select the rows which have CurrentLevel as level, gender as male and programme as something only, the rest will be ignored.
EDIT:
I don't know VB. Here is a quick, dirty example in C# which will help you understand the basic logic behind this.
string sqlQuery = "SELECT * FROM StudentsList ";
if(currentLevelDropDown.SelectedItem.Text != "")
{
sqlQuery + "WHERE CurrentLevel = " + currentLevelDropDown.SelectedItem.Text;
}
if(ProgrammeDropDown.SelectedItem.Text != "")
{
sqlQuery + " AND WHERE programme = " + ProgrammeDropDown.SelectedItem.Text;
}
//Final Query becomes: SELECT * FROM StudentsList WHERE CurrentLevel = userSelectedOption AND WHERE programme = userSelectedProgrammeOption
//Finally execute the sqlQuery

mysql parameterized query in ASP.NET

i am working on parameterized queries but i am not getting proper query in result
here is my code
public MySqlCommand Get_Login(string clinetID, string loginID, string password, string branchID)
{
MySqlCommand objCommand = new MySqlCommand(this.Query);
objCommand.Parameters.AddWithValue("#ClientID", clinetID);
objCommand.Parameters.AddWithValue("#LoginID", loginID);
objCommand.Parameters.AddWithValue("#Password", password);
objCommand.Parameters.AddWithValue("#BranchID", branchID);
objCommand.CommandType = CommandType.Text;
return objCommand;
}
and when debugging this is what i am getting in "objCommand"
Select u.groupid,p.PersonId, p.designationid,concat(p.salutation,p.FName,'
',p.MName,' ',p.LName) as PersonName,tb.Type
BrType,p.OrgId,p.subdepartmentid,ifnull(crossdept,'N') as
crossdept,p.departmentid,u.defaultpage,p.orgid,ifnull(p.crosslab,'N') as crosslab,
(select indoor_services from dc_Tp_organization where orgid='#ClientID') as
indoor_services,(select name from dc_Tp_organization where orgid='#ClientID') as
orgname,
(select default_route from dc_Tp_organization where orgid='#ClientID') as
default_route,p.BranchID BranchID,tb.Name BRName from dc_tp_personnel p left outer
join
dc_tu_userright u on u.personid=p.personid left outer join dc_tp_branch tb on
tb.BranchID=p.BranchID Where p.Active='Y' and p.LoginId = '#LoginID' and p.Pasword
='#Password' and p.BranchID='#BranchID'
i am not getting values in parameters
Here is the Query
objdbhims.Query = "Select u.groupid,p.PersonId,
p.designationid,concat(p.salutation,p.FName,' ',p.MName,' ',p.LName) as
PersonName,tb.Type BrType,p.OrgId,p.subdepartmentid,ifnull(crossdept,'N') as
crossdept,p.departmentid,u.defaultpage,p.orgid,ifnull(p.crosslab,'N') as crosslab,
(select indoor_services from dc_Tp_organization where orgid=#ClientID) as
indoor_services,(select name from dc_Tp_organization where orgid=#ClientID) as
orgname,(select default_route from dc_Tp_organization where orgid=#ClientID) as
default_route,p.BranchID BranchID,tb.Name BRName from dc_tp_personnel p left outer
join dc_tu_userright u on u.personid=p.personid left outer join dc_tp_branch tb on
tb.BranchID=p.BranchID Where p.Active='Y' and p.LoginId = #LoginID and p.Pasword
=#Password and p.BranchID=#BranchID";
Secret Squirrel was correct on using the "?" for parameterized variables. MySQL uses "#" for inline sql variables for queries and thus expecting them to be declared such as from a script or part of an inline (select subquery) declaration.
You need to change BOTH instances of the parameters... both in the query, and as the command.Parameters.Add... instances.
Also, I noticed, and not sure if its it or not, but in your WHERE clause you have "pasword" (only one 's') vs password (two 's') Don't know if intentional or not.
One LAST thing that MAY help. Since some of the parameters match the column names, I would suggest changing the parameters SLIGHTLY by just adding something like "x" to FORCE differentiation between the column name and the actual parameters...
where... p.LoginID = ?xLoginID ...
and in the command parameters
objCommand.Parameters.AddWithValue("?xLoginID", loginID);
The problem is because the parameters were wrap with single quotes converting them into string literals.
To make it work, remove the single quotes around them. eg.
Where p.Active = 'Y'
and p.LoginId = #LoginID
and p.Pasword = #Password
and p.BranchID = #BranchID

PreparedStatement: Can I supply the column name as parameter?

Let's say I have a table with 3 columns: C1, C2, C3
I make a search based on the C1 column.
Could I make something similar like this (this is not working - because this is not the way prepareStatement it's used:) )
String c;// the name of the column
...
String sql = "select * from table where ? = ?";
pre = con.prepareStatement(sql);
pre.setString(1, c);
pre.setString(1, i);
rs = pre.executeQuery();
The main idea, I don't want to have 3 ifs for every column. An elegant solution?
This won't work. The prepare statement parses the SQL, sends to the database for validation and compilation. If question marks could substitute parts of the SQL, you would loose the whole point of bound variables - speed and security. You would reintroduce SQL injection back and statements will have to be recompiled for all parameters.
Wouldn't something like SELECT * FROM table WHERE c1 = ? OR c2 = ? OR c3 = ? be better (of course depending on indexes and table sizes).
you could code up a a set of sql queries and store them in a map, then grab one based on the column in question.
enum column { a, b, c}
Map<column, string> str;
static {
str.put(a, "select * from tbl where a = ? ");
...
}
then just grab one out of the map later based on the enum. String appends in sql statements have a way of becoming security problems in the future.
Use a dynamic query and a java.sql.Statement:
String whereClause = c + " = " + i;
// Form the dynamic Query
StringBuffer query = new StringBuffer( "SELECT * FROM TABLE" );
// Add WHERE clause if any
query.append(" WHERE " + whereClause);
// Create a SQL statement context to execute the Query
Statement stmt = con.createStatement();
// Execute the formed query and obtain the ResultSet
ResultSet resultSet = stmt.executeQuery(query.toString());
can't you do this:
String c;// the name of the column
...
String sql = "select * from table where " + c + " = ?";
pre = con.prepareStatement(sql);
pre.setString(1, i);
rs = pre.executeQuery();
?
If not then this might be a solution:
String c;// the name of the column
...
String sql = "select * from table where ('C1' = ? AND C1 = ?)
OR ('C2' = ? AND C2 = ?)
OR ('C3' = ? AND C3 = ?)"
pre = con.prepareStatement(sql);
pre.setString(1, c);
pre.setString(2, i);
pre.setString(3, c);
pre.setString(4, i);
pre.setString(5, c);
pre.setString(6, i);
rs = pre.executeQuery();