Update "varchar2" column only if new record found - oracle

I'm trying to develop simple code for my project.
Where I am supposed to update table books.PUBLISHER. Here in PUBLISHER column we already have below values 'abc; pqr' and I want to update it with 'pqr; xyz' so my expected output will be 'abc; pqr; xyz'.
update books SET PUBLISHER = PUBLISHER || '; ' ||'pqr; xyz'
where id = 1 and PUBLISHER NOT LIKE '%pqr; xyz%';
My expected output will be 'abc; pqr; xyz'.

Your current value of publisher contains the string pqr. Your requirement shows you don't want to duplicate that value. By appending your proposed solution will duplicate the pqr value.
You can avoid the duplication with a replace():
update books
SET PUBLISHER = replace(PUBLISHER, 'pqr', 'pqr; xyz')
where id = 1
and PUBLISHER NOT LIKE '%pqr; xyz%';
This will substitute pqr; xyz wherever pqr appears in the publisher column.

The following update statement should do the job:
update books b
set publisher =
(select listagg(publisher_part, '; ') within group(order by publisher_part)
from (select regexp_substr(bb.publisher, '[a-z]+', 1, level) as publisher_part
from (select publisher from books where id = b.id) bb
connect by regexp_substr(bb.publisher, '[a-z]+', 1, level) is not null
union
select 'lmn' as publisher_part --> your new "publisher" pattern
from dual))
where id = 1; --> id to update
The inner select (select regexp...) scatters your publisher column in separate results
abc
pqr
xyz
...
After that, the new value lmnis added by union select from dual and finally the result is aggregated in the previous format by listagg.
Better solution, as APC already recommended, is a normalization of your table.

Related

I have a SQL table which consists of employee details and I have 3 update statements that works separately and want to merge it to 1 single starment

I have a SQL table which consists of employee details and my problem is I have three separate updates statements and want to club it together so that I can create a procedure which updates the table in such a way that it shows the salary including the bonus and the latest salary date which makes use of another bonus table
1]update employee_1 set employee_1.salary=(select sum(bonus_1.bonus_amount)from bonus_1 where employee_1.employee_id=bonus_1.employee_id GROUP by bonus_1.employee_id);
2]update employee_1 set employee_1.last_bonus_date=(select max(bonus_1.bonus_date)from bonus_1 where employee_1.employee_id=bonus_1.employee_id GROUP by bonus_1.employee_id);
3]update employee_1 set salary=salary+old_salary;
Basically need to combine these update statements so that I can use it in a procedure
You should've posted tables' description and sample data that illustrate the problem.
To me, it looks as if a single MERGE statement does the whole job (i.e. combines your 3 queries into 1):
merge into employee_1 a
using bonus_1 b
on (a.employee_id = b.employee_id)
when matched then update set
a.salary = a.salary + b.bonus_amount,
a.last_bonus_date = b.bonus_date;
You can use a MERGE statement and perform the aggregation in the USING clause:
MERGE INTO employee_1 e
USING (
SELECT employee_id,
SUM(bonus_amount) AS total_bonus,
MAX(bonus_date) AS last_date
FROM bonus_1
GROUP BY employee_id
) b
ON (e.employee_id = b.employee_id)
WHEN MATCHED THEN
UPDATE
SET salary = e.salary + b.total_bonus,
last_bonus_date = b.last_date;

can i set up an SSRS report where users input parameters to a table

I have an oracle query that uses a created table as part of the code. Every time I need to run a report I delete current data and import the new data I receive. This is one column of id's. I need to create a report on SSRS in which the user can input this data into said table as a parameter. I have designed a simple report that they can enter some of the id's into a parameter, but there may be times when they need to enter in a few thousand id's, and the report already runs long. Here is what the SSRS code currently says:
select distinct n.id, n.notes
from notes n
join (
select max(seq_num) as seqnum, id from notes group by id) maxresults
on n.id = maxresults.ID
where n.seq_num = maxresults.seqnum
and n.id in (#MyParam)
Is there a way to have MyParam insert data into a table I would join called My_ID, joining as Join My_Id id on n.id = id.id
I do not have permissions to create functions or procedures in the database.
Thank you
You may try the trick with MATERIALIZE hint which normally forces Oracle to create a temporary table :
WITH cte1 AS
( SELECT /*+ MATERIALIZE */ 1 as id FROM DUAL
UNION ALL
SELECT 2 DUAL
)
SELECT a.*
FROM table1 a
INNER JOIN cte1 b ON b.id = a.id

oracle update first 4 characters with column value from another table

This is the query I am using to update a column with value from another table :
UPDATE SPICES A
SET A.description = (SELECT CODE
FROM CHILLY B
WHERE SUBSTR(A.description,1,4) = TRIM(B.desc123))
WHERE EXISTS (SELECT 1
FROM CHILLY B
WHERE SUBSTR(A.description,1,4) = TRIM(B.desc123));
But this is not what I want . The requirement is to update the first 4 characters of description with the new value (CODE) from table CHILLY.
Any suggestions? new to writing queries.
You should use a concatenation operator for adding the rest of description
UPDATE SPICES A
SET A.description = (SELECT CODE
FROM CHILLY B
WHERE SUBSTR(A.description,1,4) = TRIM(B.desc123)) || SUSBSTR(A.description, 5, 255 )
WHERE EXISTS (SELECT 1
FROM CHILLY B
WHERE SUBSTR(A.description,1,4) = TRIM(B.desc123));

Insert and Update in Single Table using Merge?

I want to Update or insert Oracle Table based on condition.
Consider that in the table have 2 columns (like id and name), one or more name having the same id. In this situation i want to check the id and name (like 1,'Buyer'), if its exist then i want to update name 'Buyer' to 'Service Provider'. otherwise i want to just insert the values (1,'Service Provider').
I tried this through Merge, but it's update all the name column of id 1 to 'Service Provider'.
merge into party_type p
using (select 1 party_id, 'Buyer' party_type from dual) t
on (t.party_id = p.party_id)
when matched then
update set party_type = 'Service Provider'
when not matched then
insert (party_id,party_type) values(1,'Service Provider');
Available data in the table:
1 Buyer
1 Buyer Agent
1 Vendor
Thanks in advance.
you need to join on both columns
merge into party_type p
using (select 1 party_id, 'Buyer' party_type from dual) t
on (t.party_id = p.party_id and t.party_type = p.party_type)
when matched then
update set party_type = 'Service Provider'
when not matched then
insert (party_id,party_type) values(1,'Service Provider');

Oracle-update multiple row value where the the id column equals specific values

I am new in oracle and I want to update multiple row value where the column id = 1 , 2.
I tried this :
update Tester
set employee_phone_number = ( 0789456123,0789456321)
where employee_id in (1,2);
but it gives me "missing right parenthesis"
any help please and thanks in advance.
Another approach:
merge into
tester
using (
select 1 id,'0123456785' employee_phone_number from dual union all
select 2 id,'0123456786' employee_phone_number from dual) new_values
on (
tester.id = new_values.id)
when matched then update
set employee_phone_number = new_values.employee_phone_number;
More words, but allows the values to be specified in only one place and extends to allow inserts where the id does not already exist.
http://sqlfiddle.com/#!4/8fc86/3
Try this instead:
update Tester
set employee_phone_number = CASE WHEN employee_id = 1 THEN 0789456123
WHEN employee_id = 2 THEN 0789456321
END
where employee_id in (1,2);

Resources