How to do a count(*) in Hibernate? - mysql

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();
}

Related

Spring Data JPQL How to create a query with dynamic where clause?

I'm creating custom JPQL queries to fetch some data.
I have certain cases where I would like to add a where clause depending on if the parameter value is non null.
For example equivalent sql query:
//If parameter status is not null.
SELECT sum(A.sal) FROM TABLE A WHERE A.STATUS = 'X' GROUP BY A.CURRENCY;
//else
SELECT sum(A.sal) FROM TABLE A GROUP BY A.CURRENCY;
Can someone help me with it.
The two queries:
//If parameter status is not null.
SELECT sum(A.sal) FROM TABLE A WHERE A.STATUS = 'X' GROUP BY A.CURRENCY;
//else
SELECT sum(A.sal) FROM TABLE A GROUP BY A.CURRENCY;
can be compacted to one.
First lets declare a named parameter statusParam. This param can take any value (like 'X' or null from above). So the two queries above can be re-written to:
SELECT sum(A.sal) FROM A WHERE (A.STATUS = :statusParam OR :statusParam is null ) GROUP BY A.CURRENCY;
Come on, JPQL is just normal String :)
You want something like this?
private String generateHql(String status) {
String jpql = "SELECT sum(A.sal) FROM TABLE A ";
if (null != status) {
jpql += "WHERE A.STATUS = " +status ;
}
jpql += " GROUP BY A.CURRENCY "
return jpql;
}

CakePHP Using "Group By" in Virtual Field Not Working

I have the following virtual field on my Page model
function __construct($id = false, $table = null, $ds = null) {
$this->virtualFields['fans'] = 'SELECT COUNT(Favorite.id) FROM favorites AS Favorite WHERE Favorite.page_id = Page.id AND Favorite.status = 0';
parent::__construct($id, $table, $ds);
}
This works as expected and displays the number of users who have added the page to their favorites. The issue is that, during development, some rows have duplicate user_id to page_id pairs so it returns the incorrect number or unique users. I tried adding a group by clause like so
$this->virtualFields['fans'] = 'SELECT COUNT(Favorite.id) FROM favorites AS Favorite WHERE Favorite.page_id = Page.id AND Favorite.status = 0 GROUP BY Favorite.user_id';
But it does not work. I tried debugging the issue but I receive the error message "allowed memory size exhausted". I also tried using SELECT COUNT('Favorite.user_id') and SELECT DISTINCT('Favorite.user_id') neither of which worked either. I believe DISTINCT is further away from the answer as that would return an array (I believe?)
Is this a known CakePHP issue? Am I implementing the group by wrong? Is there another solution to do this other than afterfind?
try this
SELECT COUNT(DISTINCT Favorite.user_id)
like that :
$this->virtualFields['fans'] = 'SELECT COUNT(DISTINCT id) FROM favorites WHERE status = 0';

query result what should i use Count() or Any()

I am checking login of a user by this repository method,
public bool getLoginStatus(string emailId, string password)
{
var query = from r in taxidb.Registrations
where (r.EmailId == emailId && r.Password==password)
select r;
if (query.Count() != 0)
{
return true;
}
return false;
}
I saw in one of the previous questions !query.Any() would be faster... Which should i use? Any suggestion....
The sql generated will be different between the two calls. You can check by setting your context.Log property to Console.Out or something.
Here's what it will be:
SELECT COUNT(*) AS [value]
FROM [dbo].[Registrations] AS [t0]
WHERE [t0].[EmailId] = #p0 and [t0].Password = #p1
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[Registrations] AS [t0]
WHERE [t0].[EmailId] = #p0 and [t0].Password = #p1
) THEN 1
ELSE 0
END) AS [value]
In this case, I doubt it will make any difference because EmailID is probably a unique index so there can only be 1 result. In another case where count can be > 1, Any would be preferable because the second query allows sql server to short circuit the search since it only needs to find one to prove that any exist.
You could express it quite a bit shorter like this:
return taxidb.Registrations.Any(r => r.EmailId == emailId && r.Password==password);

LINQ to SQL - nullable types in where clause

I have a table with a column that has null values... when I try to query for records where that column IS NULL:
THIS WORKS:
var list = from mt in db.MY_TABLE
where mt.PARENT_KEY == null
select new { mt.NAME };
THIS DOES NOT:
int? id = null;
var list = from mt in db.MY_TABLE
where mt.PARENT_KEY == id
select new { mt.NAME };
Why?
after some more googling, I found the answer:
ref #1
ref #2
int? id = null;
var list = from mt in db.MY_TABLE
where object.Equals(mt.PARENT_KEY, id) //use object.Equals for nullable field
select new { mt.NAME };
This LINQ renders to SQL as follows:
((mt.PARENT_KEY IS NULL) AND (#id IS NULL))
OR ((mt.PARENT_KEY IS NOT NULL) AND (#id IS NOT NULL) AND (mt.PARENT_KEY = #id))
One possibility - if mt.PARENT_KEY is of some other type (e.g. long?) then there will be conversions involved.
It would help if you could show the types involved and the query generated in each case.
EDIT: I think I have an idea...
It could be because SQL and C# have different ideas of what equality means when it comes to null. Try this:
where (mt.PARENT_KEY == id) || (mt.PARENT_KEY == null && id == null)
If this is the case then it's a pretty ugly corner case, but I can understand why it's done that way... if the generated SQL is just using
WHERE PARENT_KEY = #value
then that won't work when value is null - it needs:
WHERE (PARENT_KEY = #value) OR (PARENT_KEY IS NULL AND #value IS NULL)
which is what the latter LINQ query should generate.
Out of interest, why are you selecting with
select new { mt.NAME }
instead of just
select mt.NAME
?) Why would you want a sequence of anonymous types instead of a sequence of strings (or whatever type NAME is?
It's definitely a matter of C# and SQL having different notions of how to compare nulls - the question has been addressed here before:
Compare nullable types in Linq to Sql

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;
}