DB procedure in Merge Statement
Hi,
Is there any way to use DB procedure inside of Merge Statement.
Thanks & Regards
Radha K
Wrap your procedure in a function to be accessible from within SQL.
Similar Messages
-
Error executing a stored procedure from SSIS using the MERGE statement between databases
Good morning,
I'm trying to execute from SSIS a stored procedure that compares the content of two tables on different databases in the same server and updates one of them. To perform this action, I've created a stored procedure in the destination database and I'm
comparing the data between tables with the MERGE statement. When I execute the procedure on the destination database the error that I obtain is:
"Msg 916, Level 14, State 1, Procedure RefreshDestinationTable, Line 13
The server principal "XXXX" is not able to access the database "XXXX" under the current security context."
Some things to take in account:
1. I've created a temporary table on the same destination database to check if the problem was on the MERGE statement and it works fine.
2. I've created the procedure with the option "WITH EXECUTE AS DBO".
I've read that it can be a problem of permissions but I don't know if I'm executing the procedure from SSIS to which user/login I should give permissions and which.
Could you give me some tip to continue investigating how to solve the problem?
Thank you,
VirgilioRead Erland's article http://www.sommarskog.se/grantperm.html
Best Regards,Uri Dimant SQL Server MVP,
http://sqlblog.com/blogs/uri_dimant/
MS SQL optimization: MS SQL Development and Optimization
MS SQL Consulting:
Large scale of database and data cleansing
Remote DBA Services:
Improves MS SQL Database Performance
SQL Server Integration Services:
Business Intelligence -
Hi all,
I am working on oracle9i
I am using the Merge Statement to INS/UPD rows
I am using loops to
I am updating 29 rows as insert and 1 row a update
Values are inserting and updating correctly in table
But in Sql prompt
I am getting the output as
below
12:03:54 SQL> execute Pr_Bdms_Cont_Insupd;
1 rows merged.
1 rows inserted.
1 rows updated.
PL/SQL procedure successfully completed.
But i take out the loop i am getting exact result
12:03:54 SQL> execute Pr_Bdms_Cont_Insupd;
30 rows merged.
29 rows inserted.
1 rows updated.
PL/SQL procedure successfully completed.
Any help
Below is my procedure
and
CREATE OR REPLACE PROCEDURE Pr_EMP_Insupd IS
empID VARCHAR2(7);
CURSOR C_empno IS SELECT empno FROM TEMP WHERE ROWNUM < 30;
REC_BIN C_empid%ROWTYPE;
BEGIN
FOR REC_BIN IN C_empid LOOP
empID := fn_emp_Id(REC_BIN.Bin);-- Calling function
Merge INTO EMP E
BGC
USING (SELECT A.EMP_ID,B.SALARY,B.BONUS
FROM EMP_IN A, TEMP B
WHERE A.EMPNO = B.EMPNO
AND A.EMP_ID = EMPID)NP
ON(E.EMP_ID = NP.EMP_ID)
WHEN MATCHED THEN UPDATE SET E.SALARY = NP.SALARY,
E.BONUS = NP.BONUS
WHEN NOT MATCHED THEN INSERT (E.EMP_ID,E.SALARY,E.BONUS,E.CREATED_DATE)
VALUES (CASE Check_Upd_Ins.merge_counter(Check_Upd_Ins.c_inserting)
WHEN 0 THEN E.EMP_ID
END,
E.SALARY,E.BONUS,SYSDATE);
END LOOP;
/* Use insert count... using ETL Package*/
dbms_output.put_line(Check_Upd_Ins.get_merge_update_count(SQL%rowcount) || ' rows updated.');
dbms_output.put_line(Check_Upd_Ins.get_merge_insert_count || ' rows inserted.');
Check_Upd_Ins.reset_counters;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20000, SQLERRM(SQLCODE));
END Pr_EMP_Insupd;Perhaps I can help you with this piece of code and this link :
MERGE INTO bonuses D
USING (SELECT employee_id, salary, department_id FROM employees
WHERE department_id = 80) S
ON (D.employee_id = S.employee_id)
WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01
WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)
VALUES (S.employee_id, S.salary*0.1);
http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96624/13_elems30.htm#37586
Joel P�rez -
Problem using TAPI triggers and merge statement
Hi,
I use Designer tapi triggers on a table. When I try to execute a merge statement, I get the following error:
ORA-06502: PL/SQL: numeric or value error: NULL index table key value.
Is there a restriction when using TAPI triggers and merge statements that anyone is aware of?No restrictions on MERGE commands that I know of. I have, however, seen the TAPI give inexplicable ORA-06502 errors. It would help to know what line in which procedure or trigger gave the error. That information should have been in the error stack.
-
hi gems..good afternoon...
My database version is 11.2.0.1.0 64 bit Solaris OS.
I am facing an "ORA-22813: operand value exceeds system limits" while running a procedure.
I have used loggers and found that it is getting failed in a MERGE statement.
That merge statement is used to merge a table with a collection. the code is like below:
MERGE /*+ INDEX(P BALANCE_HISTORIC_INDEX) */
INTO BALANCE_HOLD_HISTORIC P
USING TABLE(GET_BALANCE_HIST(V_MERGE_REC)) M
ON (P.CUSTOMER_ID = M.CUSTOMER_ID AND P.BOOK_ID = M.BOOK_ID AND P.PRODUCT_ID = M.PRODUCT_ID AND P.SUB_BOOK_ID = M.SUB_BOOK_ID AND)
WHEN MATCHED THEN
UPDATE
<set .....>
WHEN NOT MATCHED THEN
INSERT<.....>The parameter of the function GET_BALANCE_HIST(V_MERGE_REC) is a table type.
Now the function GET_BALANCE_HIST(V_MERGE_REC) is a pipelined function and we have used that because the collection V_MERGE_REC may get huge with data.
This proc was running fine from the beginning but from day before yesterday it was continously throwing ORA 22813 error in that line.
please help..thanks in advance..hi paul..thanks for your reply...
the function GET_BALANCE_HIST is not selecting data from any tables.
What this pipeline function is doing is, it is taking the huge collection V_MERGE_REC as parameter and releasing its datas in pipelined form. The code for the functions is :
CREATE OR REPLACE FUNCTION GET_BALANCE_HIST(P_MERGE IN TAB_TYPE_BALANCE_HISTORIC)
RETURN TAB_TYPE_BALANCE_HISTORIC
PIPELINED AS
V_MERGE TAB_TYPE_BALANCE_HISTORIC := TAB_TYPE_BALANCE_HISTORIC();
BEGIN
FOR I IN 1 .. P_MERGE.COUNT LOOP
V_MERGE.EXTEND;
V_MERGE(V_MERGE.LAST) := OBJ_TYPE_BALANCE_HISTORIC(P_MERGE(I).CUSTOMER_ID,
P_MERGE(I).BOOK_ID,
P_MERGE(I).PRODUCT_ID,
P_MERGE(I).SUB_BOOK_ID,
P_MERGE(I).EARNINGS,
P_MERGE(I).EARNINGS_HOUSE,
P_MERGE(I).QUANTITY,
P_MERGE(I).ACCOUNT_INTEGER);
END LOOP;
FOR J IN 1 .. V_MERGE.COUNT LOOP
PIPE ROW(OBJ_TYPE_BALANCE_HISTORIC(V_MERGE(I).CUSTOMER_ID,
V_MERGE(I).BOOK_ID,
V_MERGE(I).PRODUCT_ID,
V_MERGE(I).SUB_BOOK_ID,
V_MERGE(I).EARNINGS,
V_MERGE(I).EARNINGS_HOUSE,
V_MERGE(I).QUANTITY,
V_MERGE(I).ACCOUNT_INTEGER));
END LOOP;
RETURN;
END;I think the error is comming because of the parameter value of V_MERGE_REC. Since it is huge, so loading that into memory is causing problem. But in this case, how can I resolve it?? Can I use a global temporary table for this??
Please suggest... -
I encountered with ORA-00904 in Merge statement. I fixed the error but I don't know why. Would you please help me explain it? Thanks in advance. The following is the detail description of my question.
I have two tables TBL_A<col1 integer,col2 integer> TBL_B<col1 integer,col2 integer> and an anonymous block to test executed in Oracle 10gR2.
DECLARE
V_NUM INTEGER;
BEGIN
V_NUM := 1;
/*merge I it's okay.the function of merge seems meaningless, please pay attention to its grammar*/
MERGE INTO TBL_A A
USING (SELECT V_NUM N, COL1, COL2 FROM TBL_B) B
ON (A.COL1 = B.N)
WHEN MATCHED THEN
UPDATE SET A.COL2 = B.COL2;
/*merge II*/
/*ora-00904*/
MERGE INTO TBL_A A
USING (SELECT V_NUM, COL1, COL2 FROM TBL_B) B
ON (A.COL1 = V_NUM)
WHEN MATCHED THEN
UPDATE
SET A.COL2 = B.COL2;
/*merge III is okay*/
MERGE INTO TBL_A A
USING (SELECT COL1, COL2 FROM TBL_B) B
ON (A.COL1 = V_NUM)
WHEN MATCHED THEN
UPDATE
SET A.COL2 = B.COL2;
COMMIT;
END;
I traced the 904 error and it seems the point is in the binding of variable V_NUM. But I don't know the exact reason. I think maybe it relates with the parse of PL/SQL. Would someone please help me or give me some hints?hi,
When you saye,
MERGE INTO TBL_A A
USING (SELECT V_NUM,
COL1,
COL2
FROM TBL_B) B
ON (A.COL1 = V_NUM)
WHEN MATCHED
THEN
UPDATE SET A.COL2 = B.COL2;
In the above for ON (A.COL1 = V_NUM)
oracle treats v_num as a variable in the procedure rather than v_num returned from using clause.
So you need to alias that.
MERGE INTO TBL_A A
USING (SELECT V_NUM as somecol,
COL1,
COL2
FROM TBL_B) B
ON (A.COL1 = b.somecol)
WHEN MATCHED
THEN
UPDATE SET A.COL2 = B.COL2;Edited by: Ganesh Srivatsav on May 12, 2011 11:42 AM
Added alias after peter pointed out for variable in the using. -
Bogus Invalid Object in MERGE Statement
Let me begin by saying that I have been working with MERGE since its inception, and I am familiar with the fundamental gotcha's. This problem is more inexplicable. (It's one of those things that I expect, when someone explains it, will be a DOH! moment.)
I am building a one-time conversion script to merge an existing User table with a new User table. Since I am only in the development mode, I didn't want to modify the true table yet. So I made a copy of the table to work with, using the following familiar
syntax.
SELECT *
INTO uam.User2
FROM uam.[User]
Imagine my surprise when the MERGE statement refused to recognize uam.User2 - although it recognizes uam.[User] just fine.
In the interests of competeness, here is the MERGE Statement in question.
MERGE uam.[User2]
as tgt
USING (SELECT
UserID
,FirstName
,LastName
,CompanyID
,AuthenticationID
,isActive
,PrimaryEmailID
,CreatedByUserName
,CreatedByDtim
,@User
_User
,GETDATE()
_GETDATE
FROM #User
) as src
ON tgt.UserID = (src.UserID * -1)
WHEN NOT MATCHED
THEN
INSERT
(FirstName
,LastName
,CompanyID
,AuthenticationID
,isActive
,PrimaryEmailID
,CreatedByUserName
,CreatedByDtim
,LastUpdatedUserName
,LastUpdatedDtim
VALUES
(src.FirstName
,src.LastName
,src.CompanyID
,src.AuthenticationID
,src.isActive
,src.PrimaryEmailID
,src.CreatedByUserName
,src.CreatedByDtim
,_User
,_GETDATE
OUTPUT INSERTED.UserID
,tgt.UserID
INTO #UserMapping;
The procedure refuses to run, flagging the tgt.UserID as
Msg 4104, Level 16, State 1, Line 140
The multi-part identifier "tgt.UserID" could not be bound.
SSMS also flags the uam.[User2] on the MERGE line as "Invalid object name 'uam.User2'" on mouse-over.
A few notes:
I have a SELECT * FROM uam.User2 immediately before this MERGE, and it works just fine. And yes, it returns a UserID column.
If I change the name from uam.User2 to uam.[User], it works just fine.
I know the JOIN is a little strange (I really wanted just an INSERT where I could see the original UserID and the newly inserted UserID together, and INSERT will not let me OUTPUT directly from a table - hence the MERGE), but I also tried it with a straight-up
tgt.UserID = src.UserID. Nothing changed about the errors.
I also went back and re-created the uam.User2 table directly from the code that built uam.[User]. Nothing changed.
I'm flummoxed. This has all the earmarks of a "well-that-was-dumb" coding error, but for the life of me I cannot see what would change between using these two tables, since one is a copy of the other...
Any insight would be much appreciated!
Duncan DavenportOK, I have it.
DOH! (told ya)
So, while intellisense (typically) flags this table as not existing, that's just Intellisense doing the nonsense it always does. This obfuscated the ACTUAL error - which was the wrong schema defined in the output clause. The error itself pointed at the wrong
line (nothing new there either). Once I fixed the OUTPUT clause, everything worked as expected - although SSMS is still putting squiggly red lines under everything that is working anyway. Yeah, we've all seen THAT behavior - no big deal.
Anyway, that's the answer. It's magic - in that the error messages specialize in misdirection :)...
Closing this. (I wonder if I get credit for answering my own question?) -
Merge statement not working over db link
I have a merge statement that works fine when it's run against a local table, but when I try to run it against a table over a database link, I get the following error.
ERROR at line 1:
ORA-01008: not all variables bound
ORA-02063: preceding line from REPOS
ORA-06512: at "DBADMIN.PING_DB", line 6
ORA-06512: at line 1
Here is the code:
create or replace procedure ping_db
as
begin
merge into availability@repos A
using (select trunc(sysdate) from dual)
on (trunc(A.day) = trunc(sysdate))
when matched then update set A.uptime = A.uptime + 1
when not matched then insert (hostname,dbname,day,uptime) values
(utl_inaddr.get_host_name,sys.database_name,trunc(sysdate),1);
commit;
end;
/Code compiles fine, but gets the error when it's executed. Any help would be appreciated.9.2.0.x is the version (9.2.0.4,.5 and .6)
-
Where should use Merge Statement in Form
hi experts
in Toad I am using this Merge statement , working accordingly.
I want to use this merge statement in my form where can I use it.
I created a Procedure in Form Named Proc_merge and call it when validate item of *:bankcode*
PROCEDURE proc_merge IS
BEGIN
declare
v_com varchar2(5000);
BEGIN
V_COM := '
Merge into allvouchers trg
using
(select voucher_type,voucher_no,voucher_date,cheque_no,bank_code,narration,debit,credit from(
select pv_voucher_type Voucher_type, pv_no Voucher_No, pv_date Voucher_date, Cheque_no, Acc_code Bank_code, Narration,Debit,Credit
from
(select a.pv_voucher_type,a.pv_no, a.pv_date, a.cheque_no, a.pv_gl_credit_code acc_code , b.ca_title,null Debit,
a.pv_gl_credit_amount Credit, a.Pv_narration Narration
from gl_pv a, ca_gl b where a.pv_gl_credit_Code = b.ca_code and a.pv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
union all
select a.pv_voucher_type,a.pv_voucher_no,a.pv_date,b.cheque_no,a.pv_acc_code,c.ca_title,a.pv_debit, Null credit,a.pv_desc
from payment_detail a, gl_pv b, ca_gl c
where a.pv_voucher_no = b.pv_no
and a.pv_date = b.pv_date
and a.pv_voucher_type = b.pv_voucher_type
and pv_acc_code = c.ca_code and a.pv_debit > 0
and a.pv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
union all
select a.pv_voucher_type, a.pv_voucher_no,a.pv_date, b.cheque_no, a.pv_acc_code, c.ca_title,
null ,a.pv_credit, a.pv_desc
from payment_detail a , gl_pv b , ca_gl c
where a.pv_voucher_no = b.pv_no
and a.pv_date = b.pv_date
and a.pv_acc_code = c.ca_code
and pv_credit >0 and a.pv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
union all
select a.pv_voucher_type, a.pv_no,pv_date,a.cheque_no , a.wht_debt_ac, b.ca_title , null, a.wht_amount, a.wht_narration
from gl_pv a , ca_gl b where a.wht_debt_ac = b.ca_code and wht_amount > 0
and a.pv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
where acc_code = :bankcode
Union all
--------------------- R.Voucher ----------------
select a.rv_voucher_type, a.rv_no, a.rv_date, a.chequeno, b.rv_acc_code, a.rv_narration,b.rv_debit, b.rv_credit
from gl_receipt a, receipt_detail b , ca_gl c
where a.rv_no = b.rv_voucher_no
and a.rv_date = b.rv_date
and b.rv_acc_code = c.ca_code
and b.rv_acc_code = :bankcode
and a.rv_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
----------------------- SRV --------------
Union all
select a.vm_voucher_type ,a.vm_no ,a.vm_date,a.chequeno,b.vd_acc_code, b.vd_desc VNARRAION,
b.vd_debit VDEBIT,b.vd_credit VCREDIT
from vouchermaster a, voucherdetail b , ca_gl c
where a.vm_no= b.vd_no
and a.vm_voucher_type = b.vm_voucher_type
and a.vm_date = b.vm_date
and b.vd_acc_code = c.ca_code
and b.vd_acc_code = :bankcode
and a.vm_date > to_date (''30/06/2010'',''dd/mm/yyyy'')
and (a.show_voucher =''Y'' or Show_Voucher is Null)
and a.vm_voucher_type =''SRV''
)) Src
on (trg.v_type = src.voucher_type and trg.v_no = src.voucher_no and trg.v_date = src.voucher_date)
when matched then
update set
trg.v_chq = src.cheque_no, trg.v_bankcode = src.bank_code ,trg.v_debit=src.debit, trg.v_credit=src.credit, trg.v_narration=src.narration
when not matched then
insert (trg.v_type, trg.v_no, trg.v_date, trg.v_chq, trg.v_bankcode, trg.v_debit, trg.v_credit, trg.v_narration)
values (src.voucher_type, src.voucher_no, src.voucher_date, src.cheque_no, src.bank_code, src.debit, src.credit, src.narration)
FORMS_DDL(V_COM);
end;
END;no any result.
please guide me is this right way to do this. or kindly suggest me other ways to using merge statement in form.Hello,
1.) why do you use dynamic SQL here? forms_ddl is a tricky one as it doesn't throw exceptions, so debugging is really fun. And I can't see any justification why this has to be dynamic SQL.
2.) put the whole thing in a stored procedure and call this procedure. write once, run everywhere.
cheers -
2 MERGE statements in same trigger - is it possible ?
Hi guys,
I have an After Insert trigger (on table A) that takes the last record from table A and insert/update it on another table (B) then insert /update in same table (B) some records which depends on it. When trying to insert data in table A, the trigger raise this error: ORA-04092: cannot COMMIT in a trigger.
I understand the error, but I need expert's opinion to make the trigger works.
Here is the actual situation:
Table A has a trigger on after insert, and BASED ON THE LAST ROW inserted (only this data is subject to the trigger's actions) does the following:
1. MERGE the data (last row from the source table=A) with the data from the table destination=B. This data is specific to an employee;
2. Open a cursor that goes through all the ancestors of the employee (I have an employees hierarchy) and MERGE the same data (but for ancestors) with the table destination;
To be more specific :
EmpID LOB Day Status
12 1007 29 Solved
EmpID has ancestors 24 and 95. Therefore in the destination table I will have to do:
1. Merge data for EmpID 12;
2. Merge data for EmpID 24, 95:
EmpID LOB Day Status
24 1007 29 Just S (this is the status for ancestors)
95 1007 29 Just S
Steps 1 and 2 are inside a PL/SQL procedure that works fine by itself, but not within the trigger (since there are many transactions on the destination table). These 2 steps are required because for EmpID 12 I set a status and for the ancestors I set up a different status (this was the only way I could think of).
Can someone give me a hint how should I handle this situation ?
Thank you,
JohnBased on my understanding of what you are trying to do you are going about this in the wrong way. Try this approach instead:
1. Trigger fires initiating the process and passes relevant :NEW values to a stored procedure
2. The stored procedure does all the work and possibly should be an autonomous transaction
It looks very much like your code just doesn't belong in a trigger.
PS: Why a MERGE statement? If the rows most likely do not exist then INSERT and UPDATE in your exception handler: Otherwise UPDATE as the default and INSERT in the exception handler. It is not very likely the percentage of inserts and updates will be near 50% each. -
Indivual error recording in Merge Statement !!!!
Is it possible to record indivudual error in MERGE statement (Update / Insert).
I am unable to record those error. instead of MERGE if I update table in the cursor loop then I am able to record individual error but the process is time consuming.
Thanks in advance.
DebaHi Deba,
DML Error Logging:
SQL> create table tab1 (x number(1));
Table created.
SQL> exec dbms_errlog.create_error_log('tab1')
PL/SQL procedure successfully completed.
SQL>
SQL> merge into tab1 t
2 using (select 1 x from dual union all
3 select 112 x from dual) s
4 on (t.x = s.x)
5 when not matched
6 then insert (x) values (s.x)
7 log errors into err$_tab1 reject limit unlimited;
1 row merged.
SQL>
SQL> COL x for 9999
SQL> select * from tab1;
X
1
SQL> COL x for a4
SQL> select ora_err_number$, X from err$_tab1;
ORA_ERR_NUMBER$ X
1438 112
SQL>Regards
Peter -
I have a merge statement, this executes for all the rows when the procedure is executed. Here i would like to include this merge statement as the part of LOOP so that all records will not get updated for a one time.
how can i change this merge statement to include as the part of LOOP here.
the user id should be the key to update the table USERS in merge statement, the same user id is exists in the bulk collect too..
BEGIN
v_sysdate:= pkg_utilities.fn_sysdate(1) ;
o_Error_Text := 'ORA-Error in updating end date in user_status table ';
tname:= 'user_status';
MERGE INTO user_status r1
USING (
SELECT rowid rid , lead(start_period) OVER (PARTITION by user_id
order by start_period)- 1 new_enddate FROM user_status ) r2
ON ( r1.rowid = r2.rid )
WHEN MATCHED THEN
UPDATE SET end_period = new_enddate ;
OPEN generic_cv4
FOR SELECT
user_id,user_status_type_id
FROM user_status
WHERE end_period IS NULL;
LOOP
FETCH generic_cv4 BULK COLLECT INTO
v_user_id_seq,
v_user_status_new
LIMIT p_array_size;
EXIT WHEN v_user_id_seq.COUNT = 0;
IF v_user_id_seq.COUNT > 0 THEN
o_Error_Text := 'ORA-Error in update user_status type id in users table ';
tname:= 'users';
FORALL I IN v_user_id_seq.FIRST..v_user_id_seq.LAST
UPDATE users
SET user_status_type_id = v_user_status_new(i),
last_upd_date = v_sysdate
WHERE user_id = v_user_id_seq(i);
END IF;
COMMIT;
END LOOP;
v_user_id_seq.delete;
v_user_status_new.delete;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error' ||sqlerrm);
DBMS_OUTPUT.PUT_LINE(o_Error_Text);
v_sql_err :=SQLERRM;
ROLLBACK;
pkg_champ_message_log.champ_message_log ('PKG_MIGRATE_V1_NESTED_MEMBER.p_update_member_status', tname, null,'Nested', v_sql_err,'Error',o_Error_Text,O_STATUS);
END;Now lets talk how can i keep this merge statemnet as the part of the loop. It seems your mind is made up.
Unfortunately, what you're asking makes no sense at all. You can't "loop through a merge statement".
If you don't want to use merge for the entire table at once, the only thing you can do is to break up the table in your USING clause by some sort of range (maybe an account number or whatever). You could then run your code for each range (or even run them in parallel).
The only other option is to not use MERGE at all and duplicate the logic of it within your loop (which is what I said in my first response). -
i would like to know if it is possible to identify the row that is causing the problem when you use a merge statement in pl/sql. i know if you create a cursor and then loop through the data you can identify the column but what about if i have only a merge that will either insert or update. is it possible to identify which row of data cause the problem? thanks
You can use an Error Logging Table<br>
<br>
Nicolas. -
Hi
I am using a merge statement where i am updating and inserting records in table 2 from table 1.
I want to log the no. of rows updated and new rows inserted in the log table.
If i am not wrong, we can use sql%rowcount but i need help as how to use this statement.
Please suggest a solution.
Thanksuser11018028 wrote:
Will the sql%rowcount will give the no. of updated rows OR no. of newly inserted rows OR the sum of both in case of a merge statement.Total number of rows that changed (SUM). -
Question on passing string values to Partition clause in a merge statement
Hello All,
I am using the below code to update specific sub-partition data using oracle merge statements.
I am getting the sub-partition name and passing this as a string to the sub-partition clause.
The Merge statement is failing stating that the specified sub-partition does not exist. But the sub-partition do exists for the table.
We are using Oracle 11gr2 database.
Below is the code which I am using to populate the data.
declare
ln_min_batchkey PLS_INTEGER;
ln_max_batchkey PLS_INTEGER;
lv_partition_name VARCHAR2 (32767);
lv_subpartition_name VARCHAR2 (32767);
begin
FOR m1 IN ( SELECT (year_val + 1) AS year_val, year_val AS orig_year_val
FROM ( SELECT DISTINCT
TO_CHAR (batch_create_dt, 'YYYY') year_val
FROM stores_comm_mob_sub_temp
ORDER BY 1)
ORDER BY year_val)
LOOP
lv_partition_name :=
scmsa_handset_mobility_data_build.fn_get_partition_name (
p_table_name => 'STORES_COMM_MOB_SUB_INFO',
p_search_string => m1.year_val);
FOR m2
IN (SELECT DISTINCT
'M' || TO_CHAR (batch_create_dt, 'MM') AS month_val
FROM stores_comm_mob_sub_temp
WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val)
LOOP
lv_subpartition_name :=
scmsa_handset_mobility_data_build.fn_get_subpartition_name (
p_table_name => 'STORES_COMM_MOB_SUB_INFO',
p_partition_name => lv_partition_name,
p_search_string => m2.month_val);
DBMS_OUTPUT.PUT_LINE('The lv_subpartition_name => '||lv_subpartition_name||' and lv_partition_name=> '||lv_partition_name);
IF lv_subpartition_name IS NULL
THEN
DBMS_OUTPUT.PUT_LINE('INSIDE IF => '||m2.month_val);
INSERT INTO STORES_COMM_MOB_SUB_INFO T1 (
t1.ntlogin,
t1.first_name,
t1.last_name,
t1.job_title,
t1.store_id,
t1.batch_create_dt)
SELECT t2.ntlogin,
t2.first_name,
t2.last_name,
t2.job_title,
t2.store_id,
t2.batch_create_dt
FROM stores_comm_mob_sub_temp t2
WHERE TO_CHAR (batch_create_dt, 'YYYY') = m1.orig_year_val
AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
m2.month_val;
ELSIF lv_subpartition_name IS NOT NULL
THEN
DBMS_OUTPUT.PUT_LINE('INSIDE ELSIF => '||m2.month_val);
MERGE INTO (SELECT *
FROM stores_comm_mob_sub_info
SUBPARTITION (lv_subpartition_name)) T1
USING (SELECT *
FROM stores_comm_mob_sub_temp
WHERE TO_CHAR (batch_create_dt, 'YYYY') =
m1.orig_year_val
AND 'M' || TO_CHAR (batch_create_dt, 'MM') =
m2.month_val) T2
ON (T1.store_id = T2.store_id
AND T1.ntlogin = T2.ntlogin)
WHEN MATCHED
THEN
UPDATE SET
t1.postpaid_totalqty =
(NVL (t1.postpaid_totalqty, 0)
+ NVL (t2.postpaid_totalqty, 0)),
t1.sales_transaction_dt =
GREATEST (
NVL (t1.sales_transaction_dt,
t2.sales_transaction_dt),
NVL (t2.sales_transaction_dt,
t1.sales_transaction_dt)),
t1.batch_create_dt =
GREATEST (
NVL (t1.batch_create_dt, t2.batch_create_dt),
NVL (t2.batch_create_dt, t1.batch_create_dt))
WHEN NOT MATCHED
THEN
INSERT (t1.ntlogin,
t1.first_name,
t1.last_name,
t1.job_title,
t1.store_id,
t1.batch_create_dt)
VALUES (t2.ntlogin,
t2.first_name,
t2.last_name,
t2.job_title,
t2.store_id,
t2.batch_create_dt);
END IF;
END LOOP;
END LOOP;
COMMIT;
end;
Much appreciate your inputs here.
Thanks,
MK.I've not used partitioning, but I do not see MERGE supporting a variable as a partition name in
MERGE INTO (SELECT *
FROM stores_comm_mob_sub_info
SUBPARTITION (lv_subpartition_name)) T1
USING ... I suspect it is looking for a partition called lv_subpartition_name.
I also don't see why you need that partition name - the ON clause should be able to identify the partition's criteria.
Maybe you are looking for
-
Error message when dragging bookmarks to trash
When I try to delete a bookmark item by dragging it to the trash, I get this error message in Finder: "The item "Xxxxxx" can't be moved to the Trash because it can't be deleted." Well, yes it can be deleted - because despite the message, it is indeed
-
How to link to a file in UCM with content presenter site studio template
Hi, I have Webcenter spaces with content presenter showing Site studio content. In this site studio region I have an element for rich text (html) Now we want to create a link in this text to an existing document in UCM. The question is how achief thi
-
How to derive a variable value from another variable of a different IO?
Hi Gurus, I am aware that using BEx variables and Customer Exit you are able to derive a variable value from another variable of the same infoobject (for example, Fiscal Year/Period (0FISCPER) and Calendar Day (0CALDAY)). However, is is possible, usi
-
Retrieve Addresses from .Mac
Somehow my iMac dumped all the addresses in my address book. Nowhere to be found on the computer. I backed up to .Mac account with iSynch but how do I download them back to my desktop?
-
Hello Gurus!!!! Do you know how I can obtain the amount of a residual payment in a Z program? For example, a have an invoice of 10,000 USD and I execute a residual payment of 3,600 USD. There is only left 6,400 for payment. How can I obtain the value