it-swarm.asia

Apakah ada cara sederhana dalam PL / pgSQL untuk memeriksa apakah kueri tidak memberikan hasil?

Saat ini saya sedang bereksperimen sedikit dengan PL/pgSQL dan ingin tahu apakah ada cara yang lebih elegan untuk melakukan sesuatu seperti ini:

select c.data into data from doc c where c.doc_id = id and c.group_cur > group_cur order by c.id desc limit 1;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        select c.data into data from doc c where c.doc_id = id and c.global_cur > global_cur order by c.id desc limit 1;
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                RETURN NULL;
17
icefex

Blok pengecualian dimaksudkan untuk menjebak kesalahan, bukan memeriksa kondisi. Dengan kata lain, jika beberapa kondisi dapat ditangani pada waktu kompilasi, itu tidak boleh terjebak sebagai kesalahan tetapi diselesaikan dengan logika program biasa.

Di bagian Trapping Errors pada dokumentasi PL/PgSQL Anda dapat menemukan tip seperti itu:

Tip: Blok yang berisi klausa PENGECUALIAN secara signifikan lebih mahal untuk masuk dan keluar daripada blok tanpa klausa. Karena itu, jangan gunakan PENGECUALIAN tanpa perlu.

Alih-alih menggunakan pengecualian (buruk), atau JIKA/THEN/ELSIF (lebih baik), Anda dapat menulis ulang ini ke satu permintaan:

SELECT c.data into data
FROM  doc c
WHERE c.doc_id = id
  and (
    c.group_cur > group_cur
    or
    c.global_cur > global_cur
  )
ORDER BY
  -- this will make group always preferred over global
  case when c.group_cur > group_cur then 1 else 2 end ASC,
  -- and this is your normal ordering
  c.id DESC
limit 1;

Jika Anda benar-benar ingin dua kueri, Anda dapat menggunakan variabel DITEMUKAN khusus untuk menguji apakah permintaan sebelumnya memberikan hasil apa pun:

select c.data into data
from doc c
where c.doc_id = id and c.group_cur > group_cur
order by c.id desc limit 1;
if not found then
    select c.data into data
    from doc c
    where c.doc_id = id and c.global_cur > global_cur
    order by c.id desc limit 1;
    if not found then return null; end if;
end if;

Wajib RTFM tautan folllow :-)

Lihat ini untuk deskripsi FOUND variabel, dan ini untuk IF/THEN blok.

21
filiprem

Anda dapat memeriksa variabel khusus DITEMUKAN dari tipe boolean. Dari dokumentasi:

DITEMUKAN salah dalam setiap panggilan fungsi PL/pgSQL. Ini diatur oleh masing-masing jenis pernyataan berikut:

Pernyataan SELECT INTO menetapkan FOUND true jika suatu baris diberikan, false jika tidak ada baris yang dikembalikan.

Pernyataan PERFORM menetapkan FOUND true jika menghasilkan (dan membuang) satu atau lebih baris, false jika tidak ada baris yang dihasilkan.

Pernyataan UPDATE, INSERT, dan DELETE menetapkan DITEMUKAN benar jika setidaknya satu baris terpengaruh, salah jika tidak ada baris yang terpengaruh.

Pernyataan FETCH menetapkan DITEMUKAN benar jika mengembalikan baris, salah jika tidak ada baris yang dikembalikan.

Pernyataan MOVE menetapkan DITEMUKAN benar jika itu berhasil mereposisi kursor, salah jika tidak.

Pernyataan FOR atau FOREACH menetapkan DITEMUKAN jika itu mengulangi satu atau lebih kali, yang lain salah. DITEMUKAN seperti ini saat loop keluar; di dalam eksekusi loop, DITEMUKAN tidak dimodifikasi oleh pernyataan loop, meskipun mungkin diubah oleh eksekusi pernyataan lain dalam tubuh loop.

RETURN QUERY dan RETURN QUERY EXECUTE, set DITEMUKAN true jika kueri mengembalikan setidaknya satu baris, salah jika tidak ada baris yang dikembalikan.

Pernyataan PL/pgSQL lainnya tidak mengubah status DITEMUKAN. Perhatikan khususnya bahwa EXECUTE mengubah output dari DAPATKAN DIAGNOSTIK, tetapi tidak berubah DITEMUKAN.

DITEMUKAN adalah variabel lokal dalam setiap fungsi PL/pgSQL; perubahan apa pun hanya memengaruhi fungsi saat ini.

14
alexk