sql >> Database teknologi >  >> RDS >> Oracle

SQL Loader, Trigger saturation?

Du er allerede halvvejs til løsningen:

Dette er ikke en overraskelse. Din nuværende implementering udfører en masse enkelt række SELECT-sætninger for hver række, du indsætter i tabel B. Det vil uundgåeligt give dig en dårlig præstationsprofil. SQL er et sæt-baseret sprog og fungerer bedre med multi-row operations.

Så hvad du skal gøre er at finde en måde at erstatte alle SELECT-sætningerne, som er mere effektive alternativer. Så vil du være i stand til at slippe triggerne permanent. Udskift f.eks. opslagene i ordbogen med fremmednøgler mellem tabel A-kolonnerne og referencetabellen. Relationelle integritetsbegrænsninger, idet de er intern Oracle-kode, yder meget bedre end nogen anden kode, vi kan skrive (og fungerer også i flerbrugermiljøer).

Reglen om ikke at indsætte i tabel A, hvis der allerede findes en kombination af kolonner i tabel B, er mere problematisk. Ikke fordi det er svært at gøre, men fordi det lyder som et dårligt relationelt design. Hvis du ikke vil indlæse poster i tabel A, når de allerede afsluttes i tabel B, hvorfor indlæser du ikke direkte i tabel B? Eller måske har du et undersæt af kolonner, som skal udtrækkes fra tabel A og tabel B og dannet til tabel C (som ville have fremmednøglerelationer med A og B)?

Uanset hvad, hvis du overlader det til den ene side, kan du gøre dette med sæt-baseret SQL ved at erstatte SQL*Loader med en ekstern tabel. En ekstern tabel giver os mulighed for at præsentere en CSV-fil til databasen, som om det var en almindelig tabel. Det betyder, at vi kan bruge det i normale SQL-sætninger. Få mere at vide.

Så med fremmednøglebegrænsninger på ordbog og en ekstern tabel kan du erstatte SQL Loader-koden med denne sætning (med forbehold for de andre regler, der er indordnet i "...og så videre"):

insert into table_a
select ext.* 
from external_table ext
     left outer join table_b b
     on (ext.name = b.name and ext.last_name = b.last_name and ext.dept=b.dept)
where b.name is null
log errors into err_table_a ('load_fail') ;

Dette anvender DML-fejllogningssyntaksen til at fange begrænsningsfejl for alle rækker på en sæt-baseret måde. Få mere at vide . Det vil ikke give undtagelser for rækker, der allerede findes i tabel B. Du kan enten bruge multitabellen INDSÆT ALLE at dirigere rækker ind i en overløbstabel eller bruge en MINUS sæt operation efter hændelsen for at finde rækker i den eksterne tabel, som ikke er i tabel A. Afhænger af dit slutmål og hvordan du skal rapportere tingene.

Måske et mere komplekst svar, end du havde forventet. Oracle SQL er en meget omfattende SQL-implementering, med en masse funktionalitet til at forbedre effektiviteten af ​​bulk-operationer. Det kan virkelig betale sig at læse Concepts Guide og SQL Reference for at finde ud af, hvor meget vi kan gøre med Oracle.




  1. mysql jdbc-driveren understøtter ikke afgrænsere i triggere med flere sætninger

  2. codeigniter - database:hvordan man opdaterer flere tabeller med en enkelt opdateringsforespørgsel

  3. mysql - gruppe, men vis alle rækker i en kolonne

  4. Sammenføjning af tabeller i MySql med ét fælles felt, men forskellige værdier for det fælles felt