Home » SQL & PL/SQL » SQL & PL/SQL » how to use PL/SQL in a before insert trigger to check a value.
how to use PL/SQL in a before insert trigger to check a value. [message #623738] Sat, 13 September 2014 11:46 Go to next message
mattfriend
Messages: 12
Registered: September 2014
Junior Member
Hi Folks

I'm relatively new to PL/SQL and I've been trying to figure out how to do this code/check in a before insert trigger.

Info: I have two tables, BALES_FED, and GRAZING_RECORDS (I have included their structure at the bottom of this post and a diagram pic. They are linked through the PASTURE field.


Background: Before I let a record be saved in the BALES_FED table, I need to ensure that the Pasture the user had selected (from a select list/combo box) is allowed. Choosing a particular pasture is only allowed if there are animals currently in that particular pasture or they were there in the last day (i.e. current data or current data -1) from when the hay was fed. There are over 1500 possible pasture and we want the end users to only be able to select a pasture and save the record if there were animals in that pasture when they were fed (to make sure they have selected the right pasture, etc.)

I need to ensure that the DATE_FED column in the BALES_FED table falls within that time. The GRAZING_RECORDS table has a DATE_IN and a DATE_OUT columns. If there is a DATE_IN, but the DATE_OUT is null the record can be saved since the animals are still in the pasture (This is shown because since there is no DATE_OUT). If there is a DATE_OUT value saved, then I need to check to see if the value in the DATE_FED column in the BALES_FED table is = or after the DATE_IN column and is < or = to the DATE_OUT to allow the record to be saved.



There might be a better way, but my thought was to check the value of the DATE_FED column using a before insert trigger when the end user tries to save the record. If the value they have selected in the DATE_FED column does not meet the constraints listed above, then they should receive an error message and the data should not be saved.

Here is the table structure:


http://cwebpro.com/BALES_FED_GRAZING_RECORDS.png

CREATE TABLE "FARMING"."BALES_FED" (

               "BALES_FED" NUMBER (5, 0) DEFAULT NULL,

               "CROP" VARCHAR2 (20 CHAR),

               "CUTTING" NUMBER (5, 0),

               "STACKYARD" VARCHAR2 (25),

               "DATE_FED" DATE,

               "PASTURE" VARCHAR2 (12),

               "TARGET_LB_PER_DAY" NUMBER (3, 1),

               "FED_ID" NUMBER (15, 0),

               "SPECIES" VARCHAR2 (30),

               "BALE_YEAR" VARCHAR2 (4)

) 
--------------------------------------------------------

--  DDL for Table GRAZING_RECORDS

--------------------------------------------------------

CREATE TABLE "CATTLE"."GRAZING_RECORDS" (

               "PASTURE" VARCHAR2 (12),

               "GROUP_DESCRIPTION" VARCHAR2 (50),

               "DATE_IN" DATE,

               "DATE_OUT" DATE,

               "HEAD_COUNT" NUMBER (3, 0),

               "ANIMAL_UNIT_EQUIVALENT" NUMBER (3, 2),

               "MULTI_PASTURE_USAGE" NUMBER (3, 0),

               "COMMENTS" VARCHAR2 (200),

               "POLE_SHED" VARCHAR2 (8),

               "FEEDING_LEVEL" VARCHAR2 (25),

               "OFFSPRING_AUE" NUMBER (3, 2),

               "SPECIES" VARCHAR2 (12)

)



For my select list I am using the following view. This view makes it much easier for them to select a pasture from the select list since it cuts down the possible choices from about 1500 to about 60 or so. The problem with it though is the original data is written to paper first and the end user may not enter the data into the database until a few days later so I need to check to ensure that the date entered for the DATE_FED column is allowed.



Thank you for any help.... I hope this wasn't too confusing.



Matthew



View I use to limit the pasture select list:

SELECT cattle.grazing_records.pasture, 
       cattle.grazing_records.group_description, 
       cattle.grazing_records.date_in, 
       cattle.grazing_records.date_out, 
       cattle.grazing_records.head_count, 
       cattle.grazing_records.animal_unit_equivalent, 
       cattle.grazing_records.multi_pasture_usage, 
       cattle.grazing_records.comments, 
       cattle.grazing_records.pole_shed, 
       cattle.grazing_records.feeding_level, 
       cattle.grazing_records.offspring_aue, 
       cattle.grazing_records.species 
FROM   cattle.grazing_records 
WHERE  cattle.grazing_records.date_out IS NULL 
        OR cattle.grazing_records.date_out = Trunc(SYSDATE - 1) 
        OR cattle.grazing_records.date_out = Trunc(SYSDATE - 2) 
        OR cattle.grazing_records.date_out = Trunc(SYSDATE - 3) 
ORDER  BY cattle.grazing_records.pasture ASC, 
          cattle.grazing_records.date_in ASC 



Lalit : Formatted the code and added code tags.

[Updated on: Sun, 14 September 2014 03:10] by Moderator

Report message to a moderator

Re: how to use PL/SQL in a before insert trigger to check a value. [message #623741 is a reply to message #623738] Sat, 13 September 2014 12:39 Go to previous messageGo to next message
Michel Cadot
Messages: 68641
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Database Application Developer's Guide - Fundamentals
Chapter 9 Coding Triggers

Re: how to use PL/SQL in a before insert trigger to check a value. [message #623742 is a reply to message #623741] Sat, 13 September 2014 13:08 Go to previous messageGo to next message
Littlefoot
Messages: 21807
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
Here are my thoughts (you may, but don't have to agree with me).

First of all: how do you enter data into the database? I guess users don't do that directly, using SQL*Plus or any other tool which directly communicates with the database. I suppose that it is some kind of an application. Let's just suppose that it is a Forms application.

If you code a database trigger, users won't be too happy because they will already enter all data, push the "Save" button and be surprised by an error message raised by the database.

Therefore, why wouldn't you do act proactively? Forms offer "list of values" which is, basically, result of a SELECT statement. As you want to restrict number of pastures (from their maximum number of some 1500 to only allowed ones (~60, as you said)), you'd attach list of values to the PASTURE item and make sure that users can NOT enter any other pasture (except the ones returned by the list of values); if they try to do that, application raises an error and says "no, you can't enter that pasture - select one from the list of values". Forms do that itself (by setting one of item's properties); you might do that in a different manner in a tool you use.

List of values query would be similar to the one you already wrote; however, instead of referencing SYSDATE (and subtracting one, two ... who-knows-how-many days from it - which is most probably wrong as you can't think that way) you'd reference DATE_FED user enters on the screen, before navigating to the PASTURE item. Something like this:
select 
  g.pasture
from grazing_records g
where     g.date_in <= :application.date_fed_item
  and (   g.date_out is null                           -- animals still there
       or g.date_out = :application.date_fed_item - 1  -- animals left "yesterday"
      )
order by g.pasture  

Re: how to use PL/SQL in a before insert trigger to check a value. [message #623745 is a reply to message #623742] Sat, 13 September 2014 16:00 Go to previous messageGo to next message
mattfriend
Messages: 12
Registered: September 2014
Junior Member
Thank you for the responses, especially Littlefoot.

Littlefoot:

I have been using a PHP/Oracle program (PHPMaker 11) that connects to our Oracle database. There is no place to insert/save PL/SQL code within the program which is why I was thinking a trigger is the way to go. I have limited javascript/php knowledge but there is a place where I can use regex code to help validate many of the fields on the user interface.

I have some experience implementing basic triggers (for Primary Keys, copying data that is entered to another table, etc.) but haven't had much luck implementing IF/Else statemetents while trying to figure this out.

Matthew

P.S. on a side note, the last time I had tried out Oracle Apex was back in version 3 (started with version 2, then a little in 3). There were some limitations (like only allowing x2 PK's) that kept me from using it much and I eventually had to switch. I've been 'playing' with the new Apex 5.0 Preview 2 and really like it. I would hate to have to code this entire project (there are a couple dozen different pages/screens) all over again, but will likely use it for any future projects. We currently have a lot of our data entry screens in Oracle Forms, but many of our end users use tablets/smaller devices and it doesn't scale well.
Re: how to use PL/SQL in a before insert trigger to check a value. [message #623750 is a reply to message #623745] Sun, 14 September 2014 00:50 Go to previous message
Littlefoot
Messages: 21807
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
I see ... Unfortunately, I don't speak PHP so I can't assist. I do use Apex, though (4.2 currently); it offers a "mobile" template for tablets or smart phones. I understand that you won't code the whole application just for that problem.
Previous Topic: Frequency of sub-programs used in database
Next Topic: Duplicate rows
Goto Forum:
  


Current Time: Thu Apr 18 23:05:45 CDT 2024