how to check if existing column changes from some value to NULL using Oracle - sql

I'd like to check the following condition using sql query using Oracle:
to check id a user changes Condition from some value to another value
to check if a user changes condition from some value to NULL
I am trying for the below query:
(select count(*) from MyTable where (:userconditionid = (select condition_id from MyTable
where item = :useritem))
and item = :useritem)
where :userconditioncode is the value user is trying to enter value, the above query works for normal values but it wont work for null value , if user changes the condition from some value to null value
the above sql query fails.
Sample Data and Desired Results
If user is trying to alter the condition_id to NULL
then I have to throw am error as follows:
"User are not allowed to change the value to null"
also if user is trying to alter the condition from NULL to some other value
then it should not throw an error.

If I correctly got all your comments - the only case to throw error for you is when not-null value is tried to be changed to null. Consider using
select case when condition_id is not null and :userconditionid is null then 1 else 0 end as do_throw_error
from MyTable
where item = :useritem
in this case.

The thing about nulls is that almost all '=' comparisons to null return false.
The proper test is not '=' but 'is null':
In P/L SQL:
if :userConditionCode is null then
throw...
or is SQL:
(select count(*) from MyTable
where
(
(:userconditionid = (select condition_id from MyTable
where item = :useritem)
)
or :userconditionid is null
)
and item = :useritem)

The only way to check the value for null in SQL is IS NULL predicate. Of course, you can translate null to something else but real NULL check is nothing else than IS NULL.
Does this code suits your need? You've not wrote what should be done when there's no data for requested :useritem.
select 'User are not allowed to change the value to null' as msg
from MyTable
where item = :useritem
having (
min(1) /*Table has that item*/,
min(case
when f.condition_id is not null and :userconditionid is null
then 1
end) /*User sets non null value to null*/
) in ((1,1))

Related

Postgres UPDATE with CASE and RETURNING

I am trying to update columns using CASE statement
access_status here is an ENUM type, so, I have to CAST it otherwise Postgres gives error of converting text to ENUM with CASE statement (without CASE statement, I don't get this error)
UPDATE table_1
SET
access_status =
CASE
WHEN access_status='ACTIVE' THEN 'REVOKED'
ELSE access_status -- need to write this otherwise the value is set to NULL
END::access_status,
updated_at =
CASE
WHEN access_status='ACTIVE' THEN NOW()
ELSE updated_at
END,
updated_by =
CASE
WHEN access_status='ACTIVE' THEN 1
ELSE updated_by
END
WHERE
id = 4
RETURNING
id
From above, the condition is on single column only. I need to update multiple columns when access_status='ACTIVE' else DO NOTHING.
Also, I am RETURNING id to know if the update has been performed or not (to return response accordingly from the API). Want to return id only if the update has been performed
Is it possible to do it something like this =>
UPDATE table_1
CASE
WHEN access_status = 'ACTIVE' THEN SET access_status = 'REVOKED',
updated_by = 1,
updated_at = NOW()
END
WHERE
id = 4
RETURNING
id
So that, I don't need to write multiple CASE statements for each column update

merge condition is not working in sql server

I have two tables one is (providerLoc) and another one is (tmpProviderLoc) I need to take three columns combination from tmpProviderLoc and need to check the records exist in ProviderLoc
Case 1 : If record exist in providerLoc i need to update another column(Npi) in providerLoc based on column (npi) in tmpProviderLoc
case 2 : if not exist i need to insert the values in providerLoc
for that I have written below query:
MERGE INTO [dbo].[ProviderLoc] AS PL
USING
(
select *
from (
select *,
row_number() over (partition by [Location_ID],[PProviderTaxID]
,[POBOXZIP] order by [Location_ID],[PProviderTaxID],[POBOXZIP]) as row_number
from [dbo].[TmpProviderLoc]
) as rows
where row_number = 1
) AS TPL
ON TPL.[Location_ID] = PL.[ecProviderID]
AND TPL.[PProviderTaxID] = PL.[TaxID]
AND TPL.[NPI] = PL.[NPI]
AND TPL.[POBOXZIP] = PL.[POBOXZIP]
WHEN MATCHED THEN
UPDATE SET PL.[NPI] = CASE
WHEN TPL.[NPI] = NULL THEN PL.[NPI]
ELSE TPL.[NPI]
END
WHEN NOT MATCHED THEN
INSERT (EcProviderID,TaxID,NPI,POBOXZIP,ProviderLocationStatusID,CreatedON)
VALUES (TPL.[Location_ID],TPL.[PProviderTaxID],TPL.[NPI]
,TPL.[POBOXZIP],1,GETDATE());
But I am failing in updating the NPI value -- if npi value is new in tmpProviderLoc it is not updating in ProviderLoc..
Could any one please look into this issue..
or any other way to go through this kind of checking
The equal symbol in this is incorrect: WHEN TPL.[NPI] = NULL THEN PL.[NPI]
Use IS NULL
WHEN TPL.[NPI] IS NULL THEN PL.[NPI]
NULLs are special. They are "indeterminate" so they cannot be equal or unequal to anything purely because they just cannot have any value "determined". NULLs are the absence of value and equal/unequal does not apply.
To discover if NULL exists use IS NULL - or - IS NOT NULL to discover if there is a non-null value.

Select from table with 2 condition and 2 operations

I have a Table BoxTrans
the table Contain Rows (ID,Date,FromBox,ToBox,Value)
I want to make a View like (ID,Date,Box,ValueIn,ValueOut)
select when frombox Give Value to ValueOut
and when tobox Give Value to ValueIN
You can use a CASE statement to check the value of a different column when populating a column. The below query will return your output as long as either ToBox or FromBox is NULL, if they are both not null you may get unexpected results.
SELECT ID,
Date,
COALESCE(ToBox,FromBox) as Box,
CASE WHEN ToBox IS NOT NULL THEN value ELSE NULL as ValueIn,
CASE WHEN FromBox IS NOT NULL THEN value ELSE NULL as ValueOut
FROM BoxTrans

<> and != avoiding NULL in WHERE condition

I have a table PATIENT with Column STATUS. When I queried to get STATUS not equal to 1, I was expecting the result as NULL and 2.
But I am only getting 2 as the result. Can someone help me with this?
CREATE TABLE #PATIENT
(STATUS INT)
INSERT INTO #PATIENT (STATUS)
SELECT 1
UNION
SELECT 2
UNION
SELECT NULL
SELECT * FROM #PATIENT WHERE STATUS <> 1
When I queried with
SELECT * FROM #PATIENT WHERE ISNULL(STATUS, 0) != 1
I am able to get NULL and 2 as the result.
This is SQL SERVER 2012.
You can use OR in WHERE with Condition STATUS IS NULL .
SELECT * FROM #PATIENT WHERE STATUS <> 1 OR STATUS IS NULL
This will do it.
EDIT:
Conceptually, NULL means “a missing unknown value” and it is
treated somewhat differently from other values.
You cannot use arithmetic comparison operators such as =, <, or <>
to test for NULL
Because the result of any arithmetic comparison with NULL is also
NULL, you cannot obtain any meaningful results from such comparisons
we can not equate or not equate anything with null, thats why IS NULL
SELECT NULL <> 1 ===> NULL
Even though it is supposed to be true, it will return `NULL`
Hope this helps.
When you compare NULL value to any value then the result is always NULL.
So if you wan to select the NULL value as well then try this:
SELECT * FROM #PATIENT WHERE STATUS <> 1 OR STATUS IS NULL
DEMO
Conceptually "NULL" means a missing value. To test for NULL IS NULL or IS NOT NULL condition is used. Arithmetic operators cannot be used for comparing NULL values.
NULL<>1 :: returns false because NULL can be 1 or any other value (an unknown value).
Null is a special marker used in Structured Query Language (SQL) to indicate that a data value does not exist in the database.
And reason because you got only 2 and NOT NULL is because in SQL nothing is equal to NULL but also nothing is NOT equal to NULL.
In Simple words you cannot equate and not equate any value with NULL.

Trouble comparing smallint in where clause

I have a table with a column called status of type smallint and accepts null. Sql server 2000.
My data contains mostly 2 in that field, but also 0 and null.
When I do
select *
from table
where status <> 2
I don't get all the proper records (where status is null or 0). Any idea why this is happening and how to correct? Shouldn't <> give me everything other than 2?
The NULL test doesn't match any arithmetic comparison.
use
where status <> 2 OR status is null
select *
from table
where ISNULL(status, 1) <> 2
NULL doesn't compare: so remove it.
Your example is the "common mistake" on Wikipedia too...
What you're expecting can be accomplished by setting ANSI_NULLS to off.
For example, try running these queries:
set ansi_nulls off
select case when 1 != null then 'true' else 'false' end
set ansi_nulls on
select case when 1 != null then 'true' else 'false' end
That being said, this is very non-standard SQL behaviour that you're expecting to see. NULL comparisons should always be considered false whether equals to or not equals to comparisons, as every developer will expect that type of SQL query behaviour.
Your WHERE clause should then look like:
where status <> 2 or status is null
Another option would be just to compare to status = 1, if that is the only status that you're expecting to be included in your query.