Oracle update based on query - sql

I've got the folloing tables:rashodz, naklrashodz, transport, trans_task_load, shipment_plan.
What I need is to update tbl:rashodz.id_ship whith tbl:shipment_plan.id_ship as follows
rashodz.id2 = shipment_plan.id2
and rashodz.nsthet = naklrashodz.nsthet
and naklrashodz.nsthet = trans_task_load.nsthet
and shipment_plan.idts = trans_task_load.idts
Just do not have an idea how to do it.
When there are two tables under consideration there is no problem, but how to do it when multiple tables are involved?
I would appreciate any help.

Is the code snippet you give the condition for the update?
Then how about:
update rashodz r
set id_ship = nvl(
(select id_ship
from shipment_plan,
naklrashodz,
transport,
trans_task_load
where r.id2 = shipment_plan.id2
and r.nsthet = naklrashod.nsthet
and naklrashod.nsthet = trans_task_load.nsthet
and shipment_plan.idts = trans_task_load.idts
), id_ship)
The purpose of the NVL in this case is that if there is no match, id_ship remains unchanged from its original value.

Related

Problem in PostgreSQL (ERROR: relation "a" does not exist)

SQL query (PostgreSQL) looks like that:
UPDATE a
SET "PropertyAddress" = COALESCE(a."PropertyAddress", b."PropertyAddress")
FROM "NashvilleHousingData" a
INNER JOIN "NashvilleHousingData" b
ON a."ParcelID" = b."ParcelID"
AND a."UniqueID" <> b."UniqueID"
WHERE a."PropertyAddress" IS NULL;
And the error is relation "a" does not exist
I tried other advices about the notion in the code public or scheme, but it still doesn't work. Please, help
This is not how Postgres handles updates with more than one table. You don't repeat the table in the from clause:
UPDATE "NashvilleHousingData" nhd
SET "PropertyAddress" = COALESCE(nhd."PropertyAddress", nhd2."PropertyAddress")
FROM "NashvilleHousingData" nhd2
WHERE nhd2."ParcelID" = nhd."ParcelID" AND
nhd2."UniqueID" <> nhd."UniqueID"
WHERE nhd."PropertyAddress" IS NULL;
Also, the COALESCE() is superfluous because the value is known to be NULL:
SET "PropertyAddress" = nhd2."PropertyAddress"

ORA-38104 when trying to update my table using merge

I have a stored procedure in which I want to update some columns, so I wrote below code:
PROCEDURE UPDATE_MST_INFO_BKC (
P_SAPID IN NVARCHAR2
) AS
BEGIN
MERGE INTO tbl_ipcolo_billing_mst I
USING (
SELECT
R4G_STATE, -- poilitical state name
R4G_STATECODE, -- poilitical state code
CIRCLE, -- city name
NE_ID,
LATITUDE,
LONGITUDE,
SAP_ID
FROM
R4G_OSP.ENODEB
WHERE
SAP_ID = P_SAPID
AND ROWNUM = 1
)
O ON ( I.SAP_ID = O.SAP_ID )
WHEN MATCHED THEN
UPDATE SET I.POLITICAL_STATE_NAME = O.R4G_STATE,
I.POLITICAL_STATE_CODE = O.R4G_STATECODE,
I.CITY_NAME = O.CIRCLE,
I.NEID = O.NE_ID,
I.FACILITY_LATITUDE = O.LATITUDE,
I.FACILITY_LONGITUDE = O.LONGITUDE,
I.SAP_ID = O.SAP_ID;
END UPDATE_MST_INFO_BKC;
But it is giving me error as
ORA-38104: Columns referenced in the ON Clause cannot be updated: "I"."SAP_ID"
What am I doing wrong?
You are joining the source to destination tables on I.SAP_ID = O.SAP_ID and then, when matched, are trying to update them and set I.SAP_ID = O.SAP_ID. You cannot update the columns used in the join ... and why would you want to as you have already determined that the values are equal.
Just remove the last line of the UPDATE:
...
O ON ( I.SAP_ID = O.SAP_ID )
WHEN MATCHED THEN
UPDATE SET I.POLITICAL_STATE_NAME = O.R4G_STATE,
I.POLITICAL_STATE_CODE = O.R4G_STATECODE,
I.CITY_NAME = O.CIRCLE,
I.NEID = O.NE_ID,
I.FACILITY_LATITUDE = O.LATITUDE,
I.FACILITY_LONGITUDE = O.LONGITUDE;
The error message tells you what the problem is - a MERGE statement cannot update the columns used in the ON clause - and even tells you what column is the problem: "I"."SAP_ID".
So Oracle hurls ORA-38104 because of this line in your WHEN MATCHED branch
I.SAP_ID = O.SAP_ID;
Remove it and your problem disappears. Fortunately the line is unnecessary: I.SAP_ID already equals O.SAP_ID, otherwise the record wouldn't go down the MATCHED branch.
The reason why is quite straightforward: transactional consistency. The MERGE statement operates over a set of records defined by the USING clause and the ON clause. Updating the columns used in the ON clause threatens the integrity of that set, and so Oracle forbids it.

change where condition based on column value

I faced the following requirement. The following query is called by a procedure. The value p_pac_code is the input parameter of the procedure.
The requirement is the query should have an additional condition sp_sbsp.SUBSPCLTY_CODE!='C430 if the p_pac_code value is '008'.
For any other p_pac_code value, it should run as it is below. Is there way to do this by adding an additional condition in the WHERE clause?
As for now, I have done this using IF.....ELSE using the query two times separately depending on p_pac_code value. But I am required to find a way to do with just adding a condition to this single query.
SELECT ptg.group_cid
FROM PRVDR_TYPE_X_SPCLTY_SUBSPCLTY ptxss,
PT_X_SP_SSP_STATUS pxsst ,
pt_sp_ssp_x_group ptg,
group_x_group_store gg,
specialty_subspecialty sp_sbsp,
treatment_type tt,
provider_type pt
WHERE
pt.PRVDR_TYPE_CODE = ptxss.PRVDR_TYPE_CODE
AND tt.TRTMNT_TYPE_CODE = pxsst.TRTMNT_TYPE_CODE
AND ptxss.PRVDR_TYPE_X_SPCLTY_SID = pxsst.PRVDR_TYPE_X_SPCLTY_SID
AND tt.TRTMNT_TYPE_CODE = p_pac_code
AND TRUNC(SYSDATE) BETWEEN TRUNC(PXSST.FROM_DATE) AND TRUNC(PXSST.TO_DATE)
AND ptg.prvdr_type_code =ptxss.prvdr_type_code
AND ptg.spclty_subspclty_sid = ptxss.spclty_subspclty_sid
AND ptxss.spclty_subspclty_sid = sp_sbsp.spclty_subspclty_sid
AND ptg.spclty_subspclty_sid = sp_sbsp.spclty_subspclty_sid
AND ptg.status_cid = 2
AND ptg.group_cid = gg.group_cid
AND gg.group_store_cid = 16
AND gg.status_cid = 2;
Thanks in advance.
You can simply add a condition like this:
... and (
( sp_sbsp.SUBSPCLTY_CODE!='C430' and p_pac_code = '008')
OR
NVL(p_pac_code, '-') != '008'
)
This can be re-written in different ways, this one is quite self-explanatory
Just add:
AND NOT ( NVL( sp_sbsp.SUBSPCLTY_CODE, 'x' ) = 'C430'
AND NVL( p_pac_code value, 'x' ) = '008' )
to the where clause.
The NVL function is used so that it will match NULL values (if they exist in your data); otherwise, even though NULL does not match C430 you will still find that NULL = 'C430' and NULL <> 'C430' and NOT( NULL = 'C430' ) will all return false.
Quite easy. Add the following condition:
AND (sp_sbsp.SUBSPCLTY_CODE != 'C430' OR p_pac_code value != '008')
(don't forget the parenthesis)
Just sharing
SELECT ptg.group_cid
FROM PRVDR_TYPE_X_SPCLTY_SUBSPCLTY ptxss
WHERE
pt.PRVDR_TYPE_CODE = ptxss.PRVDR_TYPE_CODE
&&((tt.TRTMNT_TYPE_CODE = pxsst.TRTMNT_TYPE_CODE)
or (tt.TRTMNT_TYPE_CODE = pxsst.TRTMNT_TYPE_CODE))
just use the parenthesis to specify where the conditionmust implement.

Selects in Joins

I have query
UPDATE THD
SET RepostFlag = 'Y'
,RunListNoRetroPolicyPrepay = ?
,RetroObject = ?
FROM TranHead AS THD
JOIN (
SELECT CustPolicyNo AS CustPolicyNo
,MIN(PremPeriod) AS PremPeriod
FROM TranHead
WHERE RepostFlag = 'Y'
AND PayoutTypeNo = ?
GROUP BY CustPolicyNo
) AS THDToBeReposted ON THD.CustPolicyNo = THDToBeReposted.CustPolicyNo
WHERE THD.RepostFlag = 'N'
AND THD.PremPeriod > THDToBeReposted.PremPeriod
fails in H2 with following message
Table "THD" not found;
I looked at http://www.h2database.com/html/grammar.html#table_expression to see if H2 supports selects in join. It appears it does. Maybe I am missing something when looking at the grammar, but it seems to me that the query should work in H2.
Anyone see what is wrong?
Thanks.
I don't believe FROM is allowed in the UPDATE syntax.
You can't update an alias, you need to have the table name specified.
Complementary to other answers, JOIN (just as FROM) is not allowed in UPDATE for H2. It would be allowed in a sub query.
Essentially, stick to the basic syntax:
UPDATE SomeTable as SomeAlias
SET SomeField = ?
WHERE (%GoWild%)
Whether or not you need the alias is up to your where clause.
Reference: http://www.h2database.com/html/grammar.html#update

UPDATE is not allowed because the statement updates view "table_name" which participates in a join and has an INSTEAD OF UPDATE trigger

I am getting the following error while executing the following query in an Stored Procedure. Could anyone help in finding the fault?
UPDATE is not allowed because the statement updates view "sup_item" which participates in a join and has an INSTEAD OF UPDATE trigger.
UPDATE si
SET
name = mc.name,
sup_item_cat_id = mc.res_sup_item_cat_id,
xf_value = mc.xf_value,
ava_start_date = mc.ava_start_date,
ava_end_date = mc.ava_end_date,
status_code = mc.status_code,
last_mod_us_id = CASE WHEN mc.last_mod_us_id = 42 THEN #posting_us_id
ELSE mc.last_mod_us_id END,
last_mod_tsp = CURRENT_tsp
FROM sup_item AS si
JOIN merch_cat_imp_sup_item AS mc
ON mc.sup_id = si.sup_id
AND mc.res_sup_item_id = si.sup_item_id
AND mc.cat_imp_event_id = #cat_imp_event_id
AND mc.accept_flag = 'y'
WHERE si.shi_flag = 'n'
I found the reference: http://msdn.microsoft.com/en-us/library/ms177523.aspx
A view with an INSTEAD OF UPDATE trigger cannot be a target of an
UPDATE with a FROM clause.
So, I have to rewrite the UPDATE statement (it still can be in a procedure) to NOT use sup_item (which is a view), but keep the underlying table(s) as needed.
Could someone please rewrite it, if anyone knows what to do?
You can use MERGE to achieve this. Try:
MERGE INTO sup_item si
USING merch_cat_imp_sup_item AS mc
ON mc.sup_id = si.sup_id
AND mc.res_sup_item_id = si.sup_item_id
AND mc.cat_imp_event_id = #cat_imp_event_id
AND mc.accept_flag = 'y'
AND si.shi_flag = 'n'
WHEN MATCHED
THEN UPDATE
SET
name = mc.name,
sup_item_cat_id = mc.res_sup_item_cat_id,
xf_value = mc.xf_value,
ava_start_date = mc.ava_start_date,
ava_end_date = mc.ava_end_date,
status_code = mc.status_code,
last_mod_us_id = CASE WHEN mc.last_mod_us_id = 42 THEN #posting_us_id
ELSE mc.last_mod_us_id END,
last_mod_tsp = CURRENT_tsp
The issue is not within your query. As per comments on your question, the entity you are updating [sup_item], isn't actually a table, it's a view. That view has an INSTEAD OF UPDATE trigger on it.
Are you able to post the SQL for the View and for the Trigger(s)?
I would also be interested, because I have a stored procedure in a database that I have inherited which tries to do this. It won't let me create the sproc in SQL 2014, but the fact that it is there in the sproc indicates to me that an earlier version of SQL server must have allowed this.
Maybe in earlier versions your procedure operated on a table, which was later replaced by a view.
You should replace your "update from" syntax by standard ANSI syntax of update.