How to overcome IN clause issue in oracle - oracle

i am updating a table called table2 from table1 on column name Active_status.But the problem the result contains more than 1000.How to overcome this issue.I am using this query in a c# application.I heard we can use temp table ,if so how can i use or is there any better way.followingis my query
UPDATE table2
SET Active_status = 'N',
MODIFIED_DATE = SYSDATE
WHERE t2_SLNO IN
(SELECT t2_SLNO
FROM table2
LEFT JOIN table1
ON table2.t2_NAME = table1.t1_NAME
WHERE table1.t1_NAME IS NULL
)
AND Active_status <> 'N';
EDIT
I am doing this modification everday.By using a merge.But there are situations like table2 contain some dead data which i want to make status 'N' since the source of table1 and table2 is a remote database which is exposed by some other team.So thought of to do this work after my existing MERGE operation

As #aleksej suggested, you can use MERGE:
MERGE INTO table1 t
USING table2 s
ON(t.t1_NAME = s.t2_NAME)
WHEN NOT MATCHED UPDATE SET Active_status = 'N',
MODIFIED_DATE = sysdate
WHERE t.Active_status <> 'N'
And you can change you update to work like this:
UPDATE table1 t
SET t.Active_status = 'N',
t.MODIFIED_DATE = sysdate
WHERE NOT EXISTS(SELECT 1 FROM table2 s
WHERE t.t1_NAME = s.t2_NAME)
AND t.Active_status <> 'N'

Related

Update only values in a field in a table where criteria is from a linked table [duplicate]

I have a query which works fine in MySQL, but when I run it on Oracle I get the following error:
SQL Error: ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"
The query is:
UPDATE table1
INNER JOIN table2 ON table1.value = table2.DESC
SET table1.value = table2.CODE
WHERE table1.UPDATETYPE='blah';
That syntax isn't valid in Oracle. You can do this:
UPDATE table1 SET table1.value = (SELECT table2.CODE
FROM table2
WHERE table1.value = table2.DESC)
WHERE table1.UPDATETYPE='blah'
AND EXISTS (SELECT table2.CODE
FROM table2
WHERE table1.value = table2.DESC);
Or you might be able to do this:
UPDATE
(SELECT table1.value as OLD, table2.CODE as NEW
FROM table1
INNER JOIN table2
ON table1.value = table2.DESC
WHERE table1.UPDATETYPE='blah'
) t
SET t.OLD = t.NEW
It depends if the inline view is considered updateable by Oracle
( To be updatable for the second statement depends on some rules listed
here ).
Use this:
MERGE
INTO table1 trg
USING (
SELECT t1.rowid AS rid, t2.code
FROM table1 t1
JOIN table2 t2
ON table1.value = table2.DESC
WHERE table1.UPDATETYPE='blah'
) src
ON (trg.rowid = src.rid)
WHEN MATCHED THEN UPDATE
SET trg.value = code;
MERGE with WHERE clause:
MERGE into table1
USING table2
ON (table1.id = table2.id)
WHEN MATCHED THEN UPDATE SET table1.startdate = table2.start_date
WHERE table1.startdate > table2.start_date;
You need the WHERE clause because columns referenced in the ON clause cannot be updated.
Do not use some of the answers above.
Some suggest the use of nested SELECT, don't do that, it is excruciatingly slow. If you have lots of records to update, use join, so something like:
update (select bonus
from employee_bonus b
inner join employees e on b.employee_id = e.employee_id
where e.bonus_eligible = 'N') t
set t.bonus = 0;
See this link for more details.
http://geekswithblogs.net/WillSmith/archive/2008/06/18/oracle-update-with-join-again.aspx.
Also, ensure that there are primary keys on all the tables you are joining.
UPDATE ( SELECT t1.value, t2.CODE
FROM table1 t1
INNER JOIN table2 t2 ON t1.Value = t2.DESC
WHERE t1.UPDATETYPE='blah')
SET t1.Value= t2.CODE
As indicated here, the general syntax for the first solution proposed by Tony Andrews is :
update some_table s
set (s.col1, s.col2) = (select x.col1, x.col2
from other_table x
where x.key_value = s.key_value
)
where exists (select 1
from other_table x
where x.key_value = s.key_value
)
I think this is interesting especially if you want update more than one field.
It works fine oracle
merge into table1 t1
using (select * from table2) t2
on (t1.empid = t2.empid)
when matched then update set t1.salary = t2.salary
This following syntax works for me.
UPDATE
(SELECT A.utl_id,
b.utl1_id
FROM trb_pi_joint A
JOIN trb_tpr B
ON A.tp_id=B.tp_id Where A.pij_type=2 and a.utl_id is null
)
SET utl_id=utl1_id;
Using description instead of desc for table2,
update
table1
set
value = (select code from table2 where description = table1.value)
where
exists (select 1 from table2 where description = table1.value)
and
table1.updatetype = 'blah'
;
UPDATE table1 t1
SET t1.value =
(select t2.CODE from table2 t2
where t1.value = t2.DESC)
WHERE t1.UPDATETYPE='blah';
UPDATE (SELECT T.FIELD A, S.FIELD B
FROM TABLE_T T INNER JOIN TABLE_S S
ON T.ID = S.ID)
SET B = A;
A and B are alias fields, you do not need to point the table.
UPDATE IP_ADMISSION_REQUEST ip1
SET IP1.WRIST_BAND_PRINT_STATUS=0
WHERE IP1.IP_ADM_REQ_ID =
(SELECT IP.IP_ADM_REQ_ID
FROM IP_ADMISSION_REQUEST ip
INNER JOIN VISIT v
ON ip.ip_visit_id=v.visit_id
AND v.pat_id =3702
); `enter code here`
Just as a matter of completeness, and because we're talking Oracle, this could do it as well:
declare
begin
for sel in (
select table2.code, table2.desc
from table1
join table2 on table1.value = table2.desc
where table1.updatetype = 'blah'
) loop
update table1
set table1.value = sel.code
where table1.updatetype = 'blah' and table1.value = sel.desc;
end loop;
end;
/
Oracle base has a good run down on this.
https://oracle-base.com/articles/misc/updates-based-on-queries
From this link - I used a modification of the above query which did not work for me (the answer from mathguy which uses rowid)
MERGE /*+ APPEND PARALLEL(8) */ INTO dest_table tt
USING source_table st
ON (tt.identifier = st.identifier)
WHEN MATCHED THEN
UPDATE SET tt.number = st.number;
Here I have two tables: source and dest. They both have a varchar field in common and I am adding the source identify field (PK) into the dest table.
update table1 a
set a.col1='Y'
where exists(select 1
from table2 b
where a.col1=b.col1
and a.col2=b.col2
)

MERGE WITH ROW_NUMBER

I am trying to perform a merge to insert and update as the case may be in a table. However in table 1, I only want it to insert the unique values ​​of the tbl2.rfc field regardless if my other fields change, I only want to show the unique values ​​of said field. I am occupying the ROW_NUMBER function to bring only unique values, but I have not been able to add this function to my merge.
MERGE INTO B69_TBL1 tbl1
USING (SELECT T1.*, ROW_NUMBER() OVER (PARTITION BY T1.rfc ORDER BY T1.rfc DESC) ENUMERADO
FROM B69_TBL2 tbl2
WHEN MATCHED THEN
UPDATE SET
tbl1.id_tbl1 = tbl2.id_con,
tbl1.rfc = tbl2.rfc,
tbl1.rfc = tbl2.name_cont
WHEN NOT MATCHED THEN
INSERT (tbl1.id_tbl1,tbl1.tbl1tipo,tbl1.id_concentrado,tbl1.rfc,
tbl1.name_cont,tbl1.baja_logica,tbl1.last_update)
VALUES (id_tbl1autt.nextval,'1','1',tbl2.id_concentrado,tbl2.rfc,
tbl2.name_cont,'0', '11/05/2021')
) T1
WHERE ENUMERADO=1
AND RFC IS NOT NULL
The error it marks is 00907. 00000 - "missing right parenthesis"
because I had it like this and it fails precisely in the on.
MERGE INTO B69_TBL1 tbl1
USING (SELECT T1.*, ROW_NUMBER() OVER (PARTITION BY T1.rfc ORDER BY T1.rfc DESC) ENUMERADO
ON tbl1.rfc = tbl2.rfc
FROM B69_TBL2 tbl2 )
WHEN MATCHED THEN
UPDATE SET
tbl1.id_alert = tbl2.id_con,
tbl1.rfc = tbl2.rfc,
tbl1.rfc = tbl2.name_cont
WHEN NOT MATCHED THEN
INSERT (tbl1.id_alert,tbl1.alertype,tbl1.id_con,tbl1.rfc,
tbl1.name_cont,tbl1.baja_logica,tbl1.last_update)
VALUES (id_tbl1autt.nextval,'1','1',tbl2.id_con,tbl2.rfc,
tbl2.name_cont,'0', '11/05/2021')
) T1
WHERE ENUMERADO=1
AND RFC IS NOT NULL
Your ON clause is in the wrong place;
You had the tbl2 alias inside the USING query instead of following it;
You do not need the tbl1 aliases before the destination column names in the UPDATE or INSERT;
You are updating the rfc column twice (I removed the second instance);
There was a strange T1 alias after the insert that should be inside the USING query; and
You can use a DATE literal rather than a string.
There may be other errors, as I do not have your tables to test the query.
MERGE INTO B69_TBL1 tbl1
USING (
SELECT T1.*,
ROW_NUMBER() OVER (PARTITION BY T1.rfc ORDER BY T1.rfc DESC) AS ENUMERADO
FROM B69_TBL2 t1
) tbl2
ON tbl1.rfc = tbl2.rfc
WHEN MATCHED THEN
UPDATE SET
id_alert = tbl2.id_con,
rfc = tbl2.rfc
WHEN NOT MATCHED THEN
INSERT (
id_alert,
alertype,
id_con,
rfc,
name_cont,
baja_logica,
last_update
) VALUES (
id_tbl1autt.nextval,
'1',
'1',
tbl2.id_con,
tbl2.rfc,
tbl2.name_cont,
'0',
DATE '2021-05-11'
)
WHERE ENUMERADO=1
AND RFC IS NOT NULL

Updating column1 in table1 only if matched column3 in table2

I want to update column1 in table1 only if the column2 in table1 match the column3 in table2.
I am trying to do using this query but I got an error that says that I am missing equal sign.
Can anyone can help?
update schema1.table1
set schema1.table1.column1
where schema1.table1.column2 = table2.column1
Your error says it all. You are not assigning any value to the column. Try to set the value using the equal = sign
You may try this:
update schema1.table1
set schema1.table1.column1 = //The value which you want to store
where schema1.table1.column2 = table2.column1
Try this query:
update schema1.table1 t1
set t1.column1 = (select t2.columnX from table2 t2
where t1.column2 = t2.column1)
where t1.column2 in (select column1 from table2)
As in the error message, you have missed an = and not assigning any value for schema1.table1.column1 in the query.
Try like this:
UPDATE schema1.table1
SET schema1.table1.column1 = <your_value>
WHERE schema1.table1.column2 = table2.column1;

Bulk update in Oracle gives error ORA-01779

I have a table which doesnot have any unique key column and I want to perform bulk update using self join.
Update
(
select t1.Col1 col1, t2.col1 col2
from table t1
inner join table t2 on <join condtn>
where <condtn>
)
Set col1 = col2
but as the table does not have unique key column, it gives error:
ORA-01779: cannot modify a column which maps to a non key-preserved
table.
Is there any solution other than adding unique constraint :)
You should be able to refactor the query to do a correlated update
UPDATE table t1
SET col1 = (SELECT col1
FROM table t2
WHERE t1.<<some column>> = t2.<<some column>>)
WHERE EXISTS( SELECT 1
FROM table t2
WHERE t1.<<some column>> = t2.<<some column>>)

Getting Error in query

update tablename set (col1,col2,col3) = (select col1,col2,col3 from tableName2 order by tablenmae2.col4) return error
Missing ). The query works fine if I remove the order by clause
ORDER BY is not allowed in a subquery within an UPDATE. So you get the error "Missing )" because the parser expects the subquery to end at the point that you have ORDER BY.
What is the ORDER BY intended to do?
What you probably have in mind is something like:
UPDATE TableName
SET (Col1, Col2, Col3) = (SELECT T2.Col1, T2.Col2, T2.Col3
FROM TableName2 AS T2
WHERE TableName.Col4 = T2.Col4
)
WHERE EXISTS(SELECT * FROM TableName2 AS T2 WHERE TableName.Col4 = T2.Col4);
This clumsy looking operation:
Grabs rows from TableName2 that match TableName on the value in Col4 and updates TableName with the values from the corresponding columns.
Ensures that only rows in TableName with a corresponding row in TableName2 are altered; if you drop the WHERE clause from the UPDATE, you replace the values in Col1, Col2, and Col3 with nulls if there are rows in TableName without a matching entry in TableName2.
Some DBMS also support an update-join notation to reduce the ghastliness of this notation.

Resources