Updating rows with same id and name in oracle database - oracle

i have a large data inside a table two employees have same name and same id in accident so i want to update one of the two employee so it becomes hard to me do you have any answer or solution
when i write this it updates the two rows
update EMPLOYEE
set id = 2 where Name='ahmed' and id=1

you can use ROWNUM
update EMPLOYEE
set id = 2 where Name='ahmed' and id=1 and ROWNUM = 1

Related

How to create an Oracle trigger that updates another table?

Imagine two tables:
TableA with order headers and
TableB with order items
Uniqe link between the tables = ID
I need (I think) two triggers:
When a (date) field TableA.Q is updated, all (date) field(s) on TableB.Q should be updated with the same value as TableA.Q where TableA.ID = TableB.ID.
When a record of TableB is inserted or updated, field TableB.Q should be updated with TableA.Q where TableA.ID = TableB.ID
How to do this?
Oracle version we use is 11gR2.

How to carry out deletions from 2 tables, at the same time in Oracle database?

Within my Oracle database I wish to delete rows from 2 different tables.
The issue is that, if I delete rows from KENNEL first, then the rows I want to delete in DOG table cannot be found to delete.
Below are my SQL statements to delete from the two tables.
DELETE FROM KENNEL WHERE COUNTRY_ID IS NULL;
DELETE FROM DOG WHERE ID IN (SELECT DOG_ID FROM KENNEL WHERE COUNTRY_ID IS NULL);
How can I fix this so that the 2 deletes happen at the same time, and ensure that rows from both the tables are removed?
Note: I cannot delete from DOG then KENNEL as KENNEL is the child record that must be deleted first.
I would do this set of deletes as something like:
-- delete rows from child table first
DELETE FROM KENNEL WHERE COUNTRY_ID IS NULL;
-- now delete any parent rows that don't have any child records
DELETE FROM DOG WHERE ID not exists (SELECT DOG_ID FROM KENNEL);
Doing it this way means that if not all the country_ids for a given dog_id in the kennel table were null, you wouldn't attempt to delete the parent record - it would error if you tried.
UPDATE DOG SET [some non-key field] = 'XXX' WHERE ID IN (SELECT DOG_ID FROM KENNEL WHERE COUNTRY_ID IS NULL);
DELETE FROM KENNEL WHERE COUNTRY_ID IS NULL;
DELETE FROM DOG WHERE [non-key field] = 'XXX';

Update with 2 joins

I'm trying to update data in 2 distinct tables in the same query with the following code:
UPDATE (SELECT s.passNumb, a.hour, a.minute, p.number, s.situation
FROM passwords s
JOIN atend a ON s.passNumb = a.passNumb
JOIN points p ON a.number = p.number
WHERE s.passNumb = 1 AND
p.number = 1)
SET a.hour = TO_CHAR(SYSDATE, 'HH24'),
a.minute = TO_CHAR(SYSDATE, 'MI'),
s.situation = 'F';
But I'm getting this error: Cannot modify a column which maps to a non key-preserved table. What am I doing wrong?
A view with a join (or an inline view containing a join in your case) must meet the following conditions to be updatable:
https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_8004.htm
If you want a join view to be updatable, then all of the following
conditions must be true:
The DML statement must affect only one table underlying the join.
For an INSERT statement, the view must not be created WITH CHECK
OPTION, and all columns into which values are inserted must come from
a key-preserved table. A key-preserved table is one for which every
primary key or unique key value in the base table is also unique in
the join view.
For an UPDATE statement, the view must not be created WITH CHECK
OPTION, and all columns updated must be extracted from a key-preserved
table.
The first condition is rather obvious: The DML statement must affect only one table underlying the join.
But what does it mean: "key preserved table" ?
A key-preserved table is one for which every primary key or unique
key value in the base table is also unique in the join view.
The key preserved table means that each row from this table will appear at most once in the result of a view.
Consider a simple example:
CREATE TABLE users(
user_id int primary key,
user_name varchar(100),
age int
);
insert into users values(1,'Tom', 22);
CREATE TABLE emails(
user_id int,
email varchar(100)
);
Insert into emails values( 1, 'tom#somedomain.com' );
Insert into emails values( 1, 'tom#www.example.org' );
commit;
And a join:
SELECT *
FROM users u
JOIN emails e ON u.user_id = e.user_id;
USER_ID USER_NAME AGE USER_ID EMAIL
---------- --------------- ---------- ---------- --------------------
1 Tom 22 1 tom#somedomain.com
1 Tom 22 1 tom#www.example.org
If you look at a result of this join, it is apparent that:
user_id, user_name and age come from non-key preserved table
email comes from key-preserved table
And now: this update is acceptable, because it updates a key preserved column (table) in this join:
UPDATE (
SELECT * FROM users u
JOIN emails e ON u.user_id = e.user_id
)
SET email = email || '.it' ;
USER_ID USER_NAME AGE USER_ID EMAIL
---------- --------------- ---------- ---------- -------------------------
1 Tom 22 1 tom#somedomain.com.it
1 Tom 22 1 tom#www.example.org.it
But this update cannot be done, since it touches a column from non-key preserved table:
UPDATE (
SELECT * FROM users u
JOIN emails e ON u.user_id = e.user_id
)
SET age = age + 2;
SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table
01779. 00000 - "cannot modify a column which maps to a non key-preserved table"
*Cause: An attempt was made to insert or update columns of a join view which
map to a non-key-preserved table.
*Action: Modify the underlying base tables directly.
If you think a while .... Tom appears 2 times in the result of the join (but there is only one Tom in the users table).
When we are trying to update age = age + 2 in this join, then what should be a result of this update ?
Should Tom be updated only once ?
Should Tom be 22+2 = 24 years old after this update ?
Or maybe Tom should be updated twice (since it appears twice in the result of the join) so it should be 22 + 2 + 2 = 26 years old.
Another example - please tell me what should be an outcome of this update?:
UPDATE ( ....our join ... ) SET age = length( email );
There are very difficult questions :)
And because of this Oracle prevents from updating non-key preserved tables.
The error message gives this hint:
*Action: Modify the underlying base tables directly.
This means that we must update this table directly, using a separate UPDATE command:
UPDATE users SET age = age + 2

Update query resulting wrongly

I have table called company_emp. In that table I have 6 columns related to employees:
empid
ename
dob
doj, ...
I have another table called bday. In that I have only 2 columns; empid and dob.
I have this query:
select empid, dob
from company_emp
where dob like '01/05/2011'
It shows some list of employees.
In the same way I have queried with table bday it listed some employees.
Now I want to update the company_emp table for employees who have date '01/05/2011'.
I have tried a query like this:
update company_name a
set dob = (select dob from bday b
where b.empid=a.empid
and to_char(a.dob,'dd/mm/yyyy') = '01/05/2011'}
Then all the records in that row becoming null. How can I fix this query?
You're updating every row in the company_name/emp table.
You can fix that with a correlated subquery to make sure the row exists, or more efficiently by placing a primary or unique key on bday.empid and querying:
update (
select c.dob to_dob,
d.dob from_dob
from company_emp c join dob d on (c.empid = d.empid)
where d.dob = date '2011-05-01')
set to_dob = from_dob
Syntax not tested.

Validate person without value in date column

I have a table with several employees. They have the following columns empid,datecolumn1,is_valid.
Very few employees have a more than one record in the table. If an employee has more than one record in the table I would like to 'invalidate' one of the records on the following condition:
1. If a employee has more than one record in the table then the record with no value in the datecolumn1 is valid (update is_valid to 1) and the record with value in datecolumn1 is not valid (update is_valid to 0).
How do I accomplish this?
As Ben points out, you've stated that if datecolumn1 is NULL you want the is_valid column to be set to both 0 and 1. Assuming you fix that, you may need to adjust this CASE statement depending on which way you decide is correct.
UPDATE employees
SET is_valid = (CASE WHEN datecolumn1 IS NULL
THEN 1
ELSE 0
END)
WHERE empid IN (SELECT e.empid
FROM employees e
GROUP BY emempid
HAVING COUNT(*) > 1)
create a staging table, and fill it by a SELECT on the original table with a GROUP BY employee Id (or whatever your unique identifier is). Create a second staging table and fill it by SELECTING on the original table and excluding all rows that match rows in your grouped table. Now you have a table that contains only those people with multiple rows. From your original table, set is_valid to 0 on all rows that match employee id with the second staging table and also have no datecolumn1 (or perhaps that also have a datecolumn1 - your question as of this writing is a bit unclear.) and is_valid to 1 on the others. Once done with that, delete the staging tables, and you should have what you need.
You could also do this with a single more complicated multiselect call, but I find it helpful to use staging tables when things get complicated.

Resources