Oracle PL / SQL - Exemple INSTEAD OF Trigger
Cet article vous montre comment utiliserINSTEAD OF TRIGGER
pour mettre à jour
-
Une vue sans édition
-
Une colonne de table imbriquée d'une vue sans édition
Ces déclencheursINSTEAD OF
fournissent un moyen de modifier lesviews
qui ne peuvent pas être modifiés directement via des instructions DML comme INSERT, UPDATE et DELETE
Un déclencheur INSTEAD OF est
-
Toujours un déclencheur au niveau des lignes.
-
Peut lire les valeurs ANCIENNES et NOUVELLES, mais ne peut pas les modifier.
-
Ne peut pas être conditionnel. Cela signifie que nous ne pouvons pas ajouter de condition WHEN ou IF.
1. Insérer des données dans une vue
Dans cet exemple, nous avons créé un déclencheurINSTEAD OF
qui insérera des lignes dans les tables respectives d'unview
lorsque nous exécutons l'instruction d'insertion sur une vue.
1.1 Create tables.
Détails du client
CREATE TABLE customer_details ( customer_id number(10) primary key, customer_name varchar2(20), country varchar2(20) );
projects_details
CREATE TABLE projects_details ( project_id number(10) primary key, project_name varchar2(30), project_start_Date date, customer_id number(10) references customer_details(customer_id) );
1.2 Create customer_projects_view
view to get results of customers and their projects.
customer_projects_view
CREATE OR REPLACE VIEW customer_projects_view AS SELECT cust.customer_id, cust.customer_name, cust.country, projectdtls.project_id, projectdtls.project_name, projectdtls.project_start_Date FROM customer_details cust, projects_details projectdtls WHERE cust.customer_id = projectdtls.customer_id;
1.3 If we INSERT INTO customer_projects_view
view directly, the database will raise the following error :
INSERT INTO customer_projects_view VALUES (1,'XYZ Enterprise','Japan',101,'Library management',sysdate); -- output SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table 01779. 00000 - "cannot modify a column which maps to a non key-preserved table" *Cause: An attempt was made to insert or update columns of a join view which map to a non-key-preserved table. *Action: Modify the underlying base tables directly.
1.4 Instead, we should create a INSTEAD OF
trigger on the view to perform the actual operation.
trg_cust_proj_view_insert
CREATE OR REPLACE TRIGGER trg_cust_proj_view_insert INSTEAD OF INSERT ON customer_projects_view DECLARE duplicate_info EXCEPTION; PRAGMA EXCEPTION_INIT (duplicate_info, -00001); BEGIN INSERT INTO customer_details (customer_id,customer_name,country) VALUES (:new.customer_id, :new.customer_name, :new.country); INSERT INTO projects_details (project_id, project_name, project_start_Date, customer_id) VALUES ( :new.project_id, :new.project_name, :new.project_start_Date, :new.customer_id); EXCEPTION WHEN duplicate_info THEN RAISE_APPLICATION_ERROR ( num=> -20107, msg=> 'Duplicate customer or project id'); END trg_cust_proj_view_insert;
1.5 Insert into view again. Le déclencheurINSTEAD OF
sera déclenché et insérera les données dans la table réelle.
INSERT INTO customer_projects_view VALUES (1,'XYZ Enterprise','Japan',101,'Library management',sysdate); INSERT INTO customer_projects_view VALUES (2,'ABC Infotech','India',202,'HR management',sysdate);
1.6 Select table.
SELECT * FROM customer_details;
N ° DE CLIENT
CUSTOMER_NAME
PAYS
1
Entreprise XYZ
Japon
2
ABC Infotech
Inde
SELECT * FROM projects_details;
PROJECT_ID | NOM DU PROJET | PROJECT_START_DATE | N ° DE CLIENT |
---|---|---|---|
101 |
Gestion de la bibliothèque |
25-JUIN-17 |
1 |
202 |
gestion des ressources humaines |
25-JUIN-17 |
2 |
1.7 Select view.
SELECT * FROM customer_projects_view;
N ° DE CLIENT | CUSTOMER_NAME | PAYS | PROJECT_ID | NOM DU PROJET | PROJECT_START_DATE |
---|---|---|---|---|---|
1 |
Entreprise XYZ |
Japon |
101 |
Gestion de la bibliothèque |
25-JUIN-17 |
2 |
ABC Infotech |
Inde |
202 |
gestion des ressources humaines |
25-JUIN-17 |
2. Colonne de vue de table imbriquée
Exemple pour insérer des données dans une colonne de vue de table imbriquée avec INSTEAD OF Trigger.
2.1 Create table, type, nested table view column for testing.
vehicule_mfg_company_details
CREATE TABLE vehicle_mfg_company_details ( company_id number(10) primary key, company_name varchar2(50) NOT NULL );
les détails du véhicule
CREATE TABLE vehicle_details ( vehicle_id number(10) primary key, company_id number(10) references vehicle_mfg_company_details(company_id), vehicle_model_name varchar2(50) NOT NULL );
nestedTableEle
CREATE OR REPLACE TYPE nestedTableEle IS OBJECT ( vehicle_id NUMBER(10), vehicle_model_name VARCHAR2(50) );
Vehicle_details_list_
-- nested table view column CREATE OR REPLACE TYPE vehicle_details_list_ IS TABLE OF nestedTableEle;
2.2 Create a View.
company_vehicles_view
CREATE OR REPLACE VIEW company_vehicles_view AS SELECT company.company_id, company.company_name, CAST (MULTISET (SELECT vehicle.vehicle_id, vehicle.vehicle_model_name FROM vehicle_details vehicle WHERE vehicle.company_id = company.company_id ) AS vehicle_details_list_ ) vehiclelist FROM vehicle_mfg_company_details company;
2.3 Insert data into nested table view column.
-- no error. INSERT INTO vehicle_mfg_company_details VALUES (101,'Ford'); -- error INSERT INTO TABLE ( SELECT vw.vehiclelist FROM company_vehicles_view vw WHERE company_id = 101 ) VALUES (1, 'EcoSport'); -- output SQL Error: ORA-25015: cannot perform DML on this nested table view column 25015. 00000 - "cannot perform DML on this nested table view column" *Cause: DML cannot be performed on a nested table view column except through an INSTEAD OF trigger *Action: Create an INSTEAD OF trigger over the nested table view column and then perform the DML.
2.4 Create a INSTEAD OF trigger
trg_comp_vehicles_view_insrt
CREATE OR REPLACE TRIGGER trg_comp_vehicles_view_insrt INSTEAD OF INSERT ON NESTED TABLE vehiclelist OF company_vehicles_view REFERENCING NEW AS Vehicle PARENT AS Company FOR EACH ROW BEGIN -- Insert on nested table translates to insert on base table. INSERT INTO vehicle_details ( vehicle_id, company_id, vehicle_model_name ) VALUES ( :Vehicle.vehicle_id, :Company.company_id, :Vehicle.vehicle_model_name ); END;
2.5 Insert data into nested table view column again.
INSERT INTO TABLE ( SELECT vw.vehiclelist FROM company_vehicles_view vw WHERE company_id = 101 ) VALUES (1, 'EcoSport'); INSERT INTO TABLE ( SELECT vw.vehiclelist FROM company_vehicles_view vw WHERE company_id = 101 ) VALUES (2, 'Endeavour');
2.6 Display table.
select * from vehicle_mfg_company_details;
COMPANY_ID | NOM DE LA COMPAGNIE |
---|---|
101 |
Ford |
select * from vehicle_details;
VEHICLE_ID | COMPANY_ID | VEHICLE_MODEL_NAME |
---|---|---|
1 |
101 |
EcoSport |
2 |
101 |
Effort |