Issue while updating column using Merge statement - sql

I need to update a column based on the inner join of two tables in oracle. I am using Merge as the inner join doesn't support in Update.
Query :
MERGE INTO FAC.CMC_PRSQ_SITE_QA PRSQ
USING(
SELECT PRPR_ID, ADDRESS_TYPE, PRAD_EFF_DT, PRAD_TERM_DT
FROM FSG_WRK.FSG_PRAD_PRSQ_TEMP
) TEMP
ON (TEMP.PRPR_ID = PRSQ.PRPR_ID
AND TEMP.ADDRESS_TYPE = PRSQ.PRAD_TYPE
AND TEMP.PRAD_EFF_DT = PRSQ.PRAD_EFF_DT)
WHEN MATCHED THEN UPDATE
SET PRSQ.PRSQ_NEXT_VER_DT = TEMP.PRAD_TERM_DT
WHERE TEMP.PRAD_TERM_DT > PRSQ.PRSQ_LAST_VER_DT ;
But getting below error :
ORA-30926: unable to get a stable set of rows in the source tables
ORA-06512: at line 2
30926. 00000 - "unable to get a stable set of rows in the source tables"
*Cause: A stable set of rows could not be got because of large dml
activity or a non-deterministic where clause.
*Action: Remove any non-deterministic where clauses and reissue the dml.
Also, please let me know if there is any other option to rewrite this query.

Does your source query (TEMP) return more than 1 instance of a row in your destination (PRSQ) that matches your merge conditions? You typically see this type of error when the source contains more than 1 instance of a row that needs to be updated in the destination. If it does you need to adjust either your source query or your merge condition to avoid trying to merge multiple rows from your source into the same row of your destination.

Related

Derby run sql script by redirecting standardIO

I have the following join.sql script:
connect 'jdbc:derby:barra';
show tables;
create table sp500_univ as
select a.*,b.* from (select * from LEFT_SIDE) as a
left join (select * from RIGHT_SIDE) as b
on a.cmp_flg = b.cmp_flg2;
disconnect;
exit;
which I run with the following command:
java org.apache.derby.tools.ij < join.sql
and get the following output:
java org.apache.derby.tools.ij < join.sql
ij version 10.14
ij> ij> TABLE_SCHEM |TABLE_NAME |REMARKS
------------------------------------------------------------------------
APP |LEFT_SIDE |
APP |RIGHT_SIDE |
2 rows selected
ij> > > > ERROR 42X01: Syntax error: Encountered "<EOF>" at line 4, column 25.
Issue the 'help' command for general information on IJ command syntax.
Any unrecognized commands are treated as potential SQL commands and executed directly.
Consult your DBMS server reference documentation for details of the SQL syntax supported by your server.
ij> ij>
If I run this sql right from the command line in IJ it works.
apparently when running from a file you can't create tables and load data from a select statement. You need to add the WITH NO DATA. The WITH DATA option has not yet been implemented. From Derby's documentation:
CREATE TABLE ... AS ...
With the alternate form of the CREATE TABLE statement, the column names and/or the
column data types can be specified by providing a query. The columns in the query
result are used as a model for creating the columns in the new table.
If no column names are specified for the new table, then all the columns in the
result of the query expression are used to create same-named columns in the new
table, of the corresponding data type(s). If one or more column names are specified
for the new table, then the same number of columns must be present in the result of
the query expression; the data types of those columns are used for the corresponding
columns of the new table.
The WITH NO DATA clause specifies that the data rows which result from evaluating the
query expression are not used; only the names and data types of the columns in the
query result are used. The WITH NO DATA clause must be specified; in a future
release, Derby may be modified to allow the WITH DATA clause to be provided, which
would indicate that the results of the query expression should be inserted into the
newly-created table. In the current release, however, only the WITH NO DATA form of t
the statement is accepted.

Using table variables in Oracle Stored Procedure

I have lots of experience with T-SQL (MS SQL Server).
There it is quite common to first select some set of records into a
table variable or say temp table t, and then work with this t
throughout the whole SP body using it just like a regular table
(for JOINS, sub-queries, etc.).
Now I am trying the same thing in Oracle but it's a pain.
I get errors all the way and it keeps saying
that it does not recognize my table (i.e. my table variable).
Error(28,7): PL/SQL: SQL Statement ignored
Error(30,28): PL/SQL: ORA-00942: table or view does not exist
I start thinking what at all is possible to do with this
table variable and what not (in the SP body) ?
I have this declaration:
TYPE V_CAMPAIGN_TYPE IS TABLE OF V_CAMPAIGN%ROWTYPE;
tc V_CAMPAIGN_TYPE;
What on Earth can I do with this tc now in my SP?!
This is what I am trying to do in the body of the SP.
UPDATE ( SELECT t1.STATUS_ID, t2.CAMPAIGN_ID
FROM V_CAMPAIGN t1
INNER JOIN tc t2 ON t1.CAMPAIGN_ID = t2.CAMPAIGN_ID
) z
SET z.STATUS_ID = 4;
V_CAMPAIGN is a DB view, tc is my table variable
Presumably you are trying to update a subset of the V_CAMPAIGN records.
While in SQLServer it may be useful to define a 'temporary' table containing the subset and then operate on that it isn't necessary in Oracle.
Simply update the table with the where clause you would have used to define the temp table.
E.g.
UPDATE v_campaign z
SET z.status_id = 4
WHERE z.column_name = 'a value'
AND z.status <> 4
I assume that the technique you are familiar with is to minimise the effect of read locks that are taken while selecting the data.
Oracle uses a different locking strategy so the technique is mostly unnecessary.
Echoing a comment above - tell us what you want to achieve in Oracle and you will get suggestions for the best way forward.

sql ORA-00900: Invalid SQL statement

please help
IF EXISTS(SELECT * FROM MERC_ADM_VERSION )then UPDATE MERC_ADM_VERSION SET
VER_VALEUR = 20150409 WHERE VER_CLE = 'MEAD' ELSE INSERT INTO MERC_ADM_VERSION
('VER_VALEUR', 'VER_CLE') VALUES (20150409, 'MEAD');
ORA-00900: Invalid SQL statement
Remove the single quotes from the columns in the insert statement.
Instead of
('VER_VALEUR', 'VER_CLE')
It should be
(VER_VALEUR, VER_CLE)
Your question is quite unclear as to what you are trying to do. However, my best interpretation is you are looking for an oracle merge statement. Below is an example based on assumptions I made on the little information you provided. You are most likely looking for a MERGE statement. This allows you to perform a single operation that can either update or insert based on your criteria.
Also, you appear to be using a date, but in number format. I did nothing to address this due to lack of any table definition. You may still have problems with it.
MERGE
INTO merc_adm_version TARGET -- The table you want to update/insert into
USING (SELECT 20150409 as ver_valeur, 'MEAD' as ver_cle FROM dual) SOURCE -- The source of the data
ON (TARGET.ver_cle = SOURCE.ver_cle) -- How to try and match records between source and target
WHEN MATCHED THEN UPDATE SET ver_valeur = 20150409 -- When there is a match, how to update
WHEN NOT MATCHED THEN INSERT (ver_cle, ver_valeur) -- When there is not a match, how to insert
VALUES ('MEAD', 20150409);

Why does DELETE FROM ... FROM ... not error out?

This bit within a stored proc is apparently valid sql:
DELETE TOP (#MaxRecords)
FROM Table
FROM Table B
INNER JOIN Table2 R ON B.fk = R.pk
WHERE R.Value < #DecVariable;
How can two FROM statements be put together and yet still be valid?
First of all TOP in delete syntax indicates that it is SQL Server.
It is perfect valid query, see DELETE:
FROM
An optional keyword that can be used between the DELETE keyword and the target table_or_view_name, or rowset_function_limited.
FROM table_source
Specifies an additional FROM clause. This Transact-SQL extension to DELETE allows specifying data from and deleting the
corresponding rows from the table in the first FROM clause.
This extension, specifying a join, can be used instead of a subquery in the WHERE clause to identify rows to be removed.
DELETE:
Object:

Update multiple values in an oracle table using values from an APEX collection

I am using APEX collections to store some values and pass them between pages in Oracle Application Express 4.2.3.
I would like to then perform an update statement on a table called "project" with the values from the collection.
My code so far is as follows:
update project
SET name=c.c002,
description=c.c007,
start_date=c.c004,
timeframe=c.c005,
status=c.c009
FROM
apex_collections c
WHERE
c.collection_name = 'PROJECT_DETAILS_COLLECTION'
and id = :p14_id;
where :p14_id is the value of a page item.
However, I am getting the following error:
ORA-00933: SQL command not properly ended
Anyone have any idea on how to approach this?
Thanks!
The UPDATE syntax you are using is not valid in Oracle; it does not allow you to use FROM in the way you are attempting.
The simplest way to do this in Oracle would with a subquery:
update project
set (name, description, start_date, timeframe, status) =
(select c.c002, c.c007, c.c004, c.c005, c.c009
FROM
apex_collections c
WHERE
c.collection_name = 'PROJECT_DETAILS_COLLECTION'
)
WHERE
id = :p14_id
;
Note that if the subquery returns no rows, the columns in the target table will be updated to NULL; this could be avoided by adding a similar EXISTS condition in the predicate for the update. It could also be avoided by using a MERGE statement instead of an UPDATE.
If the subquery returns multiple rows, the statement will throw an error. It looks like tthat should not be the case here.