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
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
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.
add a comment |
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
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 fororacle
questions, they probably also want to seeoracle-11g
questions.
– RDFozz
Mar 7 '18 at 16:54
add a comment |
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
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
oracle trigger plsql
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 fororacle
questions, they probably also want to seeoracle-11g
questions.
– RDFozz
Mar 7 '18 at 16:54
add a comment |
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 fororacle
questions, they probably also want to seeoracle-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
add a comment |
3 Answers
3
active
oldest
votes
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
.
add a comment |
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 havecounter
set to 1, and you'd setMCOUNT
to 1, not the number of students with the major so far. - Since you're only setting
MCOUNT
if it is currently zero, even ifcounter
was set to the number of students with the major, theUPDATE
statement would only be run once, andMCOUNT
would still always be 1. - Finally, you're not checking the students
SMAJOR
, and only updating theMAJOR
record for that major. Whatever valueMCOUNT
holds for one major, it will hold for all of them.
A couple of notes:
- You can use the current value of
MCOUNT
to updateMCOUNT
. You do need to either make sureMCOUNT
is either never NULL, or treat a NULL value inMCOUNT
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.
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
add a comment |
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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
.
add a comment |
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
.
add a comment |
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
.
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
.
answered Mar 7 '18 at 16:50
Federico RazzoliFederico Razzoli
794116
794116
add a comment |
add a comment |
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 havecounter
set to 1, and you'd setMCOUNT
to 1, not the number of students with the major so far. - Since you're only setting
MCOUNT
if it is currently zero, even ifcounter
was set to the number of students with the major, theUPDATE
statement would only be run once, andMCOUNT
would still always be 1. - Finally, you're not checking the students
SMAJOR
, and only updating theMAJOR
record for that major. Whatever valueMCOUNT
holds for one major, it will hold for all of them.
A couple of notes:
- You can use the current value of
MCOUNT
to updateMCOUNT
. You do need to either make sureMCOUNT
is either never NULL, or treat a NULL value inMCOUNT
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.
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
add a comment |
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 havecounter
set to 1, and you'd setMCOUNT
to 1, not the number of students with the major so far. - Since you're only setting
MCOUNT
if it is currently zero, even ifcounter
was set to the number of students with the major, theUPDATE
statement would only be run once, andMCOUNT
would still always be 1. - Finally, you're not checking the students
SMAJOR
, and only updating theMAJOR
record for that major. Whatever valueMCOUNT
holds for one major, it will hold for all of them.
A couple of notes:
- You can use the current value of
MCOUNT
to updateMCOUNT
. You do need to either make sureMCOUNT
is either never NULL, or treat a NULL value inMCOUNT
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.
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
add a comment |
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 havecounter
set to 1, and you'd setMCOUNT
to 1, not the number of students with the major so far. - Since you're only setting
MCOUNT
if it is currently zero, even ifcounter
was set to the number of students with the major, theUPDATE
statement would only be run once, andMCOUNT
would still always be 1. - Finally, you're not checking the students
SMAJOR
, and only updating theMAJOR
record for that major. Whatever valueMCOUNT
holds for one major, it will hold for all of them.
A couple of notes:
- You can use the current value of
MCOUNT
to updateMCOUNT
. You do need to either make sureMCOUNT
is either never NULL, or treat a NULL value inMCOUNT
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.
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 havecounter
set to 1, and you'd setMCOUNT
to 1, not the number of students with the major so far. - Since you're only setting
MCOUNT
if it is currently zero, even ifcounter
was set to the number of students with the major, theUPDATE
statement would only be run once, andMCOUNT
would still always be 1. - Finally, you're not checking the students
SMAJOR
, and only updating theMAJOR
record for that major. Whatever valueMCOUNT
holds for one major, it will hold for all of them.
A couple of notes:
- You can use the current value of
MCOUNT
to updateMCOUNT
. You do need to either make sureMCOUNT
is either never NULL, or treat a NULL value inMCOUNT
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.
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
add a comment |
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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 seeoracle-11g
questions.– RDFozz
Mar 7 '18 at 16:54