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

Bagaimana cara menggunakan Oracle DBMS_ALERT dalam Oracle APEX?

Saya telah menyiapkan demo di apex.Oracle.com, tetapi karena Anda memerlukan hibah eksekusi di dbms_alert, itu harus tekstual saja.

Anda dapat melangkah cukup jauh dengan seluruh pengaturan, jadi saya akan menganggap ini sebagai dasar untuk membangun. Misalnya, saya hanya bekerja dengan satu peringatan. Dalam sampel Anda, Anda mungkin ingin menggunakan beberapa peristiwa untuk menangkap lansiran kemajuan yang berbeda. Ini karena alasan sederhana bahwa untuk mengembalikan sesuatu ke klien (respons ajax) panggilan balik ajax harus 'ditutup'. Jadi ketika menangkap peringatan dan ingin mengembalikannya, Anda perlu menulis ke buffer dan itu perlu dikembalikan. Ini berarti Anda juga akan berhenti mendengarkan acara tersebut (baca:di apex, Anda harus!).

Pertimbangkan alurnya seperti ini:Anda akan melakukan panggilan ajax, dan memiliki proses panggilan balik ajax yang mendaftarkan minat pada suatu acara. Kemudian Anda menunggu peringatan terjadi. Anda menangkapnya dan mengembalikannya dengan menuliskannya di buffer http (htp.p ). Itu adalah akhir dari kode dan apex akan menyiram buffer, panggilan ajax kemudian akan mengambil respons dan Anda akan dapat mengelola pengembalian itu.
Jangan lupa:apex menggunakan connection pooling, dan database sesi tidak ditautkan secara langsung melainkan digunakan kembali setiap saat. Anda tidak ingin 'meninggalkan' sesi database 'kotor'. Anda juga harus membatalkan pendaftaran minat-peringatan Anda. Ini juga membuat kasus untuk menggunakan ID unik untuk lansiran - lansiran dapat didaftarkan ke dalam sesi (basis data) yang berbeda, jadi jika ini akan menjadi halaman yang dapat digunakan banyak pengguna untuk mengikuti kemajuan kemajuan proses mereka, Anda tidak ingin mereka mengganggu peringatan pengguna lain.

Namun, sifat minat yang sekilas ini juga berarti akan ada "gangguan" antara panggilan ajax yang berbeda yang dibuat. Saat Anda ingin mendengarkan beberapa peringatan, dan peringatan ini mungkin dikemas sangat erat bersama-sama, ada kemungkinan Anda melewatkan satu. Katakanlah 2 peringatan berjarak 1 ms:yang pertama akan ditangkap, dilaporkan ke panggilan ajax, yang harus segera memulai panggilan baru untuk mendengarkan lebih banyak peringatan. Tetapi karena tidak ada pendengar yang aktif selama waktu yang singkat itu, peringatan berikutnya mungkin terlewatkan. Sekarang - ini mungkin hanya menjadi masalah di mana Anda mengaktifkan beberapa peringatan di bawah penangan yang sama. Jika Anda akan menggunakan beberapa penangan dan memulai panggilan ajax untuk semua penangan tersebut pada saat yang bersamaan, semuanya akan ditangani tepat waktu. Ada solusi untuk keduanya, tentu saja. Saya membayangkan bahwa ketika menggunakan satu penangan saja, Anda dapat menangkap semua peringatan dalam koleksi dan memeriksanya jika Anda telah mengirim tanggapan untuk peringatan tertentu atau tidak dan apakah akan melanjutkan check-in atau tidak. Dengan beberapa penangan, Anda dapat menggunakan id unik dan menambahkannya dengan status berbeda.

Jadi, inilah beberapa kode aktual yang saya gunakan di POC lokal saya.

Ikhtisar:Saya memiliki 3 tombol:1 untuk menghasilkan id peringatan, yang saya gunakan secara berurutan. Tombol lain untuk mulai mendengarkan suatu acara, dan tombol lain untuk mengirim peringatan.

Kode JS untuk tombol NEW_ALERT_ID:

apex.server.process("NEW_ALERT").done(function(pdata){
$s("P1_ALERT_ID",pdata.alertId);
})

Kode JS untuk tombol START_LISTEN:

apex.server.process("LISTEN_ALERT",{x01:$v("P1_ALERT_ID")},{timeout:(31*1000)})
.done(function(pdata){
  if (pdata.success ){
      alert('Caught alert: ' + pdata.message);
  } else {
      alert("No alerts caught during wait on database. You may want to continue listening in...")
  }
})
.fail(function(jqXHR, textStatus){
    if(textStatus === 'timeout')
    {     
        alert('Call should have returned by now...'); 
        //do something. Try again perhaps?
    }
});

Kode JS untuk tombol SEND_ALERT:

apex.server.process("SEND_ALERT",{x01:$v("P1_ALERT_ID")},{dataType:"text"});

Proses Panggilan Balik AJAX:

BARU_ALERT:

htp.p('{"alertId":'||alert_seq.nextval()||'}');

LISTEN_ALERT:

declare
  alert_id number := apex_application.g_x01;
  msg varchar2(2000);
  stat pls_integer;
  keep_looping boolean := true;
  insurance binary_integer := 0; -- prevent an infinite loop

  onecycle binary_integer := 3; -- one cycle of waiting, in seconds
  maxcycles binary_integer := 10; -- in this session, the max amount of cycles to wait
begin
  dbms_alert.register(alert_id);

  while keep_looping
  loop
    insurance := insurance + 1;

    dbms_alert.waitone(alert_id, msg, stat, onecycle);
    if stat = 1 then
      apex_debug.message('timeout occured, going again');
    else
      apex_debug.message('alert: '||msg);
      keep_looping := false;
    end if;

    exit when insurance = maxcycles;    
  end loop;


  if keep_looping then
    -- we waited a really long time now. It may be a good idea to return this info to the client and let it start a new call
    htp.p('{"success":false,"message":"No alert during wait on database"}');
  else
    htp.p('{"success":true,"message":"'||msg||'"}');
  end if;
end;

KIRIM_ALERT:

declare
  alert_id number := apex_application.g_x01;
begin
  dbms_alert.signal(alert_id, 'alert sent at '||to_char(systimestamp, 'HH24:MI:SS FF6'));
end;

Jadi, pertama-tama saya akan mendapatkan ID peringatan, lalu saya akan mulai mendengarkan, dan kemudian pada titik tertentu saya akan mengirim peringatan (atau tidak). Ini adalah kerangka dan akan membutuhkan penyempurnaan lebih lanjut dalam pengaturan Anda yang sebenarnya.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah penggunaan SELECT COUNT(*) sebelum SELECT INTO lebih lambat daripada menggunakan Pengecualian?

  2. Bagaimana Anda bisa memaksa fungsi di klausa where untuk dieksekusi sekali di Oracle?

  3. Cara menulis kode di Oracle SQL (seperti 'CCYYMMDD' ke 102 )

  4. Log kueri Oracle XE

  5. Hubungkan Node.js dengan Oracle di platform Windows