JPA Query for toggling a boolean in a UPDATE - sql

SQL version works okay and I can toggle the boolean called bar ...
mysql> update Foo set bar = ! bar WHERE id IN (1, 7, 13);
Query OK, 3 rows affected (0.02 sec)
Is there a easy JPA Query equivalent, I tried
final Set<Integer> ids;
final Query query = em.createQuery("UPDATE " + Foo.class.getName()
+ " a set bar= !bar"
+ " where a.id in :ids");
query.setParameter("ids", ids);
query.executeUpdate();
The above gives a org.hibernate.QueryException.
In my entity :
#Column(columnDefinition = "INTEGER", nullable = false)
private boolean bar;
Any ideas on the JPA syntax ?

That can be done with the case expression:
UPDATE FOO a
SET a.bar =
CASE a.bar
WHEN TRUE THEN FALSE
ELSE TRUE END
WHERE a.id in :ids
For nullable Boolean bit more is needed:
UPDATE FOO a
SET a.bar =
CASE a.bar
WHEN TRUE THEN FALSE
WHEN FALSE THEN TRUE
ELSE a.bar END
WHERE a.id in :ids

Related

IF Column has a value

I need to write sql query to check whether the column y in a table x has a value. In python I can check that like
object.y = 1
if object.y:
<statements>
Like this I need to check in Postgres
this is my query:
request.cr.execute(""" select * from x where parent_id = %s and nav_include = true and website_published = true and cms_lang = NULL and y is TRUE order by sequence""",([event_root]))
Here I need to check y has a value.
try this
request.cr.execute(""" select * from x where parent_id = %s and nav_include = true and website_published = true and cms_lang = NULL and coalesce(y, FALSE) is TRUE order by sequence""",([event_root]))
This is my solved answer
request.cr.execute(""" select * from x where parent_id = %s and nav_include = true and website_published = true and cms_lang is NULL and y is not null order by sequence""",([event_root]))
reference: https://www.techonthenet.com/postgresql/is_not_null.php

Return True if specific value exists in table - sql

I want to create an SQL query that will return True if a specific value exists in a specific column; if not, then it will return False.
I know that I can create something like 'SELECT something FROM somewhere WHERE something'. In this case I don't want to select anything, just to check.
My question is how can I do it.
You can use the IIf function:
SELECT IIf(something = 'Some value', True, False) FROM somewhere;
In Access, you can use a DCount expression to count the number of rows where your something field contains 'some value'. Here is an example copied from the Immediate window:
Debug.Print DCount("*", "somewhere", "something='some value'")
1
Debug.Print DCount("*", "somewhere", "something='BOGUS'")
0
You could adapt that to give you True when the count is greater than zero or False for count of zero:
Debug.Print (DCount("*", "somewhere", "something='some value'") > 0)
True
Debug.Print (DCount("*", "somewhere", "something='BOGUS'") > 0)
False
If you want to do it from a query, this one will return -1 for True and zero for False:
SELECT (DCount("*", "somewhere", "something='some value'") > 0) AS value_exists;
Or you could use a Format expression to display those values as strings: "True"; or "False":
SELECT Format(DCount("*", "somewhere", "something='some value'") > 0, 'True/False') AS value_exists;
As the name implies, DLookup is for this:
SomevalueExists = Not IsNull(DLookup("Id", "somewhere", "somefield = somevalue"))
try this:
select case when x is null then false else true end
from (select max(somecol) x
from sometable
where somecol = somevalue) a
just use
select count(*) from tableName where columnName = '$variableInput';
if you plan on reusing this you might as well make it a prepared statement that you can call upon through whichever interface you design to work with your database. If the returned value is greater than zero you know it to be true, for instance
if(preparedStatement($variableInput)>0)
{
$flag = true;
}
else
{
$flag = false;
}

Optional conditions in postgreSQL query

I need to create a procedure with optional arguments and use them only if they are not null
My current query looks like:
SELECT * FROM sth WHERE
(arg1 IS NULL OR sth.c1 = arg1) AND
(arg2 IS NULL OR sth.c2 = arg2) AND
(arg3 IS NULL OR sth.c3 > arg3) AND
(arg4 IS NULL OR sth.c4 < arg4)
I'm thinking of a way to make it look better / shorter. My first shot is:
SELECT * FROM sth WHERE
COALESCE(sth.c1 = arg1, 't') AND
COALESCE(sth.c2 = arg2, 't') AND
COALESCE(sth.c3 > arg3, 't') AND
COALESCE(sth.c4 < arg4, 't');
but I'm not sure if this looks any better. Do you know any useful tricks for this?
Keep it the way it is. Using coalesce will prevent the query planner from doing its job properly, and you'll end up with sucky query plans.
Best I'm aware, the following expressions will use a btree index:
col = 'val'
col is null
The following expressions will not use a btree index:
col is [not] 'val'
(col = 'val') is [not] <true | false | null>
col is [not] distinct from 'val'
coalesce(col, 'val') = 'val'
coalesce(col = 'val', <true | false | null>)
Ok, I think that this query is the best idea for this purpose
SELECT * FROM sth WHERE
NOT (sth.c1 = arg1) IS FALSE AND
NOT (sth.c2 = arg2) IS FALSE AND
NOT (sth.c3 > arg3) IS FALSE AND
NOT (sth.c4 < arg4) IS FALSE;
it doesn't use any functions so the query planner should work fine just as before
it just uses simple expressions where:
1.
true = true // true
true = false // false
true = null // null
2.
false is false // true
true is false // false
null is false // false
3.
not true // false
not false // true
so it will return true if expression is true OR null

SQL query to update list of records by looping through a table records and check some logic?

I do not want to use cursors for performance reasons.
Input Parameters for stored procedure: arg1, arg2,arg3 & arg4
For example:
Table A > A1 Column and A2 Column,
Table B > B1 Column (A.A1 <=>B.B1) foreign n primary key relation and B2 Column.
I want to update A.A2 value based on the following if condition,
if(arg1 == B.B2 && arg2 == B.B2)
{
Update A set A.A2 = 1 where A.A1 = arg4
}
else{
if(arg1 == 1 && arg3 == B.B2){
Update A set A.A2 = 0 where A.A1 = arg4
}
}
this is simple for one record but the Table A has 1000's records that match A.A1 = arg4 so i have to apply the above logic or case for all records and want to avoid using cursors...how do i do it?
Try the below query.
UPDATE tmp
SET tmp.A2 =
(CASE WHEN (tmp1.B2 == arg1 && tmp1.B2 == arg2) THEN 1 WHEN (arg1 == 1 && tmp1.B2 == arg3) THEN 0 ELSE tmp.A2)
FROM
A tmp
INNER JOIN
B tmp1
ON tmp.A1 = tmp1.B1
WHERE
tmp.A1 = arg4
Hope this Helps!!
In general, non-specific SQL-92 you could do this:
UPDATE A
SET A.A2 = CASE WHEN B.B2 IN (#Arg1,#Arg2) THEN 1
WHEN #arg1 = 1 AND B.B2 = #arg3 THEN 0 END
FROM A
JOIN B ON A.A1=B.B1
WHERE A.A1 = #arg4
You may need an ELSE before END if you don't want any values falling through (without the ELSE it would set A.A2 to NULL).

Conditional operator in Transact-sql

Is there a way to do this shorter, for instance using some sort of conditional operator in Transact-sql?
IF #ParentBinaryAssetStructureId = -1
BEGIN
SET #ParentBinaryAssetStructureId = NULL
END
UPDATE BinaryAssets.BinaryAssetStructures
SET ParentBinaryAssetStructureId = #ParentBinaryAssetStructureId
WHERE BinaryAssetStructureId = #OriginalBinaryAssetStructureId
USE NULLIF()
UPDATE BinaryAssets.BinaryAssetStructures
SET ParentBinaryAssetStructureId = NULLIF(#ParentBinaryAssetStructureId,-1)
WHERE BinaryAssetStructureId = #OriginalBinaryAssetStructureId
The ternary (conditional) operator in c like languages:
x = doSomething ? 5 : 7
would be written like this in SQL:
SELECT #x = CASE WHEN #doSomething = 1 THEN 5 ELSE 0 END
There can be multiple cases (when clauses):
SELECT #x = CASE WHEN #doSomething = 1 THEN 5 WHEN #somethingElse = 1 THEN 20 ELSE 0 END
UPDATE BinaryAssets.BinaryAssetStructures
SET ParentBinaryAssetStructureId =
CASE ParentBinaryAssetStructureId
WHEN -1 THEN NULL
ELSE ParentBinaryAssetStructureId
END
WHERE BinaryAssetStructureId = #OriginalBinaryAssetStructureId
Give that a whirl