Is it possible to create master-detail relationship in Oracle Forms when both of the blocks are based on procedure? - oracle

I have two blocks that are based on procedure and I want to create master-detail relationship between them.
I do this using Data Block Wizzard. It create trigger ON-CHECK-DELETE-MASTER, this trigger assumes that my detail block is based on table (FRL_XXX.TRIGGERS_QUERY, but it is a procedure) and generates cursor:
CURSOR TRIGGERS_cur IS
SELECT 1 FROM FRL_XXX.TRIGGERS_QUERY F
WHERE F.PTG_PST_CODE = :S_TYPES.PST_CODE;
Is there any workaround to solve this problem?
When I try delete this trigger or remove the cursor I get error:
FRM-30409: Delete Record Behavior for the relation is invalid.

I've never done that, but - let me think aloud.
If data block is based on a procedure, it means that procedure returns (as its IN OUT parameter) an array. I'd say that you'll have to
create your own trigger (i.e. replace the one created by the Wizard
note that these triggers usually have a comment "don't modify it!". If you run the Wizard again, it might overwrite your code, so safer approach is to create a procedure which will do the job, and call that procedure from the trigger
declare a local variable (array) and fetch data into it; pass all parameters to the procedure as you did while calling it in order to populate data block
review array's contents and check whether there's any row that satisfies condition PTG_PST_CODE = :S_TYPES.PST_CODE
if so, do what Wizard's trigger does in that case
Basically, I think that you'll have to write your own process which will replace default Forms behavior.

In Procedure based blocks, If you choose the Relation type as Isolated , Oracle form will allow the Master Detail relationship between two blocks because in that case ON-CHECK-DELETE-MASTER trigger won't be there.
You will be able to retrieve the records from detail block as ON-POPULATE-DETAILS trigger will work as-usual.
In my case, only detail block was based on Procedure and it's working fine.
Note : Isolated type of relationship will delete the master records even if child records exist. You need to handle this case separately.
Please share your approach step by step, if you went ahead as per littlefoot

Related

i have two table with foreign key and i want to press in foreign key in first table and the second table appear data

I have two blocks. First one is wizard and second is manual in Oracle Forms 11g with relational.
I execute the data into first block and I want to press in foreign key in first table and the second table appear data which is link together by the same number foreign key?
Which trigger should I use please? And which code should I put into trigger?
You can use WHEN-NEW-RECORD-INSTANCE trigger at block level of Block1 with code :
declare
v_skulist table1.skulist%type;
begin
v_skulist := :Block1.f_skulist; --> represents left uppermost field
go_block('Block2');
execute_query;
go_block('Block1'); --> go back to the upper block again, if don't want to come back, then starting from this line upto `end;`(exclusive) should be removed.
while v_skulist != :Block1.f_skulist
loop
next_record;
end loop;
end;
where
Query Data Source Name property is set to table1 for Block1
and
Query Data Source Name property is set to myuser1.table2 with
WHERE Clause set to
skulist = :Block1.skulist for Block2
assuming the second table is on the other user at least
with granted select privilege to your current user as mentioned in your comment.
This way, whatever record touched in the first block, the counterpart foreign key column is brought in the second block.
You should have used the data block wizard which creates all necessary triggers and procedures that take care about it.
If you're going to do it manually, well ... you probably shouldn't do that, there are too many procedures involved.
I suggest you remove detail block and create it from scratch, this time using the wizard. Pay attention to what it asks and - once you're done - the form will automatically do what you want it to.
Then, you can review what objects Forms created for you and - if you really REALLY want to do it manually, try to mimic its steps.

Oracle PL/SQL Select all Columns from Trigger's :NEW

I have a trigger that calls a stored procedure when activated, passing :NEW values as a parameter. I have about 40 tables that use the same trigger, and I would like to use the same code for each trigger. Therefore, I am trying to pass all columns of a new row. My code is below and shows what I am attempting to do (however, the problem is that :NEW.* is not a valid expression):
CREATE OR REPLACE TRIGGER "TRIG_TEST_TRIGGER"
AFTER INSERT OR DELETE OR UPDATE ON TRIG_TEST
FOR EACH ROW
DECLARE
BEGIN
MY_STORED_PROC('Trigger Activated: ' || :NEW.*);
END;
Most likely, you can't.
You could write a procedure that uses dynamic SQL to generate the appropriate trigger code for each table. Of course, that would require that you re-run the procedure to re-create the trigger every time the table changes.
I'm a bit hard-pressed, though, to imagine what my_stored_proc might be doing that it would make sense to pass it a string representing every column from 1 of 40 tables with, presumably, 40 different sets of columns. If you're writing to a log table, if you want the data from every column, that generally implies that you want to be able to see the evolution of a particular row over time. But that is extremely hard to do if your log table just has strings in all sorts of different formats from many different tables since you'd constantly have to do things like parsing the string that you logged.

Oracle error: ORA-04079: invalid trigger specification

I am new to Oracle and would like to know how to make this trigger work please. I can do each trigger separately but I need them all in the same one if that makes sense.
create trigger ID_trigger
before insert on crime, evidence, offence, officer
for each row
begin
select crime_seq.nextval into :new.crime_id from dual
and officer_seq.nextval into :new.officer_id from dual
and evidence_seq.nextval into :new.evidence_id from dual
and offence_seq.nextval into :new.offence_id from dual;
end;
I initially had a single trigger for each table. However when submitting data into my form the triggers seemed to have overwritten the previous one
" I initially had a singler trigger for each table, however when
sumbitting data into my form the triggers seemed to have overwritten
the previous one"
Let's guess: you called all four triggers id_trigger. Each subsequent CREATE OR REPLACE TRIGGER call would overwrite the first one. Unless you used CREATE TRIGGER as you do here, in which case each subsequent call would fail, Either way, only one table would have a trigger.
You see, even though they belong to a table, triggers are separate database objects. So, like indexes or constraints, their names must be unique within the schema.
The solution is simple: give each trigger a different name, say by including the table name.

Oracle: Monitoring changes in v_$parameter

Long time user, first time "asker".
I am attempt to construct an Oracle procedure and/or trigger that will compare two tables with the MINUS operation and then insert any resulting rows into another table. I understand how to do the query in standard SQL, but I am having trouble coming up with an efficient way to do this using PL/SQL.
Admittedly, I am very new to Oracle and pretty green with SQL in general. This may be a silly way to go about accomplishing my goal, so allow me to explain what I am attempting to do.
I need to create some sort of alert that will be triggered when the V_$PARAMETER view is changed. Apparently triggers can not respond to changes to view but, instead, can only replace actions on views...which I do not wish to do. So, what I did was create a table that to mirror that view to essentially save it as a "snapshot".
create table mirror_v_$parameter as select * from v_$parameter;
Then, I attempted to make a procedure that would minus these two so that, whenever a change is made to v_$parameter, it will return the difference between the snapshot, mirror_v_$parameter. I trying to create a cursor with the command:
select * from v_$parameter minus select * from mirror_v_$parameter;
to be used inside a procedure, so that it could be used to fetch any returned rows and insert them into another table called alerts_v_$parameter. The intent being that, when something is added to the "alert" table, a trigger can be used to somehow (haven't gotten this far yet) notify my team that there has been a change to the v_$parameter table, and that they can refer to alerts_v_$parameter to see what has been change. I would use some kind of script to run this procedure at a regular interval. And maybe, some day down the line when I understand all this better, manipulate what goes into the alerts_v_$parameter table so that it provides better information such as specifically what column was changed, what was its previous value, etc.
Any advice or pointers?
Thank you for taking the time to read this. Any thoughts will be very appreciated.
I would create a table based on the exact structure of v_$parameter with an additional timestamp column for "last_update", and periodically (via DBMS_Scheduler) merge into it any changes from the real v_$parameter table and capture the timestamp of any detected change.
You might also populate a history table at the same time, either using triggers on update of your table or with SQL.
PL/SQL is unlikely to be required, except as a procedural wrapper to the SQL code.
Examples of Merge are in the documentation here: http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_9016.htm#SQLRF01606

How to fire a trigger after finishing data insert in a table

I have a table A into which I am inserting data. Then some calculation is being done updating the same table A.
I want to fire a trigger, which calls a Procedure A after the completion of data insertion ( after insert and update ).
How do I do this?
Is there any other way to do it automatically... Or do I have to run Procedure A manualy after the completion of data insertion in table A.
More simply, I would like to know how to fire a trigger after inserting a few rows and a commit, i.e. not for each row.
You can define your trigger to be fired for each row or for each statement (FOR EACH ROW option).
If I understood you right, you would like to fire the trigger after a bunch of statements? Don't think you can. Even if you can, I would rather not do it. They scatter your program flow / logic and make it harder to understand later how your software works.
Regards
If I understand your question correctly, you want the trigger to fire after you completed your transaction consisting of several insert/update statements? If that is the case, I think you should consider calling your Procedure A in your program flow right after the insert/update operations are done.
In other words: A trigger would only be useful, if it should be called for each row or for each statement.
Add one column to your table: e.g "FINAL_ACTION". Leave this column untouched untill your anticipated final action. Then have your trigger get fired only with this clause:
REFERENCING NEW AS NEWREC OLD AS OLDREC
FOR EACH ROW
WHEN (NEWREC.FINAL_ACTION <> OLDREC.FINAL_ACTION)
DECLARE
--YOUR DECLARATIONS
BEGIN
--DO SOMETHING
END;

Resources