Trigger INSERTING into a rowPerformance of a Trigger vs Stored Procedure in MySQLFastest way to change column...

How to deal with taxi scam when on vacation?

Do I need life insurance if I can cover my own funeral costs?

How to terminate ping <dest> &

Does someone need to be connected to my network to sniff HTTP requests?

Are all passive ability checks floors for active ability checks?

Who is flying the vertibirds?

Identifying the interval from A♭ to D♯

Why doesn't the EU now just force the UK to choose between referendum and no-deal?

Hacking a Safe Lock after 3 tries

how to write formula in word in latex

Employee lack of ownership

Why is the President allowed to veto a cancellation of emergency powers?

Min function accepting varying number of arguments in C++17

Should we release the security issues we found in our product as CVE or we can just update those on weekly release notes?

How difficult is it to simply disable/disengage the MCAS on Boeing 737 Max 8 & 9 Aircraft?

A Cautionary Suggestion

Unexpected result from ArcLength

My adviser wants to be the first author

Are there other languages, besides English, where the indefinite (or definite) article varies based on sound?

How to change two letters closest to a string and one letter immediately after a string using notepad++

Why did it take so long to abandon sail after steamships were demonstrated?

What are substitutions for coconut in curry?

What is the significance behind "40 days" that often appears in the Bible?

Credit cards used everywhere in Singapore or Malaysia?



Trigger INSERTING into a row


Performance of a Trigger vs Stored Procedure in MySQLFastest way to change column type from varchar2 to number on large table in OracleHow to use a trigger to only insert one rowCreate Trigger MySql update or insert in another tableHow can I do the following task in OracleHow to commit transaction on an after update event trigger?Creating SQL Server triggers to copy a record from one table and populate anotherPostgreSQL Partitioned table update triggerHow to create a trigger that will insert values into another table twice?AFTER INSERT Trigger to add primary key value to foriegn key













1















I am trying to create a Trigger that will fire when a new student is being added to the table. It should update the a table called: MAJOR, by incrementing its MCOUNT domain by one.



CREATE TABLE STUDENT(
SID CHAR(7),
SName VARCHAR2(20),
SMajor CHAR(3)
CHECK (SMajor in ('CSC', 'MIS', 'TDC')),
CONSTRAINT PK_STUDENT
PRIMARY KEY (SID)
);



CREATE TABLE MAJOR(
MName CHAR(3) PRIMARY KEY,
MCount NUMBER(3) );
INSERT INTO MAJOR VALUES ('CSC', 0);
INSERT INTO MAJOR VALUES ('MIS', 0);
INSERT INTO MAJOR VALUES ('TDC', 0);
SELECT * FROM MAJOR;
COMMIT;


My trigger:



CREATE OR REPLACE TRIGGER addingS
AFTER INSERT ON STUDENT
FOR EACH ROW
DECLARE
counter NUMBER (3);
BEGIN
DBMS_OUTPUT.PUT_LINE('Adding student.');
counter := counter + 1;
UPDATE MAJOR
SET MCOUNT = counter
WHERE MCOUNT = 0;
END;
/


It is not updating, now my MCOUNT's value is empty, why is that?










share|improve this question
















bumped to the homepage by Community 6 mins ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
















  • It's usually helpful to identify your DBMS.

    – RDFozz
    Mar 7 '18 at 16:40











  • @RDFozz he did. PL/SQL is Oracle's procedural SQL.

    – Federico Razzoli
    Mar 7 '18 at 16:44











  • And now that you added the tag, this information is duplicated :)

    – Federico Razzoli
    Mar 7 '18 at 16:51











  • Normal practice here: include more general tags so searches on a more general level still show the question. If someone is looking for oracle questions, they probably also want to see oracle-11g questions.

    – RDFozz
    Mar 7 '18 at 16:54
















1















I am trying to create a Trigger that will fire when a new student is being added to the table. It should update the a table called: MAJOR, by incrementing its MCOUNT domain by one.



CREATE TABLE STUDENT(
SID CHAR(7),
SName VARCHAR2(20),
SMajor CHAR(3)
CHECK (SMajor in ('CSC', 'MIS', 'TDC')),
CONSTRAINT PK_STUDENT
PRIMARY KEY (SID)
);



CREATE TABLE MAJOR(
MName CHAR(3) PRIMARY KEY,
MCount NUMBER(3) );
INSERT INTO MAJOR VALUES ('CSC', 0);
INSERT INTO MAJOR VALUES ('MIS', 0);
INSERT INTO MAJOR VALUES ('TDC', 0);
SELECT * FROM MAJOR;
COMMIT;


My trigger:



CREATE OR REPLACE TRIGGER addingS
AFTER INSERT ON STUDENT
FOR EACH ROW
DECLARE
counter NUMBER (3);
BEGIN
DBMS_OUTPUT.PUT_LINE('Adding student.');
counter := counter + 1;
UPDATE MAJOR
SET MCOUNT = counter
WHERE MCOUNT = 0;
END;
/


It is not updating, now my MCOUNT's value is empty, why is that?










share|improve this question
















bumped to the homepage by Community 6 mins ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
















  • It's usually helpful to identify your DBMS.

    – RDFozz
    Mar 7 '18 at 16:40











  • @RDFozz he did. PL/SQL is Oracle's procedural SQL.

    – Federico Razzoli
    Mar 7 '18 at 16:44











  • And now that you added the tag, this information is duplicated :)

    – Federico Razzoli
    Mar 7 '18 at 16:51











  • Normal practice here: include more general tags so searches on a more general level still show the question. If someone is looking for oracle questions, they probably also want to see oracle-11g questions.

    – RDFozz
    Mar 7 '18 at 16:54














1












1








1








I am trying to create a Trigger that will fire when a new student is being added to the table. It should update the a table called: MAJOR, by incrementing its MCOUNT domain by one.



CREATE TABLE STUDENT(
SID CHAR(7),
SName VARCHAR2(20),
SMajor CHAR(3)
CHECK (SMajor in ('CSC', 'MIS', 'TDC')),
CONSTRAINT PK_STUDENT
PRIMARY KEY (SID)
);



CREATE TABLE MAJOR(
MName CHAR(3) PRIMARY KEY,
MCount NUMBER(3) );
INSERT INTO MAJOR VALUES ('CSC', 0);
INSERT INTO MAJOR VALUES ('MIS', 0);
INSERT INTO MAJOR VALUES ('TDC', 0);
SELECT * FROM MAJOR;
COMMIT;


My trigger:



CREATE OR REPLACE TRIGGER addingS
AFTER INSERT ON STUDENT
FOR EACH ROW
DECLARE
counter NUMBER (3);
BEGIN
DBMS_OUTPUT.PUT_LINE('Adding student.');
counter := counter + 1;
UPDATE MAJOR
SET MCOUNT = counter
WHERE MCOUNT = 0;
END;
/


It is not updating, now my MCOUNT's value is empty, why is that?










share|improve this question
















I am trying to create a Trigger that will fire when a new student is being added to the table. It should update the a table called: MAJOR, by incrementing its MCOUNT domain by one.



CREATE TABLE STUDENT(
SID CHAR(7),
SName VARCHAR2(20),
SMajor CHAR(3)
CHECK (SMajor in ('CSC', 'MIS', 'TDC')),
CONSTRAINT PK_STUDENT
PRIMARY KEY (SID)
);



CREATE TABLE MAJOR(
MName CHAR(3) PRIMARY KEY,
MCount NUMBER(3) );
INSERT INTO MAJOR VALUES ('CSC', 0);
INSERT INTO MAJOR VALUES ('MIS', 0);
INSERT INTO MAJOR VALUES ('TDC', 0);
SELECT * FROM MAJOR;
COMMIT;


My trigger:



CREATE OR REPLACE TRIGGER addingS
AFTER INSERT ON STUDENT
FOR EACH ROW
DECLARE
counter NUMBER (3);
BEGIN
DBMS_OUTPUT.PUT_LINE('Adding student.');
counter := counter + 1;
UPDATE MAJOR
SET MCOUNT = counter
WHERE MCOUNT = 0;
END;
/


It is not updating, now my MCOUNT's value is empty, why is that?







oracle trigger plsql






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 7 '18 at 16:47









RDFozz

9,90231531




9,90231531










asked Mar 7 '18 at 16:31









HelloHello

61




61





bumped to the homepage by Community 6 mins ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.







bumped to the homepage by Community 6 mins ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • It's usually helpful to identify your DBMS.

    – RDFozz
    Mar 7 '18 at 16:40











  • @RDFozz he did. PL/SQL is Oracle's procedural SQL.

    – Federico Razzoli
    Mar 7 '18 at 16:44











  • And now that you added the tag, this information is duplicated :)

    – Federico Razzoli
    Mar 7 '18 at 16:51











  • Normal practice here: include more general tags so searches on a more general level still show the question. If someone is looking for oracle questions, they probably also want to see oracle-11g questions.

    – RDFozz
    Mar 7 '18 at 16:54



















  • It's usually helpful to identify your DBMS.

    – RDFozz
    Mar 7 '18 at 16:40











  • @RDFozz he did. PL/SQL is Oracle's procedural SQL.

    – Federico Razzoli
    Mar 7 '18 at 16:44











  • And now that you added the tag, this information is duplicated :)

    – Federico Razzoli
    Mar 7 '18 at 16:51











  • Normal practice here: include more general tags so searches on a more general level still show the question. If someone is looking for oracle questions, they probably also want to see oracle-11g questions.

    – RDFozz
    Mar 7 '18 at 16:54

















It's usually helpful to identify your DBMS.

– RDFozz
Mar 7 '18 at 16:40





It's usually helpful to identify your DBMS.

– RDFozz
Mar 7 '18 at 16:40













@RDFozz he did. PL/SQL is Oracle's procedural SQL.

– Federico Razzoli
Mar 7 '18 at 16:44





@RDFozz he did. PL/SQL is Oracle's procedural SQL.

– Federico Razzoli
Mar 7 '18 at 16:44













And now that you added the tag, this information is duplicated :)

– Federico Razzoli
Mar 7 '18 at 16:51





And now that you added the tag, this information is duplicated :)

– Federico Razzoli
Mar 7 '18 at 16:51













Normal practice here: include more general tags so searches on a more general level still show the question. If someone is looking for oracle questions, they probably also want to see oracle-11g questions.

– RDFozz
Mar 7 '18 at 16:54





Normal practice here: include more general tags so searches on a more general level still show the question. If someone is looking for oracle questions, they probably also want to see oracle-11g questions.

– RDFozz
Mar 7 '18 at 16:54










3 Answers
3






active

oldest

votes


















0














I think that counter is NULL because you don't assign it a value. And after you increment it, nothing changes because NULL + 1 = NULL. Also your UPDATE will not work if MCOUNT is not 0.



Unrelated: I suggest to use a foreign key instead of CHECK.






share|improve this answer































    0














    You define a variable, counter. However, you never set it to a value, which means its value is NULL. 1 + NULL yields NULL.



    Note that this won't work as you want, anyway:




    • Even if you initialize counter to 0, that going to be done for each row. So, for every student, you'll have counter set to 1, and you'd set MCOUNT to 1, not the number of students with the major so far.

    • Since you're only setting MCOUNT if it is currently zero, even if counter was set to the number of students with the major, the UPDATE statement would only be run once, and MCOUNT would still always be 1.

    • Finally, you're not checking the students SMAJOR, and only updating the MAJOR record for that major. Whatever value MCOUNT holds for one major, it will hold for all of them.


    A couple of notes:




    • You can use the current value of MCOUNT to update MCOUNT. You do need to either make sure MCOUNT is either never NULL, or treat a NULL value in MCOUNT as a zero.

    • You need to make sure you're only updating MCOUNT for the major you're concerned with.


    Something like



        UPDATE MAJOR
    SET MCOUNT = NVL(MCOUNT, 0) + 1
    WHERE MAJOR = NEW.SMAJOR


    should work well.



    Also, of course, note that you need to handle changing counts if a student changes their major, or if a student is removed from the system.






    share|improve this answer


























    • MCOUNT could be NULL. It should read "SET MCOUNT = NVL( MCOUNT, 0) + 1"

      – Michael Kutz
      Mar 7 '18 at 21:58











    • @MichaelKutz - Excellent point; updated.

      – RDFozz
      Mar 7 '18 at 22:02



















    0














    For starters, you could use a trigger that picks up the mcount value from table MAJOR, and increments it (via an UPDATE) whenever a student is added to the STUDENT table. However, this will raise a NO_DATA_FOUND exception when the MAJOR table is empty. Thus, we start populating the MAJOR table (with an INSERT) in this situation.



    -- create the 2 tables, then compile the trigger

    create or replace trigger addstudent
    after insert on student
    for each row
    declare
    counter number(3) := 0 ;
    begin
    select mcount into counter
    from major
    where mname = upper( :new.smajor )
    for update ;

    dbms_output.put_line( 'Student added to ' || :new.smajor || ' group.' );
    counter := counter + 1;
    update major
    set mcount = counter
    where mname = :new.smajor ;
    exception
    when no_data_found then
    dbms_output.put_line( 'Table MAJOR: no entry for ' || :new.smajor || '!' ) ;
    insert into major ( mname, mcount ) values ( :new.smajor, 1 ) ;
    dbms_output.put_line( 'Table MAJOR: row for ' || :new.smajor || ' INSERTed.') ;
    end;
    /

    Trigger ADDSTUDENT compiled


    Testing



    begin
    insert into student ( sid, sname, smajor ) values ( 'a1', 'Frank', 'CSC' ) ;
    insert into student ( sid, sname, smajor ) values ( 'a2', 'Lorna', 'CSC' ) ;
    insert into student ( sid, sname, smajor ) values ( 'a3', 'Colin', 'CSC' ) ;
    insert into student ( sid, sname, smajor ) values ( 'a4', 'Harriet', 'MIS' ) ;
    insert into student ( sid, sname, smajor ) values ( 'a5', 'Michael', 'MIS' ) ;
    insert into student ( sid, sname, smajor ) values ( 'a6', 'Dorothy', 'MIS' ) ;
    insert into student ( sid, sname, smajor ) values ( 'a7', 'Harriet', 'TDC' ) ;
    insert into student ( sid, sname, smajor ) values ( 'a8', 'Michael', 'TDC' ) ;
    insert into student ( sid, sname, smajor ) values ( 'a9', 'Dorothy', 'TDC' ) ;
    end ;
    /

    -- output
    Table MAJOR: no entry for CSC!
    Table MAJOR: row for CSC INSERTed.
    Student added to CSC group.
    Student added to CSC group.
    Table MAJOR: no entry for MIS!
    Table MAJOR: row for MIS INSERTed.
    Student added to MIS group.
    Student added to MIS group.
    Table MAJOR: no entry for TDC!
    Table MAJOR: row for TDC INSERTed.
    Student added to TDC group.
    Student added to TDC group.

    SQL> select * from major;
    MNAME MCOUNT
    CSC 3
    MIS 3
    TDC 3


    See dbfiddle here.



    Even if this works initially, it may be better to use a VIEW (and ditch the trigger(s)). Maybe you don't need the MAJOR table at all ...



    create or replace view major_vw
    as
    select
    smajor
    , count(smajor) as mcount
    from student
    group by smajor
    ;

    -- testing
    SQL> select * from major_vw;
    SMAJOR MCOUNT
    MIS 3
    CSC 3
    TDC 3


    See dbfiddle.






    share|improve this answer


























    • A DML can occur between SELECT..INTO and UPDATE clause. You should lock that row (eg FOR UPDATE) or do it with a single UPDATE statement.

      – Michael Kutz
      Mar 7 '18 at 22:00











    • @MichaelKutz - Thanks for pointing this out!

      – stefan
      Mar 8 '18 at 21:15











    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "182"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f199616%2ftrigger-inserting-into-a-row%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I think that counter is NULL because you don't assign it a value. And after you increment it, nothing changes because NULL + 1 = NULL. Also your UPDATE will not work if MCOUNT is not 0.



    Unrelated: I suggest to use a foreign key instead of CHECK.






    share|improve this answer




























      0














      I think that counter is NULL because you don't assign it a value. And after you increment it, nothing changes because NULL + 1 = NULL. Also your UPDATE will not work if MCOUNT is not 0.



      Unrelated: I suggest to use a foreign key instead of CHECK.






      share|improve this answer


























        0












        0








        0







        I think that counter is NULL because you don't assign it a value. And after you increment it, nothing changes because NULL + 1 = NULL. Also your UPDATE will not work if MCOUNT is not 0.



        Unrelated: I suggest to use a foreign key instead of CHECK.






        share|improve this answer













        I think that counter is NULL because you don't assign it a value. And after you increment it, nothing changes because NULL + 1 = NULL. Also your UPDATE will not work if MCOUNT is not 0.



        Unrelated: I suggest to use a foreign key instead of CHECK.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 7 '18 at 16:50









        Federico RazzoliFederico Razzoli

        794116




        794116

























            0














            You define a variable, counter. However, you never set it to a value, which means its value is NULL. 1 + NULL yields NULL.



            Note that this won't work as you want, anyway:




            • Even if you initialize counter to 0, that going to be done for each row. So, for every student, you'll have counter set to 1, and you'd set MCOUNT to 1, not the number of students with the major so far.

            • Since you're only setting MCOUNT if it is currently zero, even if counter was set to the number of students with the major, the UPDATE statement would only be run once, and MCOUNT would still always be 1.

            • Finally, you're not checking the students SMAJOR, and only updating the MAJOR record for that major. Whatever value MCOUNT holds for one major, it will hold for all of them.


            A couple of notes:




            • You can use the current value of MCOUNT to update MCOUNT. You do need to either make sure MCOUNT is either never NULL, or treat a NULL value in MCOUNT as a zero.

            • You need to make sure you're only updating MCOUNT for the major you're concerned with.


            Something like



                UPDATE MAJOR
            SET MCOUNT = NVL(MCOUNT, 0) + 1
            WHERE MAJOR = NEW.SMAJOR


            should work well.



            Also, of course, note that you need to handle changing counts if a student changes their major, or if a student is removed from the system.






            share|improve this answer


























            • MCOUNT could be NULL. It should read "SET MCOUNT = NVL( MCOUNT, 0) + 1"

              – Michael Kutz
              Mar 7 '18 at 21:58











            • @MichaelKutz - Excellent point; updated.

              – RDFozz
              Mar 7 '18 at 22:02
















            0














            You define a variable, counter. However, you never set it to a value, which means its value is NULL. 1 + NULL yields NULL.



            Note that this won't work as you want, anyway:




            • Even if you initialize counter to 0, that going to be done for each row. So, for every student, you'll have counter set to 1, and you'd set MCOUNT to 1, not the number of students with the major so far.

            • Since you're only setting MCOUNT if it is currently zero, even if counter was set to the number of students with the major, the UPDATE statement would only be run once, and MCOUNT would still always be 1.

            • Finally, you're not checking the students SMAJOR, and only updating the MAJOR record for that major. Whatever value MCOUNT holds for one major, it will hold for all of them.


            A couple of notes:




            • You can use the current value of MCOUNT to update MCOUNT. You do need to either make sure MCOUNT is either never NULL, or treat a NULL value in MCOUNT as a zero.

            • You need to make sure you're only updating MCOUNT for the major you're concerned with.


            Something like



                UPDATE MAJOR
            SET MCOUNT = NVL(MCOUNT, 0) + 1
            WHERE MAJOR = NEW.SMAJOR


            should work well.



            Also, of course, note that you need to handle changing counts if a student changes their major, or if a student is removed from the system.






            share|improve this answer


























            • MCOUNT could be NULL. It should read "SET MCOUNT = NVL( MCOUNT, 0) + 1"

              – Michael Kutz
              Mar 7 '18 at 21:58











            • @MichaelKutz - Excellent point; updated.

              – RDFozz
              Mar 7 '18 at 22:02














            0












            0








            0







            You define a variable, counter. However, you never set it to a value, which means its value is NULL. 1 + NULL yields NULL.



            Note that this won't work as you want, anyway:




            • Even if you initialize counter to 0, that going to be done for each row. So, for every student, you'll have counter set to 1, and you'd set MCOUNT to 1, not the number of students with the major so far.

            • Since you're only setting MCOUNT if it is currently zero, even if counter was set to the number of students with the major, the UPDATE statement would only be run once, and MCOUNT would still always be 1.

            • Finally, you're not checking the students SMAJOR, and only updating the MAJOR record for that major. Whatever value MCOUNT holds for one major, it will hold for all of them.


            A couple of notes:




            • You can use the current value of MCOUNT to update MCOUNT. You do need to either make sure MCOUNT is either never NULL, or treat a NULL value in MCOUNT as a zero.

            • You need to make sure you're only updating MCOUNT for the major you're concerned with.


            Something like



                UPDATE MAJOR
            SET MCOUNT = NVL(MCOUNT, 0) + 1
            WHERE MAJOR = NEW.SMAJOR


            should work well.



            Also, of course, note that you need to handle changing counts if a student changes their major, or if a student is removed from the system.






            share|improve this answer















            You define a variable, counter. However, you never set it to a value, which means its value is NULL. 1 + NULL yields NULL.



            Note that this won't work as you want, anyway:




            • Even if you initialize counter to 0, that going to be done for each row. So, for every student, you'll have counter set to 1, and you'd set MCOUNT to 1, not the number of students with the major so far.

            • Since you're only setting MCOUNT if it is currently zero, even if counter was set to the number of students with the major, the UPDATE statement would only be run once, and MCOUNT would still always be 1.

            • Finally, you're not checking the students SMAJOR, and only updating the MAJOR record for that major. Whatever value MCOUNT holds for one major, it will hold for all of them.


            A couple of notes:




            • You can use the current value of MCOUNT to update MCOUNT. You do need to either make sure MCOUNT is either never NULL, or treat a NULL value in MCOUNT as a zero.

            • You need to make sure you're only updating MCOUNT for the major you're concerned with.


            Something like



                UPDATE MAJOR
            SET MCOUNT = NVL(MCOUNT, 0) + 1
            WHERE MAJOR = NEW.SMAJOR


            should work well.



            Also, of course, note that you need to handle changing counts if a student changes their major, or if a student is removed from the system.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 7 '18 at 22:02

























            answered Mar 7 '18 at 16:51









            RDFozzRDFozz

            9,90231531




            9,90231531













            • MCOUNT could be NULL. It should read "SET MCOUNT = NVL( MCOUNT, 0) + 1"

              – Michael Kutz
              Mar 7 '18 at 21:58











            • @MichaelKutz - Excellent point; updated.

              – RDFozz
              Mar 7 '18 at 22:02



















            • MCOUNT could be NULL. It should read "SET MCOUNT = NVL( MCOUNT, 0) + 1"

              – Michael Kutz
              Mar 7 '18 at 21:58











            • @MichaelKutz - Excellent point; updated.

              – RDFozz
              Mar 7 '18 at 22:02

















            MCOUNT could be NULL. It should read "SET MCOUNT = NVL( MCOUNT, 0) + 1"

            – Michael Kutz
            Mar 7 '18 at 21:58





            MCOUNT could be NULL. It should read "SET MCOUNT = NVL( MCOUNT, 0) + 1"

            – Michael Kutz
            Mar 7 '18 at 21:58













            @MichaelKutz - Excellent point; updated.

            – RDFozz
            Mar 7 '18 at 22:02





            @MichaelKutz - Excellent point; updated.

            – RDFozz
            Mar 7 '18 at 22:02











            0














            For starters, you could use a trigger that picks up the mcount value from table MAJOR, and increments it (via an UPDATE) whenever a student is added to the STUDENT table. However, this will raise a NO_DATA_FOUND exception when the MAJOR table is empty. Thus, we start populating the MAJOR table (with an INSERT) in this situation.



            -- create the 2 tables, then compile the trigger

            create or replace trigger addstudent
            after insert on student
            for each row
            declare
            counter number(3) := 0 ;
            begin
            select mcount into counter
            from major
            where mname = upper( :new.smajor )
            for update ;

            dbms_output.put_line( 'Student added to ' || :new.smajor || ' group.' );
            counter := counter + 1;
            update major
            set mcount = counter
            where mname = :new.smajor ;
            exception
            when no_data_found then
            dbms_output.put_line( 'Table MAJOR: no entry for ' || :new.smajor || '!' ) ;
            insert into major ( mname, mcount ) values ( :new.smajor, 1 ) ;
            dbms_output.put_line( 'Table MAJOR: row for ' || :new.smajor || ' INSERTed.') ;
            end;
            /

            Trigger ADDSTUDENT compiled


            Testing



            begin
            insert into student ( sid, sname, smajor ) values ( 'a1', 'Frank', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a2', 'Lorna', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a3', 'Colin', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a4', 'Harriet', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a5', 'Michael', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a6', 'Dorothy', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a7', 'Harriet', 'TDC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a8', 'Michael', 'TDC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a9', 'Dorothy', 'TDC' ) ;
            end ;
            /

            -- output
            Table MAJOR: no entry for CSC!
            Table MAJOR: row for CSC INSERTed.
            Student added to CSC group.
            Student added to CSC group.
            Table MAJOR: no entry for MIS!
            Table MAJOR: row for MIS INSERTed.
            Student added to MIS group.
            Student added to MIS group.
            Table MAJOR: no entry for TDC!
            Table MAJOR: row for TDC INSERTed.
            Student added to TDC group.
            Student added to TDC group.

            SQL> select * from major;
            MNAME MCOUNT
            CSC 3
            MIS 3
            TDC 3


            See dbfiddle here.



            Even if this works initially, it may be better to use a VIEW (and ditch the trigger(s)). Maybe you don't need the MAJOR table at all ...



            create or replace view major_vw
            as
            select
            smajor
            , count(smajor) as mcount
            from student
            group by smajor
            ;

            -- testing
            SQL> select * from major_vw;
            SMAJOR MCOUNT
            MIS 3
            CSC 3
            TDC 3


            See dbfiddle.






            share|improve this answer


























            • A DML can occur between SELECT..INTO and UPDATE clause. You should lock that row (eg FOR UPDATE) or do it with a single UPDATE statement.

              – Michael Kutz
              Mar 7 '18 at 22:00











            • @MichaelKutz - Thanks for pointing this out!

              – stefan
              Mar 8 '18 at 21:15
















            0














            For starters, you could use a trigger that picks up the mcount value from table MAJOR, and increments it (via an UPDATE) whenever a student is added to the STUDENT table. However, this will raise a NO_DATA_FOUND exception when the MAJOR table is empty. Thus, we start populating the MAJOR table (with an INSERT) in this situation.



            -- create the 2 tables, then compile the trigger

            create or replace trigger addstudent
            after insert on student
            for each row
            declare
            counter number(3) := 0 ;
            begin
            select mcount into counter
            from major
            where mname = upper( :new.smajor )
            for update ;

            dbms_output.put_line( 'Student added to ' || :new.smajor || ' group.' );
            counter := counter + 1;
            update major
            set mcount = counter
            where mname = :new.smajor ;
            exception
            when no_data_found then
            dbms_output.put_line( 'Table MAJOR: no entry for ' || :new.smajor || '!' ) ;
            insert into major ( mname, mcount ) values ( :new.smajor, 1 ) ;
            dbms_output.put_line( 'Table MAJOR: row for ' || :new.smajor || ' INSERTed.') ;
            end;
            /

            Trigger ADDSTUDENT compiled


            Testing



            begin
            insert into student ( sid, sname, smajor ) values ( 'a1', 'Frank', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a2', 'Lorna', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a3', 'Colin', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a4', 'Harriet', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a5', 'Michael', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a6', 'Dorothy', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a7', 'Harriet', 'TDC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a8', 'Michael', 'TDC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a9', 'Dorothy', 'TDC' ) ;
            end ;
            /

            -- output
            Table MAJOR: no entry for CSC!
            Table MAJOR: row for CSC INSERTed.
            Student added to CSC group.
            Student added to CSC group.
            Table MAJOR: no entry for MIS!
            Table MAJOR: row for MIS INSERTed.
            Student added to MIS group.
            Student added to MIS group.
            Table MAJOR: no entry for TDC!
            Table MAJOR: row for TDC INSERTed.
            Student added to TDC group.
            Student added to TDC group.

            SQL> select * from major;
            MNAME MCOUNT
            CSC 3
            MIS 3
            TDC 3


            See dbfiddle here.



            Even if this works initially, it may be better to use a VIEW (and ditch the trigger(s)). Maybe you don't need the MAJOR table at all ...



            create or replace view major_vw
            as
            select
            smajor
            , count(smajor) as mcount
            from student
            group by smajor
            ;

            -- testing
            SQL> select * from major_vw;
            SMAJOR MCOUNT
            MIS 3
            CSC 3
            TDC 3


            See dbfiddle.






            share|improve this answer


























            • A DML can occur between SELECT..INTO and UPDATE clause. You should lock that row (eg FOR UPDATE) or do it with a single UPDATE statement.

              – Michael Kutz
              Mar 7 '18 at 22:00











            • @MichaelKutz - Thanks for pointing this out!

              – stefan
              Mar 8 '18 at 21:15














            0












            0








            0







            For starters, you could use a trigger that picks up the mcount value from table MAJOR, and increments it (via an UPDATE) whenever a student is added to the STUDENT table. However, this will raise a NO_DATA_FOUND exception when the MAJOR table is empty. Thus, we start populating the MAJOR table (with an INSERT) in this situation.



            -- create the 2 tables, then compile the trigger

            create or replace trigger addstudent
            after insert on student
            for each row
            declare
            counter number(3) := 0 ;
            begin
            select mcount into counter
            from major
            where mname = upper( :new.smajor )
            for update ;

            dbms_output.put_line( 'Student added to ' || :new.smajor || ' group.' );
            counter := counter + 1;
            update major
            set mcount = counter
            where mname = :new.smajor ;
            exception
            when no_data_found then
            dbms_output.put_line( 'Table MAJOR: no entry for ' || :new.smajor || '!' ) ;
            insert into major ( mname, mcount ) values ( :new.smajor, 1 ) ;
            dbms_output.put_line( 'Table MAJOR: row for ' || :new.smajor || ' INSERTed.') ;
            end;
            /

            Trigger ADDSTUDENT compiled


            Testing



            begin
            insert into student ( sid, sname, smajor ) values ( 'a1', 'Frank', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a2', 'Lorna', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a3', 'Colin', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a4', 'Harriet', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a5', 'Michael', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a6', 'Dorothy', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a7', 'Harriet', 'TDC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a8', 'Michael', 'TDC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a9', 'Dorothy', 'TDC' ) ;
            end ;
            /

            -- output
            Table MAJOR: no entry for CSC!
            Table MAJOR: row for CSC INSERTed.
            Student added to CSC group.
            Student added to CSC group.
            Table MAJOR: no entry for MIS!
            Table MAJOR: row for MIS INSERTed.
            Student added to MIS group.
            Student added to MIS group.
            Table MAJOR: no entry for TDC!
            Table MAJOR: row for TDC INSERTed.
            Student added to TDC group.
            Student added to TDC group.

            SQL> select * from major;
            MNAME MCOUNT
            CSC 3
            MIS 3
            TDC 3


            See dbfiddle here.



            Even if this works initially, it may be better to use a VIEW (and ditch the trigger(s)). Maybe you don't need the MAJOR table at all ...



            create or replace view major_vw
            as
            select
            smajor
            , count(smajor) as mcount
            from student
            group by smajor
            ;

            -- testing
            SQL> select * from major_vw;
            SMAJOR MCOUNT
            MIS 3
            CSC 3
            TDC 3


            See dbfiddle.






            share|improve this answer















            For starters, you could use a trigger that picks up the mcount value from table MAJOR, and increments it (via an UPDATE) whenever a student is added to the STUDENT table. However, this will raise a NO_DATA_FOUND exception when the MAJOR table is empty. Thus, we start populating the MAJOR table (with an INSERT) in this situation.



            -- create the 2 tables, then compile the trigger

            create or replace trigger addstudent
            after insert on student
            for each row
            declare
            counter number(3) := 0 ;
            begin
            select mcount into counter
            from major
            where mname = upper( :new.smajor )
            for update ;

            dbms_output.put_line( 'Student added to ' || :new.smajor || ' group.' );
            counter := counter + 1;
            update major
            set mcount = counter
            where mname = :new.smajor ;
            exception
            when no_data_found then
            dbms_output.put_line( 'Table MAJOR: no entry for ' || :new.smajor || '!' ) ;
            insert into major ( mname, mcount ) values ( :new.smajor, 1 ) ;
            dbms_output.put_line( 'Table MAJOR: row for ' || :new.smajor || ' INSERTed.') ;
            end;
            /

            Trigger ADDSTUDENT compiled


            Testing



            begin
            insert into student ( sid, sname, smajor ) values ( 'a1', 'Frank', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a2', 'Lorna', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a3', 'Colin', 'CSC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a4', 'Harriet', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a5', 'Michael', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a6', 'Dorothy', 'MIS' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a7', 'Harriet', 'TDC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a8', 'Michael', 'TDC' ) ;
            insert into student ( sid, sname, smajor ) values ( 'a9', 'Dorothy', 'TDC' ) ;
            end ;
            /

            -- output
            Table MAJOR: no entry for CSC!
            Table MAJOR: row for CSC INSERTed.
            Student added to CSC group.
            Student added to CSC group.
            Table MAJOR: no entry for MIS!
            Table MAJOR: row for MIS INSERTed.
            Student added to MIS group.
            Student added to MIS group.
            Table MAJOR: no entry for TDC!
            Table MAJOR: row for TDC INSERTed.
            Student added to TDC group.
            Student added to TDC group.

            SQL> select * from major;
            MNAME MCOUNT
            CSC 3
            MIS 3
            TDC 3


            See dbfiddle here.



            Even if this works initially, it may be better to use a VIEW (and ditch the trigger(s)). Maybe you don't need the MAJOR table at all ...



            create or replace view major_vw
            as
            select
            smajor
            , count(smajor) as mcount
            from student
            group by smajor
            ;

            -- testing
            SQL> select * from major_vw;
            SMAJOR MCOUNT
            MIS 3
            CSC 3
            TDC 3


            See dbfiddle.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 8 '18 at 21:14

























            answered Mar 7 '18 at 20:58









            stefanstefan

            2,152139




            2,152139













            • A DML can occur between SELECT..INTO and UPDATE clause. You should lock that row (eg FOR UPDATE) or do it with a single UPDATE statement.

              – Michael Kutz
              Mar 7 '18 at 22:00











            • @MichaelKutz - Thanks for pointing this out!

              – stefan
              Mar 8 '18 at 21:15



















            • A DML can occur between SELECT..INTO and UPDATE clause. You should lock that row (eg FOR UPDATE) or do it with a single UPDATE statement.

              – Michael Kutz
              Mar 7 '18 at 22:00











            • @MichaelKutz - Thanks for pointing this out!

              – stefan
              Mar 8 '18 at 21:15

















            A DML can occur between SELECT..INTO and UPDATE clause. You should lock that row (eg FOR UPDATE) or do it with a single UPDATE statement.

            – Michael Kutz
            Mar 7 '18 at 22:00





            A DML can occur between SELECT..INTO and UPDATE clause. You should lock that row (eg FOR UPDATE) or do it with a single UPDATE statement.

            – Michael Kutz
            Mar 7 '18 at 22:00













            @MichaelKutz - Thanks for pointing this out!

            – stefan
            Mar 8 '18 at 21:15





            @MichaelKutz - Thanks for pointing this out!

            – stefan
            Mar 8 '18 at 21:15


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Database Administrators Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f199616%2ftrigger-inserting-into-a-row%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            ORA-01691 (unable to extend lob segment) even though my tablespace has AUTOEXTEND onORA-01692: unable to...

            Always On Availability groups resolving state after failover - Remote harden of transaction...

            Circunscripción electoral de Guipúzcoa Referencias Menú de navegaciónLas claves del sistema electoral en...