SQL update to make a toggle - sql

I want to make a toggle request as defined there T-SQL: Using a CASE in an UPDATE statement to update certain columns depending on a condition
I did this :
Update capteur
join smartparking_reference on(smartparking_reference.id_capteur = capteur.id_capteur)
set (CASE WHEN capteur.valeur != 0 then capteur.valeur = 0 and last_value_date = now() END)
where smartparking_reference.id_ref = 3;
But always a syntax error. So what did i miss ?

Apparently you want to update capteur.valeur only when it is nonzero and set it to zero. Try this simpler statement:
MySql style
Update capteur
join smartparking_reference on(smartparking_reference.id_capteur = capteur.id_capteur)
set valeur = case when valeur = 0 then 1 else 0 end, last_value_date = now()
where smartparking_reference.id_ref = 3;
Sql Server style
Update capteur
set valeur = case when valeur = 0 then 1 else 0 end, last_value_date = getdate()
from smartparking_reference
where smartparking_reference.id_capteur = capteur.id_capteur
and smartparking_reference.id_ref = 3;

I also guess your update statement has the wrong syntax
UPDATE c
SET valeur = 0, last_value_date = now()
FROM capteur c
INNER JOIN smartparking_reference AS sr ON
sr.id_capteur = c.id_capteur
WHERE sr.id_ref = 3 and c.valeur != 0

UPDATE capteur
SET capteur.valeur=(
CASE
WHEN capteur.valeur != 0 THEN
0 ELSE 'another value'
END
),last_value_date = now ()
FROM capteur
INNER JOIN smartparking_reference ON
smartparking_reference.id_capteur = capteur.id_capteur
WHERE
smartparking_reference.id_ref = 3;

Related

I'm getting: Subquery returned more than 1 value, but I don't have a subquery

UPDATE P
SET NRI_1 = (WI_1 * .8)
FROM AC_Property P
WHERE COALESCE(WI_1,0) <> 0 and RSV_CAT = 'PDNP'
Try with this:
UPDATE AC_Property
SET NRI_1 = (WI_1 * .8)
WHERE COALESCE(WI_1,0) <> 0 and RSV_CAT = 'PDNP'
You don't need to FROM because you are using the same table.
Also if you have a Trigger it will cause the error, because you update more than one (1) row.
Why not just use ?
UPDATE AC_Property
SET NRI_1 = (WI_1 * .8)
WHERE COALESCE(WI_1,0) <> 0 and RSV_CAT = 'PDNP'

SQL - WHERE with CASE statement

SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE
(CASE
WHEN DATALENGTH(CostRule.ModelName) = 0
THEN
CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1
ELSE
CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1
END
)
) AS MonoCost
I want to define my where statement depending on the datalength of CostRule.ModelName. But i got an error: Incorrect syntax near '='. in CostRule.Type = 1 and i got a error in the ELSE statement.
Must be like this:
...
WHERE
(DATALENGTH(CostRule.ModelName) = 0
AND CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1)
OR
(DATALENGTH(CostRule.ModelName) != 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1)
The CASE-style from your query cannot work.
you can change your statement like this:
SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE CostRule.ColorType=1
AND CostRule.Type=CASE WHEN DATALENGTH(CostRule.ModelName) = 0 THEN 1 ELSE 2 END
AND CostRule.Manufacturer=CASE WHEN DATALENGTH(CostRule.ModelName) = 0 THEN Printer.ManufacturerId ELSE Printer.ModelName END
You can't use a CASE statement to define where conditions like that. It will be easier to just use some boolean logic
SELECT *
FROM your_table
WHERE (DATALENGTH(CostRule.ModelName) = 0
AND CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1)
OR (DATALENGTH(CostRule.ModelName) != 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1)
There are some other things that could be removed (like CostRule.ColorType = 1 since it is the same in both branches) but I've left them in here to illustrate how to transform your CASE statement into a boolean logic set.
It looks like you would just need to change the WHERE statement:
It looks like you will just need to change your WHERE statement to use OR and remove the CASE Statement.
(SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE
DATALENGTH(CostRule.ModelName) = 0
CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1
OR
DATALENGTH(CostRule.ModelName) <> 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1
) AS MonoCost

Is there a way to ignore the AND in a CASE when something is true?

I have this Where clause
Select * From Student_Info si
Inner Join Certifications cc
Inner Join Cert_Earned ce
Where si.grad_date = #grad_date
AND cc.org_no = #org_no
but I need an additional AND that should be ignored if it turns out the value is false, I will want ALL certificates
AND cc.industrial = CASE WHEN #industrial = 0 THEN Do Nothing
Else #industrial
This would normally be expressed as:
AND (#industrial = 0 OR ccc.industrial = #industrial)
It sounds like you just want to add a predicate that does an OR between two different conditions
AND (#industrial = 0 or ccc.industrial = #industrial)
You can do something like this with CASE functions:
AND 1 = (CASE WHEN #industrial = 0 THEN 1
ELSE CASE WHEN cc.industrial = #industrial THEN 1 END
END)
or if cc.industrial is not nullable, then maybe:
AND cc.industrial = CASE WHEN #industrial = 0 THEN cc.industrial
Else #industrial END

If Var is certain Value omit the WHERE

Is it possible to omit the WHERE if a variable is a certain value? The following doesn't work and I am struggling to find an answer;
DECLARE #rMonth int, #rYear int, #sID int
SET #rMonth = 0;
SET #rYear = 0;
SET #sID= 0;
SELECT
TCS.bStatus AS jStatus, TCS.ID, TCS.sID, TCS.insDate, TCS.statusLabel, TCS.cID
FROM
TCS
CASE WHEN #rMonth > 0 THEN
WHERE month(insDate) = #rMonth AND year(insDate) = #rYear
END
This is common scenario to include a clause conditionally
check this out:
WHERE
(#rMonth = 0 OR MONTH(insDate) = #rMonth)
AND (#rYear = 0 OR YEAR(insDate) = #rYear)
AND (#sID = 0 OR sID = #sID)
In above query and for each clause, right hand side of "OR" is applied only if left hand side is false. Otherwise whole clause is considered as true and does not filter any row.
Hopefully,by using above trick any complex clause could be written in right side of "OR" rather than a simple equality comparision.
WHERE
(#rMonth <= 0)
OR
(month(insDate) = #rMonth AND year(insDate) = #rYear)
Another two options to achieve the same result:
one - using CASE statement like you wanted initially:
WHERE MONTH(insDate) = CASE WHEN #rMonth > 0 THEN #rMonth ELSE MONTH(insDate) END
AND YEAR(insDate) = CASE WHEN #rYear > 0 THEN #rYear ELSE YEAR(insDate) END
AND sID = CASE WHEN #sID > 0 THEN #sID ELSE sID END
and another - using ISNULL and NULLIF functions:
WHERE MONTH(insDate) = ISNULL(NULLIF(#rMonth, 0), MONTH(insDate))
AND YEAR(insDate) = ISNULL(NULLIF(#rYear, 0), YEAR(insDate))
AND sID = ISNULL(NULLIF(#sID, 0), sID)

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