SQL Server Multiple Assignments within IF or CASE WHEN block - sql

I was wondering if it's possible to assign values to multiple fields within a block of an IF or CASE WHEN statement in SQL Server 2008? In a project I am working on, when a condition is met, I want to assign specific values to 4 different fields, if not met I want to assign other values to the sames fields.
See examples below.
Thanks in advance for your help. Any tip will be welcome.
SELECT With CASE WHEN
SELECT with IF
SELECT Field1
,Field2
,Field3
CASE
WHEN Condtion1_Met THEN
,Field4 = Value4A
,Field5 = Value5A
,Field6 = Value6A
,Field7 = Value7A
ELSE
,Field4 = Value4B
,Field5 = Value5B
,Field6 = Value6B
,Field7 = Value7B
END
FROM Table1
______________________________________________
SELECT Field1
,Field2
,Field3
IF Condtion1_Met
BEGIN
,Field4 = Value4A
,Field5 = Value5A
,Field6 = Value6A
,Field7 = Value7A
END
ELSE
BEGIN
,Field4 = Value4B
,Field5 = Value5B
,Field6 = Value6B
,Field7 = Value7B
END
FROM Table1

No, this is not possible. A CASE expression (it is considered to be an expression, not a statement) can only return a single value. It can't set multiple values.
And an IF statement can't be used inside a query at all. Instead you could do this:
IF Condition1_Met
SELECT ...
ELSE
SELECT ...

I finally decided to use a WHILE loop combined with IF/ELSE statements to UPDATE the fields in the table.

Related

GETTING ERROR-- ORA-00936:MISSING EXPRESSION for below query please help on this

SELECT CASE (SELECT Count(1)
FROM wf_item_activity_statuses_v t
WHERE t.activity_label IN ('WAITING_DISB_REQ',
'LOG_DDE',
'LOG_SENDBACK_DDE')
AND t.item_key IN(
SELECT r.i_item_key
FROM wf_t_item_xref r
WHERE r.sz_appl_uniqueid = '20400000988')
)
WHEN 0 THEN
(
delete
from t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_item_key = '648197'
AND p.i_document_srno = '27' )
WHEN 1 THEN
(
DELETE
FROM t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_document_srno = '28' )
ELSE NULL
END
FROM dual;
You need to recreate your query and make sure to follow the flow of the clauses properly, please check the next two links to get a better understanding :
[ORA-00936: missing expression tips]
How do I address this ORA-00936 error?
Answer: The Oracle oerr utility notes this about the ORA-00936 error:
ORA-00936 missing expression
Cause: A required part of a clause or expression has been omitted. For example, a SELECT statement may have been entered without a list of columns or expressions or with an incomplete expression. This message is also issued in cases where a reserved word is misused, as in SELECT TABLE.
Action: Check the statement syntax and specify the missing component.
The ORA-00936 happens most frequently:
1 - When you forget list of the column names in your SELECT statement.
2. When you omit the FROM clause of the SQL statement.
ora-00936-missing-expression
I hope this can help you.
You cannot use a simple select query like this. You have to use a PL/SQL block like below -
DECLARE NUM_CNT NUMBER := 0;
BEGIN
SELECT Count(1)
INTO NUM_CNT
FROM wf_item_activity_statuses_v t
WHERE t.activity_label IN ('WAITING_DISB_REQ',
'LOG_DDE',
'LOG_SENDBACK_DDE')
AND t.item_key IN(SELECT r.i_item_key
FROM wf_t_item_xref r
WHERE r.sz_appl_uniqueid = '20400000988');
IF NUM_CNT = 0 THEN
delete
from t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_item_key = '648197'
AND p.i_document_srno = '27';
ELSIF NUM_CNT = 1 THEN
DELETE
FROM t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_document_srno = '28' )
END IF;
END;

Update multiple values using IS NULL condition

I just finished migrating an Access database to the SQL Server and I need to fix the Yes/No values to be defaulted to No as their data type conversion is set to bit.
I do this by setting the default value to 0.
However, I want to execute a query to do that as well, but there are multiple bit rows.
I know how to use multiples with the SET command, but how do we use multiple with WHERE? What is the proper way of structuring it?
UPDATE sometable SET
[isConditionOnePassed] = 0
, [isSecondPassed] = 0
, [isThirdPassed] = 0
WHERE [isConditionOnePassed] IS NULL, [isSecondPassed] is NULL, [isThirdPassed] IS NULL
Or is it with an AND? Like boolean logic?
UPDATE sometable SET
[isConditionOnePassed] = 0
, [isSecondPassed] = 0
, [isThirdPassed] = 0
WHERE [isConditionOnePassed] IS NULL and [isSecondPassed] is NULL and [isThirdPassed] IS NULL
Hmmm . . . If you want to set NULL values to another value, you can use COALESCE():
UPDATE sometable
SET isConditionOnePassed = COALESCE(isConditionOnePassed, 0),
isSecondPassed = COALESCE(isSecondPassed, 0),
isThirdPassed = COALESDCE(isThirdPassed, 0)
WHERE isConditionOnePassed IS NULL OR isSecondPassed is NULL OR isThirdPassed IS NULL;
Seems like what you really need is an ISNULL or CASE expression. Here is an example with both:
UPDATE dbo.SomeTable
SET isConditionOnePassed = ISNULL(isConditionOnePassed,0),
isSecondPassed = CASE isSecondPassed WHEN 1 THEN 1 ELSE 0 END;

How to not update null value into a column when it already have a value in SQL Server query

How can I not update the null value into a column when it already have a value in SQL Server query in the query prepared in Mule? The payload contains the result set from Data weave. While updating, I want to check whether the updating value is null or not, in case of it "not null" then only value should be updated.
Query is:
UPDATE dbo.ix_str_store
SET NAME = '#[payload.Site.Name]',
ADDRESS1 = '#[payload.Site.Address1]',
ADDRESS2 = '#[payload.Site.Address2]',
ADDRESSCITY = '#[payload.Site.AddressCity]',
ADDRESSSTATE = '#[payload.Site.AddressState]',
ADDRESSPOSTALCODE = '#[payload.Site.AddressPostalCode]',
ADDRESSCOUNTRY = '#[payload.Site.AddressCountry]',
EMAIL = '#[payload.Site.Email]',
PHONE = '#[payload.Site.Phone]',
FAX = '#[payload.Site.Fax]',
REGION = '#[payload.Site.Region]',
COMPANY = '#[payload.Site.Company]',
DESC1 = '#[payload.Site.Desc1]',
DESC2 = '#[payload.Site.Desc2]',
DESC7 = '#[payload.Site.Desc7]',
DESC8 = '#[payload.Site.Desc8]',
VALUE1 = #[payload.Site.Value1],
VALUE2 = #[payload.Site.Value2],
DBTIME = CURRENT_TIMESTAMP,
DBSTATUS = 1
WHERE
STORENUMBER = #[payload.Site.StoreNumber]
try it's
isnull(new_value,old_value)
In that case, instead of using insert into (...) values(...) construct ; use insert into .. select from construct like
insert into table (..)
select ..,
case when new_col_val is not null then new_col_val else old_col_val end
from ...
(OR) you can as well use COALESCE() function instead of CASE expression saying coalesce(new_col_val, old_col_val)

SQL Update when not null

I'm trying to set a column in the fabcon table only if the original column is null.
This is the code I've already tried.
UPDATE dbo.fabcon
SET ext = COALESCE(ext, ( SELECT CASE WHEN [<3] IS NOT NULL THEN '3' END AS extent
FROM dbo.spreadsheetData ))
This is the error I'm getting:
Sub-query returned more than 1 value. This is not permitted when the sub-query follows =, !=, <, <= , >, >= or when the sub-query is used as an expression.
Can anyone see where I've gone wrong?
Thanks. :)
EDIT: the two tables fabcon and spreadsheetData are linked by a column called main1
EDIT2: I've updated the query to this:
UPDATE dbo.fabcon
SET ext = (SELECT CASE WHEN [<3] IS NOT NULL THEN '3' END
FROM dbo.spreadsheetData ssd
WHERE ssd.id = fabcon.id
)
WHERE ext IS NULL;
However, its still failing with the same error.
You need a link between the table fabcon and spreadsheetData. Assuming it is called id:
UPDATE dbo.fabcon
SET ext = (SELECT CASE WHEN [<3] IS NOT NULL THEN '3' END)
FROM dbo.spreadsheetData ssd
WHERE ssd.id = fabcon.id
)
WHERE ext IS NULL;
Note that I removed the coalesce() and replaced it with a where clause for the update. This prevents the query from updating rows unnecessarily (with unchanged values).
DECLARE #PAth INT
Select #path = COALESCE(ext,'')+[<3]+';' FROM dbo.spreadsheetData
UPDATE dbo.fabcon
SET ext = CASE WHEN #PAth IS NOT NULL
THEN '3' ELSE ''
END AS Extent
FROM dbo.fabcon f WHERE f.id = #path
may be this works i think
This should work for you. Assuming I have understood your original query correctly
UPDATE dbo.fabcon
SET
ext = ssd.[column to insert data from]
FROM
dbo.spreadsheetData ssd
WHERE
ext IS NULL
AND
fabcon.id = ssd.id
This assumes the id in the ssd table is the id from the fabcon table. Otherwise just change the id matching based on your column specification
UPDATE dbo.fabcon
SET ext = (SELECT TOP 1 CASE WHEN [<3] IS NOT NULL THEN '3' END
FROM dbo.spreadsheetData ssd
WHERE ssd.main1 = fabcon.main1
ORDER BY 1
)
WHERE ext IS NULL;
with the 2 tables related via "main1" (as now indicated) and an arbitrary "TOP 1" thrown in to avoid the error, this might work.
but: the best way to get an answer is to provide some sample data and an expected result

ISNULL, SQL, Using a select statement as the second parameter

I don't know if this is possible in SQL or if I have to write a stored procedure but I'm trying to use the ISNULL function as below so that when the parameter #sku is null I'm using a select statement to bring back all the sku's in the table:
SELECT GooglePrice.idGooglePrice, GooglePrice.idProduct, products.sku, products.wholeprice, products.price as CurrentHMMPrice, GooglePrice.bestPrice, GooglePrice.link, GooglePrice.title, GooglePrice.description, GooglePrice.ourPrice as PriceCompHMMPrice,
GooglePrice.searchType, GooglePrice.shippingCost, GooglePrice.cheapestOrder, GooglePrice.timeStamp,
'ShippingCostNew' = CASE
WHEN GooglePrice.shippingCost = -1 THEN 'N/A'
WHEN GooglePrice.shippingCost = 0 THEN 'Free Shipping'
WHEN GooglePrice.shippingCost > 0 Then cast(GooglePrice.shippingCost as varchar)
END
FROM GooglePrice INNER JOIN
products ON GooglePrice.idProduct = products.idProduct
WHERE (products.supplierCode in (#SupplierCode)) AND ISNULL((products.sku like '%'+#sku+'%'), (products.sku in (select sku from products where products.sku)))
ORDER BY GooglePrice.idGooglePrice
Would be easier with an OR
WHERE
(products.supplierCode in (#SupplierCode))
AND
(products.sku like '%'+#SupplierCode+'%' OR #SupplierCode IS NULL)
This was your intention, no?
AND
products.sku like ISNULL('%'+#SupplierCode+'%',products.sku)
Notes:
leading wildcards can not be optimised and won't use indexes.
I assume you don't have a CSV in #SupplierCode for this products.supplierCode in (#SupplierCode)
Don't overcomplicate it.
Make your WHERE clause:
WHERE
((products.supplierCode in (#SupplierCode)
AND
(products.sku like '%'+#SupplierCode+'%'))
OR (#suppliercode IS NULL)
You don't really explain your logic so I'm guessing, but the idea is to put a separate check for the NULL comparison.
SELECT GooglePrice.idGooglePrice, GooglePrice.idProduct, products.sku, products.wholeprice, products.price as CurrentHMMPrice, GooglePrice.bestPrice, GooglePrice.link, GooglePrice.title, GooglePrice.description, GooglePrice.ourPrice as PriceCompHMMPrice, GooglePrice.searchType, GooglePrice.shippingCost, GooglePrice.cheapestOrder, GooglePrice.timeStamp,
'ShippingCostNew' = CASE
WHEN GooglePrice.shippingCost = -1 THEN 'N/A'
WHEN GooglePrice.shippingCost = 0 THEN 'Free Shipping'
WHEN GooglePrice.shippingCost > 0 Then cast(GooglePrice.shippingCost as varchar)
END
FROM GooglePrice INNER JOIN
products ON GooglePrice.idProduct = products.idProduct
WHERE (products.supplierCode in (#SupplierCode)) AND (#SupplierCode is null or products.sku like '%'+#SupplierCode+'%')
ORDER BY GooglePrice.idGooglePrice