I am a beginner to SQL, so bear with me.
I’m trying to create a trigger in SQL. This code is giving me trouble:
select brw.borage, bt.agelower, bt.ageupper
into borage, minage, maxage
from borrower brw
inner join loan ln on ln.borid = brw.borid
inner join bookcopy bc on ln.bcid = bc.bcid
inner join booktitle bt on bt.isbn = bc.isbn
where ln.bcid = :new.bcid
and ln.borid = :new.borid;
-- and ln.dateout = :new.dateout;
The primary key in the loan table is composed of “bcID”, “borID” and “dateOut”.
When I comment out the last line, I get the newly added line(s) to the table.
With the last line uncommented though, it won’t work!
I just get this error (with the line uncommented):
Row 34: ORA-01403: no data found
ORA-01403: no data found
meaning oracle did not find any rows that match the query criteria.
NOTE: When I uncomment the line, I also remove the semicolon above it.
OK. First off, a row-level trigger on table
Ashould not query tableA. In general, doing so is going to generate an “ORA-04091: table is mutating” error. Since your trigger is defined onLOAN, the query should not reference theLOANtable. It should only reference the data for the current row in the:NEWrecord.That being the case, you probably want something like this (note that I’m guessing about the cardinality of the relationships between the tables here)
You could combine the two queries but I don’t see an easy way to do that without making the result more complex than you probably want.
Additionally, you really want to avoid having local variables that share the name of a column in your database (like
borage). That tends to generate rather puzzling scope resolution bugs. For example, using theSCOTT.EMPtableThere are no employees with an
EMPNOof -17But when I write a simple PL/SQL block that tries to count the number of employees with an
EMPNOof -17, the result I get is 14. Can you spot the bug?The problem is that when I wrote
e.empno = empno, I clearly intended the left-hand side of the expression to reference theEMPNOcolumn in theEMPtable and the right-hand side of the expression to reference the local variableEMPNO. Unfortunately for me, however, Oracle resolves the unqualifiedEMPNOfirst to a column in the table and only then to the local variable of the same name. If you’re using named PL/SQL blocks, you can work around that by using the name of the block as the alias for the local variable but virtually no one ever does that.Instead, in order to avoid these sorts of problems, most developers will use some sort of distinctive prefix for variable names. For example, I use
P_as the prefix for parameter names,L_as the prefix for local variables, andG_as the prefix for package global variables. That’s a relatively common convention but other conventions exist. The important thing is just to have some way of ensuring that you never have a local variable and a column name that use the same name.