Return value for mySql UPDATE - mysql

I'm working on a springboot app and have this update function in my Mapper class that updates the field groupId if groupId exists in the DB.
#Update("UPDATE user SET groupId = " +
"IF(EXISTS(SELECT * FROM allGroup WHERE groupId = #{groupId}) is true, #{groupId}, groupId) " +
"WHERE email = #{email}")
int updateUserGroup(#Param("groupId") Integer groupId, #Param("email") String email);
This function returns 1 regardless of whether groupId was really updated. Is there a way to tell if that field was changed? Having the function return 0 or something when no changes were made for example. Thank you!

Related

SimpleJDBCCall handle out paramater with resultset

I am using spring jdbc. I want result set with out param. separately i done but together i am not able to do.
CREATE DEFINER=`xxx`#`%` PROCEDURE `client_xxxx`(
IN p_xxxx TINYINT(1) UNSIGNED,
IN p_result SMALLINT(2) UNSIGNED,
OUT p_result BIT ) BEGIN
IF EXISTS(SELECT 1 FROM xxx WHERE xxx = 1 AND xxx = 1) THEN
SELECT ...;
SET p_result = 0;
ELSE
SELECT ...;
SET p_result = 1;
END IF;
END
spring jdbc code
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(dataSource).withProcedureName(sp);
List<Map<String, Object>> list = (List<Map<String, Object>>) jdbcCall.execute(paramsArray).get("#result-set-1");
list get the result set with result set how can i get p_result with that.
I find it in simple way that i miss.
public Map<String, Object> xxx(String sp, Object... paramsArray) {
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(dataSource).withProcedureName(sp);
return jdbcCall.execute(paramsArray);
}
execute() gives two parameters default
i.e.
1) #result-set-1
2) #update-count-1
#result-set-1 result set i.e. select record
and #update-count-1 returns update count. If we want to access result with select statement with out parameter. we just have to declare out parameter. execute() gives all the things in Map<String, Object> type.
So from map we can get all the multiple values that stored procedure returns.
For example my SP like
PROCEDURE xxx(
IN xxxxTINYINT(1) UNSIGNED,
IN xxxSMALLINT(2) UNSIGNED,
OUT p_isconfig BIT
)
BEGIN
SELECT....
SET p_isconfig = 1;
END
So in #result-set-1 i get select result.
and p_isconfig gives me result to. If you have any confusion then you can iterate map and identify that how get return parameters.
Iterator i = map.keySet().iterator();
while ( i.hasNext() ) {
String key = (String) i.next();
String value = params.get( key );
System.out.println("key: " + key + " --- value: " + value) ;
}
This way i found solution after reading many things. If any one have other option for this solution then please share with me.
You can try morejdbc (available in maven central) to call your procedure, it's more laconic and it's type safe:
import static org.morejdbc.SqlTypes.BIGINT;
import static org.morejdbc.NamedJdbcCall.call;
import org.morejdbc.*;
...
private JdbcTemplate jdbcTemplate;
...
Out<Integer> out = Out.of(INTEGER);
jdbcTemplate.execute(call("client_xxxx")
.in("p_xxxx", pValue)
.out("p_result", out));
System.out.println("Result is " + out.get());
For ref_cursor out parameter and Oracle database you can use
Out<List<Record>> out = Out.of(OracleSqlTypes.cursor((rs, idx) -> new Record(rs)));
jdbcTemplate.execute(call("client_xxxx")
.in("p_xxxx", pValue)
.out("p_result", out)); // will auto-close ref-cursor
System.out.println("Got result records: " + out.get());

Select count return 0 mysql JDBC

I'm trying to store messages, so i create 2 tables in mysql with HeidiSql, the first one is msg and the second one is users. I wrote a store procedure to get the number of messages that have as sender the first parameter, as recipient the second parameter and viceversa, i stored this value in id variable. I need the variable to count the messages between 2 people. When i run the application from java, i always get id=0. I can't understand the mistake.
...
sql="call getIdMsg(?,?,?)";
sql2="call addRecord(?,?,?,?)";
try (Connection conn= DriverManager.getConnection(db_url,username,password);
CallableStatement statement = conn.prepareCall(sql);
CallableStatement statement2 = conn.prepareCall(sql2)){
statement.setInt(1,sender);
System.out.println(sender);
statement.setInt(2,recipient);
System.out.println(recipient);
statement.registerOutParameter(3, Types.INTEGER);
statement.execute();
id=statement.getInt(3);
System.out.println("ID is: "+id);
statement2.setInt(1,sender);
statement2.setInt(2,recipient);
statement2.setInt(3,id);
statement2.setString(4,msg);
statement2.execute();
System.out.println("The record is been added");
}
catch (SQLException sqle){sqle.printStackTrace();}
...
This is my sql code:
BEGIN
set #id = ((select count(*) from msg WHERE sender = #thisrecipient and recipient = #thissender)+(SELECT COUNT(*) FROM msg WHERE sender = #thissender and recipient = #thisrecipient));
END
These are my parameters:
thissender INT IN
thisrecipient INT IN
id INT OUT
Could you help me please?

How can I get auto increment values in batch update query (Java,MySQL)?

I am using Spring-Jdbc template(first timer) to create MySql repository. I have tables that use AutoIncrement columns as primary key.
I wonder if there a way to get newly generated Ids (autoInc) with each successful batch create statement?
Any pointers or sample would be a great help.
Thanks
Panks
Use getGeneratedKeys() method from your Statement or PreparedStatement object to identify the new auto generated values. Iterate the returned ResultSet object to get the newly generated key values in the order of batch statements.
This call may throw java.sql.SQLFeatureNotSupportedException if the JDBC driver, that you are using, does not support this method.
Sample code snippet:
String sql_insert =
"insert into my_table ( non_auto_incrmnt_fld_names_,_separated ) " +
" values ( record1 ), ( record2 )"; // append as many as required
...
int rowsAffected = stmtObject.executeUpdate( sql_insert, Statement.RETURN_GENERATED_KEYS );
ResultSet rs = stmtObject.getGeneratedKeys();
//******************************************************
rs.last();
int rows = rs.getRow();
System.out.println( "Generated keys count: " + rows );
int currentRow = 1;
rs.beforeFirst();
//******************************************************/
while( rs.next() ) {
System.out.println( /**/( currentRow++ ) + " = " + /**/rs.getInt( 1 ) );
} // while rs

How to do a count(*) in Hibernate?

How can I count the records in a MySQL table in Hibernate? I tried the following HQL, but it does not work.
SELECT COUNT(*) FROM MEMBERS WHERE `username` =:USERNAME OR `email` =:EMAIL
It is used in the following method:
public boolean checkInfos() {
Session newSession = NewHibernateUtil.getSessionFactory().openSession();
int count = (Integer) newSession.createSQLQuery("SELECT COUNT(*) FROM MEMBERS WHERE `username` ='admin' OR `email` ='admin'").uniqueResult();
if (count >= 1) {
return false;
} else {
return true;
}
}
I guess you need that
Query q = newSession.createSQLQuery("SELECT COUNT(*) FROM MEMBERS WHERE username = ? OR email =?");
q.setParameter( 1, "your username");
q.setParameter(2, "your email");
Select count(*) returns a Long, not an Integer.
One more thing: The backticks, which you are using, are not accepted by every database.
By the way, you can use count(*) also in HQL. This means, you can use createQuery instead of createSQLQuery. An advantage of HQL is, it is portable from one database to another, which is not always the case for SQL statements.
You also can achieve this by using criteria also.
private Number getCount(){
Criteria criteria = session.createCriteria(Members.class);
criteria.add(Restrictions.or(Restrictions.eq("username", "admin"), Restrictions.eq("email","admin")));
criteria.setProjection(Projections.rowCount());
return (Number) criteria.list();
}

How to get the last inserted id in a Linq To Sql custom sql expression?

Here is my problem.
I'd like to get the last inserted Id with a custom sql expression in Linq To Sql.
My insert method:
public int Add(string Label)
{
_dbContext.ExecuteCommand("INSERT INTO Products (Label) VALUES (#Label);", Label);
_dbContext.SubmitChanges();
var lastId = _dbContext.ExecuteQuery<int>("SELECT Scope_Identity() as [Scope_Identity];").ToList()[0];
return lastId;
}
lastId always returns null. When I tried this query (Insert + Select) directly in Sql Server, it works perfectly and returns the last inserted Id.
I don't want to use a procedure and I can't use a new Product object (it is not possible for me to use InsertOnSubmit or whatever).
Can you please help me ?
Thanks.
Ok I've found how to do it:
public int Add(string Label)
{
var query = String.Format("INSERT INTO Products (Label) VALUES (#Label); SELECT ProductId FROM Products WHERE ProductId = Scope_Identity();", Label);
var lastId = _dbContext.ExecuteQuery<int>(query).ToList()[0];
return lastId;
}
Try using:
INSERT INTO Products (Label) OUTPUT inserted.ProductID VALUES (#Label);
Rob
I know that you've already answered but there is anouther way of doing it which I found which was useful for my particular scenerio which involved needing to edit the latest records added to a table without knowing there ids:
public int Add(string Label)
{
var query = String.Format("INSERT INTO Products (Label) VALUES (#Label);", Label);
_dbContext.ExecuteCommand(query);
var lastId = _dbContext.ExecuteQuery<int>("SELECT IDENT_CURRENT('Products ')").First();
return lastId;
}