Home » SQL & PL/SQL » SQL & PL/SQL » using rowcount
using rowcount [message #536559] Wed, 21 December 2011 09:18 Go to next message
Paya
Messages: 8
Registered: November 2010
Location: GB
Junior Member
Hi,

i'm working on a trigger that will 'fire' before a deletion, insertion or update.

this is the code I have so far:

create or replace trigger del_ins_upd
  BEFORE INSERT OR DELETE OR UPDATE ON customer
  for each row
  DECLARE
  v_sysdate varchar2(25);
  v_row_count := sql%rowcount;
begin
  

  select to_char(sysdate,'DD-MON-YYYY HH:MM:SS') into v_sysdate from dual;
  
    IF INSERTING THEN
      
      insert into results(output)
                      values (' CUSTOMER table was modified '|| v_row_count ||
                      ' rows have been inserted at ' || v_sysdate); 
    ELSIF UPDATING THEN
      insert into results(output)
                      values (' CUSTOMER table was modified '|| 
                      ' rows have been updated at ' || v_sysdate);
    ELSIF DELETING THEN
      insert into results(output)
                      values (' CUSTOMER table was modified '|| 
                      ' rows have been deleted at ' || v_sysdate);
    ELSE 
      dbms_output.put_line('UNKNOWN');
    END IF;

end;
/


What I try to do is to count the number of rows affected during one of the procedures (insert, delete or update).

I tried using a variable (v_row_count) and then add it within the insert into result table, but it doesnt seem to like it. And i've looked all over the internet to figure out if it's even possible to have a rowcount within an insert statement, but not much luck! Sad So my question is: is it possible? And if yes, can someone give me some guidance with my code please?

The output should be e.g.
'CUSTOMER was modified, 1 new
row has been inserted at 23-NOV-11 09:34:45'.


Thanks in advance!
Re: using rowcount [message #536563 is a reply to message #536559] Wed, 21 December 2011 09:49 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
Hi,

maybe you should realized that the trigger you posted is row-level (for each row clause) one. That means, it fires on every row in statement - rowcount is always 1. If you are satisfied with it, you may end now - simply replace sql%rowcount with 1.

If you are interested in rows affected in a statement, you should use statement-level (without for each row clause) one. I do not know if sql%rowcount is accessible in that case. If not, you may still use the technique described in this thread on AskTom: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:290416059674
Shortly: create global package variable for storing row count, before statement-level trigger for clearing it, after row-level trigger for increasing it (by 1) and after statement-level trigger for writing it.
Re: using rowcount [message #536566 is a reply to message #536563] Wed, 21 December 2011 10:01 Go to previous messageGo to next message
Paya
Messages: 8
Registered: November 2010
Location: GB
Junior Member
My problem is that I want to be able to indicate how many rows are affected in 1 line basically. So if 3 rows are inserted then it should display that 3 rows were inserted at (timestamp).

How would I do that then? And also, do I need to get rid of the for each row clause?

Thanks!


[EDITED by LF: removed unnecessary quote of the whole previous message]

[Updated on: Wed, 21 December 2011 14:26] by Moderator

Report message to a moderator

Re: using rowcount [message #536567 is a reply to message #536566] Wed, 21 December 2011 10:10 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
Paya wrote on Wed, 21 December 2011 17:01
My problem is that I want to be able to indicate how many rows are affected in 1 line basically. So if 3 rows are inserted then it should display that 3 rows were inserted at (timestamp).

How would I do that then?

3 rows in one INSERT SELECT statement? Then follow the second paragraph I wrote in my previous post.
3 rows in 3 INSERT VALUES statement? Then it is impossible with trigger - you have to explicitly say that you want to log these three INSERT statements and not the other (say 2) ones which follow them.
Paya wrote on Wed, 21 December 2011 17:01
And also, do I need to get rid of the for each row clause?

If you want to create statement-level trigger, yes. Maybe you should get acquainted with CREATE TRIGGER syntax. Fortunately, it is described in SQL Language Reference book, which is available e.g. online on http://tahiti.oracle.com/
Just pick the one for your Oracle version (which you did not bother to state).
Re: using rowcount [message #536569 is a reply to message #536566] Wed, 21 December 2011 10:12 Go to previous messageGo to next message
Michel Cadot
Messages: 68767
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator
Also it should be an AFTER trigger and even then you are not sure what is displayed is what actually happens as you may have other triggers.
Also your trigger should compile before you can use it! (this is not the case of the one you posted).

If you have to do many things on a DML then it is FAR better to embed it in a procedure and ONLY allow the DML to be executed from this procedure (using a BEFORE trigger, of course).

Regards
Michel
Re: using rowcount [message #536572 is a reply to message #536569] Wed, 21 December 2011 10:28 Go to previous messageGo to next message
Paya
Messages: 8
Registered: November 2010
Location: GB
Junior Member
It does compile if I get rid of the v_count_row variables. I've only had it in there so you could see what I was pointing at.

@Flyboy:
I will try and have a look into that guide. Sorry I forgot to mention, it's Oracle 11g.


[EDITED by LF: removed unnecessary quote of the whole previous message]

[Updated on: Wed, 21 December 2011 14:27] by Moderator

Report message to a moderator

Re: using rowcount [message #536573 is a reply to message #536572] Wed, 21 December 2011 11:00 Go to previous messageGo to next message
John Watson
Messages: 8988
Registered: January 2010
Location: Global Village
Senior Member
How about something completely different?
orcl>
orcl> var retval varchar2(50)
orcl> update emp set sal=sal*1 where deptno=10
  2  returning count(*)||' rows updated at '||max(sysdate) into :retval;

3 rows updated.

orcl> print retval

RETVAL
------------------------------------------------------------------------------

3 rows updated at 21-12-11 16:59:25

orcl>

Re: using rowcount [message #536574 is a reply to message #536573] Wed, 21 December 2011 11:17 Go to previous messageGo to next message
Paya
Messages: 8
Registered: November 2010
Location: GB
Junior Member
That's basically what I want BUT
1) I'm using SQL developer
2) would that line with the returning count(*) be used in an IF statement such as in my code?


[EDITED by LF: removed unnecessary quote of the whole previous message]

[Updated on: Wed, 21 December 2011 14:27] by Moderator

Report message to a moderator

Re: using rowcount [message #536576 is a reply to message #536574] Wed, 21 December 2011 11:28 Go to previous message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
A shovel is a fine tool to make a hole in the ground;
but only when the "correct" end of the tool comes into contact with the Earth.
When you use the wrong end of the shovel, it is sub-optimal.
You (ab)use of trigger, is problematic.
In your actual PL/SQL code, you KNOW where UPDATE statement exists.
John showed how to capture the completed row count.
You can the place the appropriate INSERT statement, following the UPDATE statement.
I suggest that you not over complicate the implementation by abusing TRIGGER.
Previous Topic: Table backup
Next Topic: Synonyms and the DBA_SYNONYMS view
Goto Forum:
  


Current Time: Sun Aug 24 20:33:20 CDT 2025