Update columns In a Teradata Table using data from another table - sql

I have seen many posts and followed the syntax to write the below query. But it is still given the error "Column/Parameter wm_ad_hoc.temp.temp does not exist"
Please assist in figuring out what am I doing wrong here.
UPDATE temp
FROM wm_ad_hoc.OWNED_ITEM_STORE_DLY temp,
wm_ad_hoc.OWNED_ITEM_STORE_DLY_UTIL util
SET temp.VENDOR_STOCK_ID = util. VENDOR_STOCK_ID,
temp.ON_HAND_EACH_QTY = util. ON_HAND_EACH_QTY,
temp.VENDOR_STOCK_ID = util.VENDOR_STOCK_ID
WHERE temp. VENDOR_NBR = util. VENDOR_NBR
AND temp.WMI_ITEM_NBR = util.WMI_ITEM_NBR
AND temp. store_nbr = util. store_nbr
AND temp.BUSINESS_DATE = util.BUSINESS_DATE

You need to not qualify your SET columns. So:
UPDATE temp
FROM wm_ad_hoc.OWNED_ITEM_STORE_DLY temp,
wm_ad_hoc.OWNED_ITEM_STORE_DLY_UTIL util
SET VENDOR_STOCK_ID = util.VENDOR_STOCK_ID,
ON_HAND_EACH_QTY = util.ON_HAND_EACH_QTY,
VENDOR_STOCK_ID = util.VENDOR_STOCK_ID
...

Related

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.

How to update columns in a table joined with other tables?

I want to update two columns of a table with reference of other tables. While executing the script its showing error.
Error: Error starting at line 1 in command:
UPDATE wb_costing_work_items,
sa_sales_documents,
sa_sales_document_items
SET cwi_price_per_hour = sdi_price,
cwi_amount = sdi_price * cwi_hours
WHERE cwi_lo_id = sad_lo_id
AND sdi_sad_id = sad_id
AND sdi_wit_id = cwi_wit_id
AND cwi_id = 1650833
Error at Command Line:1 Column:28 Error report: SQL Error: ORA-00971:
missing SET keyword
00971. 00000 - "missing SET keyword"
SQL STATEMENT
UPDATE wb_costing_work_items cwi,
sa_sales_documents sad,
sa_sales_document_items sdi
SET cwi.cwi_price_per_hour = sdi.sdi_price,
cwi.cwi_amount = sdi.sdi_price * cwi.cwi_hours
WHERE cwi.cwi_lo_id = sad.sad_lo_id
AND sdi.sdi_sad_id = sad.sad_id
AND sdi.sdi_wit_id = cwi.cwi_wit_id
AND cwi.cwi_id = 1650855
This should definitely work.
UPDATE (SELECT cwi_price_per_hour,
sdi_price,
cwi_amount,
sdi_price,
cwi_hours
FROM wb_costing_work_items,
sa_sales_documents,
sa_sales_document_items
WHERE cwi_lo_id = sad_lo_id
AND sdi_sad_id = sad_id
AND sdi_wit_id = cwi_wit_id
AND cwi_id = 1650833)
SET cwi_price_per_hour = sdi_price, cwi_amount = sdi_price * cwi_hours
Please alias the tables used and prefix columns so one can easily read your query.
Something like this maybe.
Note that I had to use some wild guesses about which column belongs to which table as you have not included any information about how your tables are define.
So most probably I didn't get it right and you will need to adjust the query to your actual table structure.
merge into wb_costing_work_items
using
(
select cwi.pk_column, -- don't know what the PK of the wb_costing_work_items is due to lack of information
sdi.sdi_price, -- don't know if this column really belong to this table
sdi.sdi_price * cwi.cwi_hours as total-- again unsure about column names due to lack of information
FROM wb_costing_work_items cwi
JOIN sa_sales_documents sad ON sad.sad_lo_id = cwi.cwi_lo_id -- not sure about these, due to lack of information
JOIN sa_sales_document_items sdi
ON sdi.sad_id = sad.sdi_sad_id -- not sure about these, due to lack of information
AND sdi.sdi_wit_id = cwi.cwi_wit_id -- not sure about these, due to lack of information
) t ON (t.pk_column = w.pk_column) -- not sure about this, due to lack of information
when matched then
update
set cwi_price_per_hour = t.sdi_price,
cwi_amount = t.total;

What to do with the error "Ambiguous Columns Defined"?

This is my sql command:
select INCOME_TYPE_ID,
REGION_CODE,
FIN_YEAR_CODE,
PORTION_AMOUNT
from INCOME.INCOME_TYPE,
COMMON.REGION,
INCOME.RECEIVE_DOC_PORTION,
INCOME.ASSESS_ORDER_ITEM,
ACCOUNTING.VOUCHER_ITEM_RECEIVE_DOC,
ACCOUNTING.VOUCHER_ITEM,
ACCOUNTING.VOUCHER,
ACCOUNTING.FIN_YEAR
where INCOME.RECEIVE_DOC_PORTION.ASSESS_ORDER_ITEM_ID = INCOME.ASSESS_ORDER_ITEM.ASSESS_ORDER_ITEM_ID
and INCOME.ASSESS_ORDER_ITEM.INCOME_TYPE_ID=INCOME.INCOME_TYPE.INCOME_TYPE_ID
and INCOME.RECEIVE_DOC_PORTION.RECEIVE_DOC_PORTION_ID = ACCOUNTING.VOUCHER_ITEM_RECEIVE_DOC.RECEIVE_DOC_PORTION_ID
and ACCOUNTING.VOUCHER_ITEM_RECEIVE_DOC.VOUCHER_ITEM_ID = ACCOUNTING.VOUCHER_ITEM.VOUCHER_ITEM_ID
and ACCOUNTING.VOUCHER_ITEM.VOUCHER_ID = ACCOUNTING.VOUCHER.VOUCHER_ID
and ACCOUNTING.VOUCHER.REGION_CODE = COMMON.REGION.REGION_CODE
and ACCOUNTING.VOUCHER.FIN_YEAR_CODE = ACCOUNTING.FIN_YEAR.FIN_YEAR_CODE
and I got this error:
Ambiguous Columns Defined
I'm Using SQL Developer as Oracle client.
Apparently one (or more) column names in your select list exists in more than one table of the FROM list.
You need to prefix every column in the SELECT list with the table it's coming from (it's also a good practice to always do that, regardless of the fact if they are ambigous)
Mention name of table before every column in select query.
Ambiguous column means that you have more than one column with the same name in one of the SELECT statements.
Try this instead, prefgixing all selected columns with their fully qualified names (as you have done elsewhere in your SELECT):
select INCOME.INCOME_TYPE.INCOME_TYPE_ID,
COMMON.REGION.REGION_CODE,
ACCOUNTING.FIN_YEAR.FIN_YEAR_CODE,
ACCOUNTING.VOUCHER_ITEM_RECEIVE_DOC.PORTION_AMOUNT
from INCOME.INCOME_TYPE,
COMMON.REGION,
INCOME.RECEIVE_DOC_PORTION,
INCOME.ASSESS_ORDER_ITEM,
ACCOUNTING.VOUCHER_ITEM_RECEIVE_DOC,
ACCOUNTING.VOUCHER_ITEM,
ACCOUNTING.VOUCHER,
ACCOUNTING.FIN_YEAR
where INCOME.RECEIVE_DOC_PORTION.ASSESS_ORDER_ITEM_ID = INCOME.ASSESS_ORDER_ITEM.ASSESS_ORDER_ITEM_ID
and INCOME.ASSESS_ORDER_ITEM.INCOME_TYPE_ID = INCOME.INCOME_TYPE.INCOME_TYPE_ID
and INCOME.RECEIVE_DOC_PORTION.RECEIVE_DOC_PORTION_ID = ACCOUNTING.VOUCHER_ITEM_RECEIVE_DOC.RECEIVE_DOC_PORTION_ID
and ACCOUNTING.VOUCHER_ITEM_RECEIVE_DOC.VOUCHER_ITEM_ID = ACCOUNTING.VOUCHER_ITEM.VOUCHER_ITEM_ID
and ACCOUNTING.VOUCHER_ITEM.VOUCHER_ID = ACCOUNTING.VOUCHER.VOUCHER_ID
and ACCOUNTING.VOUCHER.REGION_CODE = COMMON.REGION.REGION_CODE
and ACCOUNTING.VOUCHER.FIN_YEAR_CODE = ACCOUNTING.FIN_YEAR.FIN_YEAR_CODE
I had to guess the filly qualified name for
ACCOUNTING.VOUCHER_ITEM_RECEIVE_DOC.PORTION_AMOUNT
It might be
INCOME.RECEIVE_DOC_PORTION.PORTION_AMOUNT
But you should be able to resolve that easily.
Hope it helps...

Oracle customized merge

We have two tables one is source and another one is target. The source table gets updated/refresh with external data source and we have a PL/SQL block which runs daily and updates/inserts the target table rows using Oracle's merge function.
Now we have a situation where a column (email) in the target table could get updated by some external source. Consequently, this email is being updated/overwritten by email of source table with the above mentioned PL/SQL's merge function.
Is there something in the merge function so that it only updates the rows in the target table if things other than the email have been changed. I am happy to add new column(s) into the source and target table if needed.
create or replace
PROCEDURE INSERT_UPDATE_TARGET AS
BEGIN
merge into INTEGRATION_TARGET t
using v_merge vm
on (t.person_num = vm.person_num)
when matched then update set T.YEAR_START = VM.YEAR_START,
T.SEMESTER_START = VM.SEMESTER_START,
T.SATAC_DATABASE_NAME = VM.SATAC_DATABASE_NAME,
T.STUDY_LEVEL = VM.STUDY_LEVEL,
T.REF_NUM = VM.REF_NUM,
T.SEX = VM.SEX,
T.DATE_OF_BIRTH = VM.DATE_OF_BIRTH,
T.DATE_RECEIVED = VM.DATE_RECEIVED,
T.TITLE = VM.TITLE,
T.FAMILY_NAME = VM.FAMILY_NAME,
T.GIVEN_NAME_1 = VM.GIVEN_NAME_1,
T.STREET_NAME = VM.STREET_NAME,
T.STREET_NAME_2 = VM.STREET_NAME_2,
T.STREET_NAME_3 = VM.STREET_NAME_3,
T.POSTAL_STATE = VM.POSTAL_STATE,
T.POSTAL_TOWN = VM.POSTAL_TOWN,
T.POSTAL_POSTCODE = VM.POSTAL_POSTCODE,
T.COUNTRY = VM.COUNTRY,
T.MOBILE = VM.MOBILE,
T.EMAIL = VM.EMAIL
when not matched then insert (T.YEAR_START,
T.SEMESTER_START,
T.SATAC_DATABASE_NAME,
T.STUDY_LEVEL,
T.REF_NUM,
T.PERSON_NUM,
T.SEX,
T.DATE_OF_BIRTH,
T.DATE_RECEIVED,
T.TITLE,
T.FAMILY_NAME,
T.GIVEN_NAME_1,
T.STREET_NAME,
T.STREET_NAME_2,
T.STREET_NAME_3,
T.POSTAL_STATE,
T.POSTAL_TOWN,
T.POSTAL_POSTCODE,
T.COUNTRY,
T.MOBILE,
T.EMAIL
)
values(VM.YEAR_START,
VM.SEMESTER_START,
VM.SATAC_DATABASE_NAME,
VM.STUDY_LEVEL,
VM.REF_NUM,
VM.PERSON_NUM,
VM.SEX,
VM.DATE_OF_BIRTH,
VM.DATE_RECEIVED,
VM.TITLE,
VM.FAMILY_NAME,
VM.GIVEN_NAME_1,
VM.STREET_NAME,
VM.STREET_NAME_2,
VM.STREET_NAME_3,
VM.POSTAL_STATE,
VM.POSTAL_TOWN,
VM.POSTAL_POSTCODE,
VM.COUNTRY,
VM.MOBILE,
VM.EMAIL
);
END;
Thanks
Add a where clause to your update statement

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.