This question already has an answer here:
Oracle: ON DUPLICATE KEY UPDATE [duplicate]
(1 answer)
Closed 9 years ago.
I've isolated my problem down to this code, which is giving me the error message "ORA-00933: SQL command not properly ended" for the on duplicate key line.
I'm trying to insert rows unless they have a duplicate key, in which case I want to update them instead. Something like insert...select and on duplicate key update.
I can see it must be a syntax problem, but I don't normally work with SQL so any help is appreciated.
insert into "tableB" ("col1", "col2")
select "tableA"."colX", "tableA"."colY"
from "tableA"
on duplicate key update "tableB"."col1" = "tableA"."colX";
I would look into using MERGE:
MERGE INTO tableB b
USING tableA a
ON (b.col1 = a.colX)
WHEN MATCHED THEN UPDATE SET b.col2 = a.colY
WHEN NOT MATCHED THEN INSERT( col1, col2 )
VALUES(a.colX, a.colY);
SQL Fiddle Demo
Note: this is presuming your key between the two tables is col1 and colx.
Related
This question already has answers here:
Update statement with inner join on Oracle
(15 answers)
syntax error with update query when join with some table
(1 answer)
Update with self-join
(3 answers)
Closed 3 years ago.
I have query which is working fine with MySQL, but if I execute it in Oracle database I get the following error:
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
MySQL query:
UPDATE T1
INNER JOIN T2 ON T1.UIDPK =T2.UIDFK
SET T1.C1=CONCAT('EMPTY_',T2.UID) WHERE T2.C1 IS NULL ;
Changed query for Oracle:
UPDATE
(
SELECT T1.C1 AS OLD ,CONCAT('EMPTY_',T2.UID) AS NEW FROM T1
INNER JOIN T2 ON T1.UIDPK= T2.UIDFK WHERE T1.C1 IS NULL
) T3
SET T3.OLD = T3.NEW
Above query is not working in Oracle database.
The update syntax you are using only works if your version of Oracle decides that the subquery aliased as T3 is an updatable view. You may use a correlated subquery instead of this:
UPDATE T1
SET C1 = (SELECT CONCAT('EMPTY_', T2.UID) FROM T2
WHERE T1.UIDPK = T2.UIDFK AND T2.C1 IS NULL);
You can also check if you have indexes on T2.UIDFK and T1.UIDP columns.
If not, create them and your update might work after that.
Not having indexes on those columns would result in this error / restriction.
Note:
You can always delete those indexes after this update, although it would seem that those are intended as a foreign key and a primary key column, respectively, and it's always good to have created FK and PK constraints on such columns (which would also lead to existing indexes on those columns).
This question already has answers here:
Can you SELECT everything, but 1 or 2 fields, without writer's cramp?
(12 answers)
Closed 8 years ago.
I have a table with many columns (20 or 25) and i want to build an insert statement on it, using select and generating another primary key
The simple soulution will be:
INSERT INTO myTable
SELECT mySeq.nextVal PRIMARY_KEY, COLUMN2, COLUMN3, COLUMN4...
FROM myTable
WHERE PRIMARY_KEY = 1
Since my table have many columns, there is a way to say "i give you primary key, and ALL the other columns are the same" without explain them?
Like:
INSERT INTO myTable
SELECT mySeq.nextVal m.* /* Sure this not work because i get again PRIMARY_KEY column*/
FROM myTable m
WHERE PRIMARY_KEY = 1
There is no way to specify something like SELECT * EXCEPT aColumn, you will have to write them manually as you already did, sorry.
Actually, you could do a subquery that select column from table info then query that subquery but that make non-sense to me.
If your table contains so many column that it is a pain to write them all, then you might want to re-design your database and split your table in multiple tables.
This question already has answers here:
Oracle: Updating a table column using ROWNUM in conjunction with ORDER BY clause
(4 answers)
Closed 8 years ago.
Oracle 10g
I have a table that has a compound key, which I want to replace with a singular key. So I've added an id column. Now I need a single update statement update existing data.
Example:
MyTable(NewID,CMP_Key1,CMP_Key2)
NULL,1,1
NULL,1,2
NULL,2,2
NULL,2,2
Needs to be updated to:
1,1,1
2,1,2
3,2,2
4,2,2
What I've tried so far:
Update MyTable SET NewID = (SELECT ROWNUM FROM DUAL);
Which doesn't work. This will set them all to 1.
You can just do:
update MyTable set NewId = rownum;
SQL Fiddle.
But presumably you'll want to increment the NewId column for future inserts, quite likely with a sequence and maybe a trigger. You'd need to make the sequence start with the highest value you set manually (i.e. the number of rows in the table when you run the update), so you might as well just use the sequence here:
create sequence MyTableSeq;
update MyTable set NewId = MyTableSeq.nextval;
SQL Fiddle.
Both assume this is a purely synthetic key and you don't want to impose any ordering as it's generated.
Try this one
merge into mytable t
using (select t.rowid rid, t.rownum id from mytable t) s
on (t.rowid = s.rid)
when matched then update set
t.newid= s.id;
commit;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Insert statement that checks for duplicate before insert
I'd like to check if a building id exists in the issue log table using the foreign key b_id. And if it does not exist then i would like to add it to the issue log table.
I have the code below but this only checks to see which buildings are not in the issue log table...how can i do the insert? Thanks a lot. I'm using SQL Server 2008.
select b.b_id from building
where not exists(select b.b_id from issue_log as l where b._id = l.b_id)
Something like this?
INSERT INTO issue_log(b_id)
SELECT b.b_id FROM building b
WHERE NOT EXISTS(SELECT l.b_id FROM issue_log AS l WHERE b.b_id = l.b_id)
Either use IF NOT EXISTS or if you'd like to potentially do an update use MERGE which will make the decision whether to do an insert, update, or optionally a delete based on rules you set in the statment. It's quite useful once you get the syntax down
MSDN: http://technet.microsoft.com/en-us/library/bb510625(v=sql.105).aspx
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to get the primary key of the last row inserted into the table
In SQL Server 2008, I have a stored proc that inserts in a table which includes identity column for ID. I need to return the ID of record to my application so that I can use it for related tables.
How can I get generated ID by SQL?
Use select Scope_Identity() to get the ID
A separate SQL statement
SELECT SCOPE_IDENTITY()
Or the OUTPUT clause
INSERT MyTable (...=
OUTPUT INSERTED.KeyCol
VALUES (...) --Or SELECT ... FROM Another table)
There are multiple options that are a bit different:
SCOPE_IDENTITY() - that's what I would use
IDENT_CURRENT( 'table_name' )
##IDENTITY