I insert some values into a database using a PreparedStatement, but it seems, that i cannot retrieve the last insert id in that case.
I try to use the same statement as i use for Statements (below) but it doent work. It says, that .executeQuery() cannot take arguments in this case.
In fact, i don't exactly need the last insert id, the number of affected rows will do, but how do i get that? I thought PreparedStatement's .executeUpdate() method would return the number of affected rows, but it apparently it does not.
Here is the method.
public static int getLastInsertId(Statement stmt) throws SQLException {
String sql = "SELECT SCOPE_IDENTITY() AS id";
ResultSet rs = stmt.executeQuery(sql);
int id = 0;
while (rs.next()) {
id = rs.getInt("id");
}
return id;
}
Thank you in advance.
A PreparedStatement's executeUpdate method DOES indeed return the number of affected rows...
Related
I have a java method like this one below:
public String qE (String query, String selector) throws QSLException, IOException{
//I get my sqlQuery from properties
String sqlQuery = properties.getPRoperty(query);
//sqlQuery = SELECT count(?) FROM employees WHERE ? is not null
PreparedStatement ps = conn.preparedStatement(sqlQuery);
ps.setFetchSize(100);
ps.setString(1,selector);
ps.setString(2,selector);
ResultSet rs = ps.executeQuery();
String rs = "";
while(rs.next()){
queryValue = rs.getString(1);
}
return queryValue;
}
When I run it with parameters
qe(employees, second_name)
then this query should be executed:
SELECT count(second_name)
FROM employees
WHERE second_name is not null
The problem is that non of employees has second name and I should get 0 and the whole method should return 0 but I always get diffrent number greater than zero.
Can anyone tell me why this doesn't return 0 but always diffrent number like i.e. 2399?
A ? represents a value not an object name, so it is equivalent to using
SELECT count('second_name')
FROM employees
WHERE 'second_name' is not null
Which is always true and is always counted. In other words, your query counts all rows in table employees.
You cannot use parameters to parameterize object names. If you really need to do this dynamically, you will need to construct the query dynamically (by concatenating the name in the query string). Just be sure to guard yourself against SQL injection if you do that (eg by checking the name against a white list or comparing explicitly to the database metadata).
I want to get some informations in my SQL base, but i don't know how to. I have already used this following code :
String pseudo = null;
String query = "select * from UsersInfos where Pseudo=?"
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, pseudo);
ResultSet rs = statement.executeQuery();
while (rs.next()) {
pseudo = rs.getString("Pseudo");
}
System.out.println(pseudo);
But it returns me null of
System.out.println(pseudo);
I want to get some informations, not set them, well can some one helps me please ?
Your result set is coming back empty. In other words, the assignment pseudo = rs.getString("Pseudo") never took place.
The reason the result set is empty (i.e. contains no records) is due to the WHERE clause:
select * from UsersInfos where Pseudo=null
The comparison of any value in the Pseudo column to null will be either null or false (depending on your particular RDBMS). This means that no records will match.
I am trying to update a MSSQL instance using JDBC using a prepared statement, I made a method to update any record in the table when given the column name, the value to update, and the updated value.
public void updateProjectOptions(int projectID, int number, String column){
try {
PreparedStatement ps = conn.prepareStatement("UPDATE cryptic.dbo.projects SET ? = ? WHERE project_id = ?");
int newNum = number+1;
System.out.println(projectID+" "+newNum+" "+column);
ps.setString(1, column);
ps.setInt(2, newNum);
ps.setInt(3, projectID);
int debug = ps.executeUpdate();
System.out.println("Rows affected: "+debug);
} catch (SQLException ex) {
Logger.getLogger(DAL.class.getName()).log(Level.SEVERE, null, ex);
}
}
The first print statement is printing out the correct values so I know the inputs are correct, and the second print statement is letting me know that 1 row is affected which is correct.
If I run the script inside of Management Studio the script runs fine and updates the table, but if I run the script from the java project nothing is updated and no errors are generated.
The db table in question has 4 columns: (int)project_id, (nvarchar)project_name, (int)num_bugs, (int)num_features
Can anyone help me out with getting this to work and/or spot whats wrong?
You can't bind a column name that way, only variables.
I would recommend that you close that PreparedStatement in method scope in a finally block. Your way is asking for trouble.
I would also call writing to System.out a very bad idea. I'd prefer returning the number of affected rows to the user.
Column names cannot be parameterized in prepared statements. You can parameterize only literal values like strings or numbers.
I have a stored procedure, I want to call it from JDBC, I got null pointer exception in the line"
while (restuls.next()) {
My code is:
Connection con = Database.getConnection();
CallableStatement callableStatement = null;
try {
String storedProcedure = "{call getAllCustomerAddresses(?,?,?,?,?,?,?)}";
callableStatement = con.prepareCall(storedProcedure);
callableStatement.setInt(1, this.getID());
callableStatement.registerOutParameter(2,
java.sql.Types.INTEGER);
callableStatement.registerOutParameter(3,
java.sql.Types.VARCHAR);
callableStatement.registerOutParameter(4,
java.sql.Types.INTEGER);
callableStatement.registerOutParameter(5,
java.sql.Types.INTEGER);
callableStatement.registerOutParameter(6,
java.sql.Types.INTEGER);
callableStatement.registerOutParameter(7,
java.sql.Types.VARCHAR);
callableStatement.execute();
System.out.println(callableStatement.getInt(2));
System.out.println(callableStatement.getString(3));
System.out.println(callableStatement.getInt(4));
System.out.println(callableStatement.getInt(5));
System.out.println(callableStatement.getInt(6));
System.out.println(callableStatement.getString(7));
ResultSet restuls = callableStatement.getResultSet();
while (restuls.next()) {
int addressID = restuls.getInt(2);
String label = restuls.getString(3);
int regionID = restuls.getInt(4);
int areaID = restuls.getInt(5);
int cityID = restuls.getInt(6);
String description = restuls.getString(7);
this.addresses.add(new CustomerAddressImpl(this, label,
description, RegionImpl.getInstance(regionID),
AreaImpl.getInstance(areaID), CityImpl
.getInstance(cityID), addressID));
}
look at the code, the System.out.println is working , and It is printing the right values from database, so why the results set is null please??
another thing, I must use result set because the stored procedure returns many rows.
I am really confusing why I can print the right values but the result set is null
Thanks in advance
Edit
If you want to give you the stored procedure tell me please
Stored Procedure
ALTER PROCEDURE [dbo].getAllCustomerAddresses(
#customerID INT,
#addressID INT OUTPUT,
#label VARCHAR(200) OUTPUT,
#regionID INT OUTPUT,
#areaID INT OUTPUT,
#cityID INT OUTPUT,
#description TEXT OUTPUT
)
AS
SET NOCOUNT Off;
SELECT #addressID = [ID],
#label = [label],
#regionID = [regionID],
#areaID = [areaID],
#cityID = [cityID],
#description = [description]
FROM Customer_Address
WHERE customerID = #customerID
execute() method of PreparedStatement returns true if result set presents and false otherwise. You do not check the return value of execute(). I think that if you do that you see that it is false.
The reason should be in your stored procedure that IMHO does not return value. So, try to analyze it to understand the problem.
Here are recommendations I can give you:
Use executeQuery() that directly returns ResaultSet instead of execute(). I think this is more convenient.
Avoid using stored procedures that couple your platform independent java code with specific type of database. Try to write all logic in java and use portable SQL statements only.
The last time I saw pure JDBC code was about 10 years ago. There are a lot of tools that help you to avoid writing SQL inside java code. Take a look on JPA, Hibernate, iBatis etc.
Your stored procedure doesn't actually produce a ResultSet because you are using output parameters (not 100% sure, I don't have a SQL Server handy to test).
You may just need to call CallableStatement.getObject(int) or CallableStatement.getObject(String) (or a type specific getter) to get the values instead. If you want to process as a ResultSet, then you should not use the output parameters in your stored procedures, but write the stored procedure as a select without assigning to output parameter. That will create a result set from the stored procedure
Another possibility might by that your stored procedure is first returning one or more update counts before returning the result set. The boolean return value of execute() indicates whether the first result is an update count or a ResultSet. You will need to repeatedly call getMoreResults() and getUpdateCount() to be sure you have processed every result.
Your posted stored procedure contains SET NOCOUNT OFF which signals to SQL Server (or Sybase) that you want update (and I believe select) counts returned as well, you might want to try using SET NOCOUNT ON.
You can also try to process the results of execute() like this to find out if there are indeed multiple update counts etc before the result set:
boolean result = pstmt.execute();
while(true)
if (result) {
ResultSet rs = pstmt.getResultSet();
// Do something with resultset ...
} else {
int updateCount = pstmt.getUpdateCount();
if (updateCount == -1) {
// no more results
break;
}
// Do something with update count ...
}
result = pstmt.getMoreResults();
}
See also Java SQL: Statement.hasResultSet()?
How can I use resultset to get me the minimum, average or maximum value from a mysql database column?
I have a prepared statement sql constant string = Select avg(EntryValues) from Entries;
I know I need to use a resultset.getString(EntryValues) but I dont know how to build the java method that would return the actual average value from that resultset.next() loop thing...
Could you please help me?
Get a statement from your connection
use the statement.executeQuery() method to invoke your query and assign it to your ResultSet, e.g.
ResultSet rs = statement.executeQuery("SELECT AVG(EntryValues) FROM Entries");
Your result is one simple 'row' therefore you can use
if(rs.next()) { // check if a result was returned
String avg = rs.getString(1); // get your result
}
If your result contains multiple rows you'll have to use a while-loop for example to iterate through all the result entries:
while(rs.next()) {
// do your thing
}
Hope this helpes, have Fun!