Update a flag only if ALL matching condition fails - sql

I am trying to write a query in oracle to only update a flag based on below scenario :
Scenario :
A mctn_id is linked with multiple PRPR_ID and each PRPR_ID can have different addresses, I need to update flag as N in a table if ALL PRPR_ID addresses don't belong to config table address. If any of it belongs to config table address then it shouldn't update the flag as N.
I am using not exists in this case which is not working.
update prcb_enroll_tbl
set prov_flg ='N',
sys_insert_dtm = systimestamp
where tin_number in (select mctn_id
from cc_pr_prov prpr
inner join cc_pr_addr prad
on prpr.prpr_id = prad.prad_id
and not exists (select 1
from fsg_prcb_config config
where prad.prad_addr1 = config.config_value)
The above query is updating a flag even if only one of the addresses belongs to config table which is not the expected outcome.

This shoulds like not exists. Does this do what you want?
update prcb_enroll_tbl pe
set prov_flg ='N', sys_insert_dtm = systimestamp
where not exists (
select 1
from cc_pr_prov pr
inner join cc_pr_addr pa on pr.prpr_id = pz.prad_id
inner join fsg_prcb_config pc on pc.config_value = pa.prad_addr1
where ??.mctn_id = pe.tin_number
)
It is unclear which table column mctn_id comes from, so I used ???: you should replace it with the correct table alias.

Related

Update table column based on two other table values

I need to update a column in one of my tables based on data from 2 other tables.
So I want the column isAvailable, in the table questionObjectives, to be set to 1 based on 2 conditions and this is what I have:
UPDATE
dbo.questObjectives
SET
isAvailable = 1
FROM
dbo.questObjectives qo
INNER JOIN
dbo.dungeonList dl
ON
qo.questID = dl.questID
WHERE dl.dungeonType = 17
AND qo.objectiveID IN(SELECT objectiveID FROM gameMissions)
So to translate, isAvailable should be set to 1 if:
the linked dungeonList type is 17
the questionObjectives objectiveID is in the table gameMissions
So I thought I had my logic right, but I keep getting this error:
'invalid column name isAvailable.'
But it is there. It is in the questionObjectives table so I'm not sure what I'm doing wrong.
Any ideas?
Thanks!
Is this what you want?
update qo
set qo.isavailable = 1
from questObjectives qo
inner join dungeonList dl on qo.questID = dl.questID
where
dl.dungeonList = 17
and exists (select 1 from gameMissions gm where gm.objectiveID = qo.objectiveID)
The main problem with your query is that you have target table questObjectives both in the update and from clauses; you should have it just once, in the from clause, and then refer to the alias in the update clause.
I also rewrote the in condition as a correlated subquery with exists - the logic is the same, but this might perform better.

Is this questionable SQL Update syntax with aliased table correct?

I saw this SQL Update statement in a trigger and am unsure if the update works accurately - based on looking at where the table alias is and the update table syntax.
The syntax doesn't give any error on execution, and updates the record correctly when executing on random samples on my test DB.
However, on a larger PROD DB with more records, is there a possibility that the update fails or skips altogether? There were reports that random records did not have the SAMPLE.ISCOMPOSITESAMPLE field set.
Questionable syntax
UPDATE SAMPLE SET
SAMPLE.SAMPLETYPE = (SELECT DESCRIPTION FROM SAMPLETYPE WHERE SAMPLETYPENO = C.SAMPLETYPENO),
SAMPLE.ISCOMPOSITESAMPLE = (SELECT COMPOSITESAMPLE FROM SAMPLETYPE WHERE SAMPLETYPENO = C.SAMPLETYPENO)
FROM SAMPLE C
INNER JOIN INSERTED T ON C.SAMPLENO = T.SAMPLENO
Syntax I am familiar with (similar to above but intentionally not optimised for comparison)
UPDATE C SET
SAMPLETYPE = (SELECT DESCRIPTION FROM SAMPLETYPE WHERE SAMPLETYPENO = C.SAMPLETYPENO),
ISCOMPOSITESAMPLE = (SELECT COMPOSITESAMPLE FROM SAMPLETYPE WHERE SAMPLETYPENO = C.SAMPLETYPENO)
FROM SAMPLE C
INNER JOIN INSERTED T ON C.SAMPLENO = T.SAMPLENO
The query is correct and will work. However, there are two things that I would fix:
TheUPDATE SAMPLE does update the table whose alias is C. This is documented as correct and something that really irks me, because aliases should be respected. You should use the alias for the update.
The correlated subqueries are not using fully qualified column names.
So, using correlated subqueries, I would recommend:
UPDATE S
SET SAMPLETYPE = (SELECT ST.DESCRIPTION FROM SAMPLETYPE ST WHERE ST.SAMPLETYPENO = S.SAMPLETYPENO),
ISCOMPOSITESAMPLE = (SELECT ST.COMPOSITESAMPLE FROM SAMPLETYPE ST WHERE ST.SAMPLETYPENO = S.SAMPLETYPENO)
FROM SAMPLE S INNER JOIN
INSERTED I
ON S.SAMPLENO = I.SAMPLENO ;
You can also write this -- probably more efficiently -- using a LEFT JOIN:
UPDATE S
SET SAMPLETYPE = ST.DESCRIPTION,
ISCOMPOSITESAMPLE = ST.COMPOSITESAMPLE
FROM SAMPLE S INNER JOIN
INSERTED I
ON S.SAMPLENO = I.SAMPLENO LEFT JOIN
SAMPLETYPE ST
ON ST.SAMPLETYPENO = S.SAMPLETYPENO;

Oracle : How to update multiple columns from different table?

I am using oracle database and have a situations to update fields from some other tables. My issue is it is updating all the records instead of specified conditions.
For example, I am trying to update perm_address and temp_address in EMPLOYEE table from ADDRESS table. Right now, I am using below query. But, it is updating all the records.
UPDATE EMPLOYEE EMP
SET (EMP.PERM_ADDRESS, EMP.TEMP_ADDRESS) =
(SELECT ADDR.PERM_ADDR,ADDR.TEMP_ADDR
FROM ADDRESS ADDR
WHERE ADDR.ID=EMP.ADDRESS_ID
);
In Oracle how to handle this situations? Normally, how to handle the update from multiple table into source table?
Thanks in advance....
Add a WHERE clause to update only matching records:
UPDATE EMPLOYEE EMP
SET (EMP.PERM_ADDRESS, EMP.TEMP_ADDRESS) =
(SELECT ADDR.PERM_ADDR, ADDR.TEMP_ADDR
FROM ADDRESS ADDR
WHERE ADDR.ID = EMP.ADDRESS_ID
)
WHERE EXISTS (SELECT 1 FROM ADDRESS ADDR WHERE ADDR.ID = EMP.ADDRESS_ID);
Updating a table with data from another table is often simpler using the MERGE statement. https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm
Something like this:
merge into employee emp
using address addr
on (addr.id = emp.address_id)
when matched
then update
set emp.perm_address = addr.perm_addr,
emp.temp_address = addr.temp_addr;
updating one table by another table - the basic format is
--ORACLE
update tableX t set (t.fldA, t.fldB) =
(select fldA, fldB from table_B where ID ='X')
where t.ID = 'Y'

How to merge missing records from the backup table to the original one

I have 2 schema of database (on oracle 11.g) : BackUp and Original.
The table TAX has the same structure on both schema.
It hasn't a primary key but has as index :
TAXCOD, COUNTRY, LONG_SHORT and FUND.
I want to select the records that are missing from the original table and found on the backup.
I checked the Left Outer Join query on this Link
http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
And, I wrote this query according to what is mentioned :
select *
from BackUp.TAX x
left outer join Original.TAX y
on (x.TAXCOD = y.TAXCOD and
x.COUNTRY = y.COUNTRY and
x.LONG_SHORT = y.LONG_SHORT and
x.FUND = y.FUND)
where y.TAXCOD is NULL
and y.COUNTRY is NULL
and y.LONG_SHORT is NULL
and y.FUND is NULL
but this query brings even commun records between the 2 tables and not just missing one .
Please could you explain for me where the problem lies.
Thanks for advance.
I'd use EXCEPT to find rows in one table that does not exist in the other table:
select * from BackUp.TAX
except all
select * from Original.TAX
Or, if you just want to match the mentioned columns, use NOT EXISTS:
select * from BackUp.TAX x
where NOT EXISTS (select 1 from Original.TAX y
where x.TAXCOD = y.TAXCOD
and x.COUNTRY = y.COUNTRY
and x.LONG_SHORT = y.LONG_SHORT
and x.FUND = y.FUND)

Update database from another using joins?

I am trying to update a table from another database using joins and having a hard time. This is what I am trying to do in pseudo:
UPDATE [Database1].[dbo].[Sessions]
SET [SpeakerID] = ?STATEMENT1?
WHERE ?STATEMENT2?
For "Statement1", this would be coming from another database and table that has columns: SessionID and SpeakerID. How can this be achieved?
UPDATE a
SET a.SpeakerID = b.colName -- SET valoue here
FROM Database1.dbo.Sessions a
INNER JOIN Database2.dbo.Sessions b
ON a.SessionID = b.SessionID -- assumes that their
-- relationship column is SessionID,
-- change it in your original columnName
WHERE ....
a and b are called alias. They are useful when you have longer source name.
UPDATE L
SET SpeakerID = R.SpeakerID
FROM dbo.LocalTable AS L
INNER JOIN RemoteDatabase.dbo.RemoteTable AS R
ON L.SomeValue = R.SomeValue;
This really is no different from this problem except you have to add a database prefix to one of the tables in the join.
try
UPDATE [Database1].[dbo].[Sessions]
SET
Sessions.col1 = other_table.col1
FROM
[Database1].[dbo].[Sessions] Sessions
INNER JOIN
[Database2].[dbo].other_table AS other_table
ON
Sessions.id = other_table.id
WHERE Sessions.id = ??
Note if the database is on another server you will need to create a linked server first
http://msdn.microsoft.com/en-us/library/ff772782.aspx