Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Bagaimana menjalankan pemicu dan prosedur di oracle

Seperti yang sudah diusulkan, pertama-tama cobalah untuk mendapatkan desain yang tepat sehubungan dengan kebutuhan Anda. Anda dapat menerapkan banyak batasan hanya dengan mendesain skema database Anda dengan benar.

Jauhi pemicu dan PL/SQL selama mungkin. Ini akan memaksa Anda untuk mendesain dengan lebih baik pada akhirnya dan akan membuahkan hasil.

Sebelum menggunakan trigger untuk logika bisnis, coba gunakan view untuk hal-hal yang bisa dipilih. Untuk itulah database.

Saat Anda "selesai", uji kinerjanya dan jika kurang optimal, perbaiki skema Anda. Jika tidak ada yang membantu, mulailah menggunakan pemicu untuk logika bisnis.

Saya telah mengumpulkan contoh dengan pandangan yang saya bicarakan. Saya harap ini bisa membantu Anda memulai.

create table Products (
  ProdId number generated always as identity primary key
, ProdName varchar2(20) not null
);

create table Stores (
  StoreId number generated always as identity primary key
, StoreName varchar2(20) not null
);

create table Customers (
  CustomerId number generated always as identity primary key
, CustomerName varchar2(20) not null
);

create table Prices (
  PriceId number generated always as identity primary key
, ProdId number not null
, Price number
, ValidFrom date default on null sysdate
, constraint fk_Prices_Product foreign key (ProdId) references Products (ProdId)
);

create unique index uniq_prices_product_price on Prices (ProdId, ValidFrom);

create table Orders (
  OrderId number generated always as identity primary key
, CustomerId number not null
, StoreId number not null
, OrderedAt date default on null sysdate
, constraint fk_Orders_Customer foreign key (CustomerId) references Customers (CustomerId)
, constraint fk_Orders_Store foreign key (StoreId) references Stores (StoreId)
);

create table OrderLines (
  OrderLineId number generated always as identity primary key
, OrderId number not null
, ProdId number not null
, ProdQuantity number not null
, constraint fk_OrderLines_Order foreign key (OrderId) references Orders (OrderId)
, constraint fk_OrderLines_Prod foreign key (ProdId) references Products (ProdId)
);

create table Payments (
  PaymentId number generated always as identity primary key
, OrderId number not null
, PaidAt date default on null sysdate
, PaidAmount number not null
, constraint fk_Payments_Order foreign key (OrderId) references Orders (OrderId)
);

create view Prices_V as
select
  p.*
, coalesce(
    lead(p.ValidFrom) over (partition by p.ProdId order by p.ValidFrom)
  , to_date('9999', 'YYYY')
  ) ValidTo
from Prices p;

create view Orders_V as
select
  o.*
, (
    select sum(ol.ProdQuantity * p.Price)
    from OrderLines ol
    join Prices_V p on (p.ProdId = ol.ProdId and o.OrderedAt between p.ValidFrom and p.ValidTo)
    where o.OrderId = ol.OrderId
  ) Total
, (
    select sum(PaidAmount)
    from Payments p
    where p.OrderId = o.OrderId
  ) TotalPaid
from Orders o;

insert into Products(ProdName)
select 'Prod A' from dual union all
select 'Prod B' from dual;

insert into Stores(StoreName) values ('Store A');

insert into Customers(CustomerName) 
select 'Customer A' from dual union all
select 'Customer B' from dual;

insert into Prices(ProdId, Price, ValidFrom)
select 1, 10, sysdate - 10 from dual union all
select 1, 12, sysdate - 2 from dual union all
select 1, 14, sysdate + 3 from dual union all
select 2, 100, sysdate - 10 from dual union all
select 2,  90, sysdate - 2 from dual union all
select 2,  null, sysdate + 5 from dual;

insert into Orders(CustomerId, StoreId, OrderedAt)
select 1 cid, 1 stoid, sysdate - 5 from dual union all
select 2, 1, sysdate - 5 from dual union all
select 2, 1, sysdate - 1 from dual;

insert into OrderLines(OrderId, ProdId, ProdQuantity)
select 1 ordid, 1 prodid, 3 prodquant from dual union all
select 1, 2, 2 from dual union all
select 2, 2, 10 from dual union all
select 3, 2, 10 from dual;

insert into Payments(OrderId, PaidAmount) values (2, 500);


select * from Prices_V order by ProdId, ValidFrom;
select * from OrderLines order by OrderId, ProdId;
select * from Orders_v order by OrderId;

Beberapa ide di sana:

  1. Harga disimpan dalam tabel terpisah, mengacu pada produk dan memiliki validitas sehingga harga produk dapat berubah seiring waktu. Tampilan harga memiliki ValidTo kolom ditambahkan sehingga lebih mudah digunakan
  2. Ada indeks unik pada Harga sehingga kami tidak dapat memiliki 2 harga untuk produk yang sama secara bersamaan
  3. Anda dapat memesan banyak item, makanya ada Orders dan OrderLines tabel dalam hubungan 1-ke-banyak
  4. Dalam Order_V total pembayaran ditampilkan (menggunakan subquery pada Payments ) dan total nilai pesanan ditampilkan (menggunakan subquery pada OrderLines dan Prices , tanggal pemesanan digunakan untuk mendapatkan harga dari periode yang benar)

Berdasarkan skema, Anda akan melihat hal-hal apa yang dapat Anda wakili dan mana yang tidak. Adalah tugas Anda untuk membuatnya sesuai dengan kebutuhan Anda :)

Dan sekarang saya sampai pada titik yang Anda katakan bahwa pemicu dan prosedur adalah wajib dalam proyek Anda. Oleh karena itu saya punya proposal:

  1. Buat prosedur yang memungkinkan pengguna membuat harga baru untuk suatu produk. Itu pasti harus memeriksa bahwa validitas tidak dimulai di masa lalu. Kemudian terapkan yang lain yang memungkinkan untuk mengubah valid menjadi tanggal (juga tidak dapat berakhir di masa lalu). Anda dapat mencabut hak istimewa penyisipan/pembaruan apa pun pada tabel Produk dan memaksa pengguna untuk menggunakan prosedur Anda yang akan berisi logika bisnis ini.
  2. Buat tabel PricesLog dan memicu pada Prices yang akan memasukkan PriceId, old.Price, new.Price, sysdate dan User ke log pada setiap sisipan/pembaruan ke tabel harga.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lihat transaksi terbuka di Oracle

  2. Oracle SQL untuk Mengurutkan Nomor Versi

  3. Perbedaan UTL_SMTP antara DATA, WRITE_DATA dan WRITE_RAW_DATA

  4. Buat pekerjaan penjadwal oracle

  5. Mengambil informasi tipe data untuk kolom di Oracle OCCI ResultSet