Convert MySQL update SQL statement to Oracle update statement [duplicate] - sql

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).

Related

"WITH AS" Working in Postgres but not in H2 dabatabse

I am writing a single query to insert data into 2 tables using "WITH AS". The query works fine on Postgres but on H2 database it is throwing syntax error.
I have 2 tables.
Table 1 has 2 columns -- a Primary Key table1_ID and a table1_value column.
Table 2 has 3 columns -- a PK table2_Id and table2_value and table1_id as Foreign key.
The query is like this:
WITH ins as (
INSERT INTO table_1 (table1_value) VALUES ("table1_value")
RETURNING table1_ID as t1_id
)
INSERT INTO table_2 (table2_value, tab1_id) VALUES ("table2_value", (SELECT t1_id FROM ins));
This query works fine on Postgres but on H2 DB it throws syntax error with a message
"; expected "(, WITH, SELECT, FROM"; SQL statement
hadatabase reference link:
http://www.h2database.com/html/advanced.html#recursive_queries
http://www.h2database.com/html/commands.html?highlight=insert&search=insert#firstFound
see Compatibility section: https://www.postgresql.org/docs/current/sql-insert.html
INSERT conforms to the SQL standard, except that the RETURNING clause
is a PostgreSQL extension, as is the ability to use WITH with INSERT,
and the ability to specify an alternative action with ON CONFLICT.
Also, the case in which a column name list is omitted, but not all the
columns are filled from the VALUES clause or query, is disallowed by
the standard.

Having error while executing postgresqlquery

I am facing error in my query while deleting row from two table which have same primary and foreign key :
Query:
DELETE FROM TABLE1 INNER JOIN TABLE2 ON (TABLE1.id=TABLE2.id) WHERE TABLE1.id='21306';
ERROR: syntax error at or near "INNER"
Using rdbms POSTGRESQL
You can't have a join in the from clause of a delete in Postgresql (although this is supported in SQL Server). Any additional table that you want to participate in the delete must be added to the using clause. Try this instead:
DELETE FROM TABLE1
USING TABLE2
WHERE (TABLE1.id=TABLE2.id) AND TABLE1.id='21306';

Drop Column from Selection After Join

I am trying to drop a number of columns after joining three tables. I came across a very useful SO post: SQL exclude a column using SELECT * [except columnA] FROM tableA?
However I can't get the solution I found therein (the top answer) to work for my case;
joining multiple tables, and want to drop the key that is used for the second and third tables, as well as some other columns.
Here is a simplified case whereby I'm just attempting to drop the key of the second table, which comes out as mykey_2:
SELECT * INTO Temptable
FROM
table_1 INNER JOIN table_2 ON
table_1.mykey=table_2.mykey INNER JOIN
table_3 ON table_1.mykey= table_3.mykey
WHERE table_1.A_FIELD = 'Some Selection'
ALTER TABLE Temptable
DROP COLUMN table_2.mykey
GO
SELECT * FROM Temptable
DROP TABLE Temptable
My console is giving me the error "ORA-00933: SQL command not properly ended".
How can I achieve this dropping of specific columns from the final selection?
For information I'm querying an Oracle database using Toad.

Oracle 10g update table i from table 2 column join error

I have the following Oracle 10g sql which to me looks about right:
update ( select OLD1.TC_CUSTOMER_NUMBER,NEW1.PRD_CUST_NUMBER
FROM TBYC84_PROFILE_ACCOUNT OLD1,
TMP_PRD_KEP NEW1
WHERE
OLD1.TC_CUSTOMER_NUMBER = NEW1.KEP_CUST_NUMBER )
SET
TC_CUSTOMER_NUMBER = PRD_CUST_NUMBER
But i am getting this error when i run the script:
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.
I have done done some research on this error but not quite sure how to remedy.
So my question is, how can i fix this or is there a better way to write the update sql?
Any help would be appreciated.
many thanks
UPDATE
I have changed the update sql to this:
update
TBYC84_PROFILE_ACCOUNT PA
set
(
PA.TC_CUSTOMER_NUMBER
) = (
select
TPK.PRD_CUST_NUMBER
from
TMP_PRD_KEP TPK
where
TPK.KEP_CUST_NUMBER = PA.TC_CUSTOMER_NUMBER
)
Now this has updated the TBYC84_PROFILE_ACCOUNT table AND nulled out the TC_CUSTOMER_NUMBER
column.
Why did it do this?
There may be more than one row in the TBYC84_PROFILE_ACCOUNT.TC_CUSTOMER_NUMBER
that has the same account number but for different user_id's.
Please can anyone assist in helping me resolve this.
All I need to to is update the TBYC84_PROFILE_ACCOUNT.TC_CUSTOMER_NUMBER to the one that is xrefed in the TMP_PRD_KEP, surely this is not impossible.
many thanks
For an UPDATE statement, all the columns that are updated must be extracted from a key-preserved table.
Also:
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.
Here.
In this case, TBYC84_PROFILE_ACCOUNT is being updated. So, it must be key-preserved in the view's subquery. Currently it is not. It must be changed in a way that it becomes key-preserved by involving primary or unique columns in the where clause. If not possible, you should try to update the base table instead.
UPDATE
In case of the table update problem, assuming the subquery returns at most one distinct value for the TC_CUSTOMER_NUMBER column, the reason you get NULLs is that all records are being updated even if they do not have any matching records in the TMP_PRD_KEP table. So, the parent update statement needs to be fitted with a where clause:
update
TBYC84_PROFILE_ACCOUNT PA
set
(
PA.TC_CUSTOMER_NUMBER
) = (
select
TPK.PRD_CUST_NUMBER
from
TMP_PRD_KEP TPK
where
TPK.KEP_CUST_NUMBER = PA.TC_CUSTOMER_NUMBER
)
where exists(select *
from TMP_PRD_KEP TPK
where TPK.KEP_CUST_NUMBER = PA.TC_CUSTOMER_NUMBER)
;
Create a index on the columns used in your where clause predicates. That should solve your problem.

SQL command not properly ended, on an insert/on duplicate [duplicate]

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.