PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bagaimana mengembalikan nilai dari suatu fungsi jika tidak ada nilai yang ditemukan

Penjelasan

Akar masalahnya adalah definisi kabur dari "bukan apa-apa".

NULL bukan apa-apa , itu hanya tidak diketahui apa itu sebenarnya. "Tidak ada" dalam istilah SQL akan menjadi tidak ada baris :tidak ada yang dikembalikan sama sekali. Itu biasanya terjadi ketika tidak ada baris yang ditemukan. Namun saat menggunakan fungsi agregat , itu tidak dapat terjadi karena, per dokumentasi:

avg() mengembalikan NULL ketika tidak ada baris yang ditemukan (jadi bukan "tidak ada"). Anda mendapatkan baris dengan NULL nilai sebagai hasil - yang ditimpa nilai init Anda dalam kode yang Anda tunjukkan.

Solusi

Bungkus hasilnya dalam COALESCE . Mendemonstrasikan fungsi SQL yang lebih sederhana:

CREATE OR REPLACE FUNCTION get_height_sql(firstn varchar, lastn varchar)
  RETURNS float AS
$func$
   SELECT COALESCE(AVG(((p.h_feet * 12) + p.h_inches) * 2.54)::float, 0)
   FROM   player p
   WHERE  p.firstname = firstn
   AND    p.lastname = lastn
$func$  LANGUAGE sql STABLE;

SQL Fiddle.

Hal yang sama dapat digunakan dalam fungsi plpgsql. Fungsi ini dapat menjadi STABLE , mungkin membantu performa dalam konteks kueri yang lebih besar.

Kasus lain

Jika Anda benar-benar bisa dapatkan tanpa baris dari kueri, COALESCE simple sederhana akan gagal , karena tidak pernah dieksekusi.

Untuk nilai tunggal hasilnya Anda bisa membungkus seluruh kueri seperti:

SELECT COALESCE((SELECT some_float FROM ... WHERE ... LIMIT 1), 0) AS result

PL/pgSQL memiliki kemampuan untuk memeriksa sebelum benar-benar kembali dari fungsi. Ini berfungsi untuk beberapa baris dengan satu atau beberapa kolom , juga. Ada contoh di panduan mendemonstrasikan penggunaan FOUND :

...
RETURN QUERY SELECT foo, bar ...;

IF NOT FOUND THEN
    RETURN QUERY VALUES ('foo_default'::text, 'bar_default'::text);
END IF;
...

Terkait:

Untuk selalu mengembalikan tepat satu baris , Anda juga dapat menggunakan SQL murni :

SELECT foo, bar FROM tbl
UNION ALL
SELECT 'foo_default', 'bar_default'
LIMIT 1;

Jika SELECT pertama tidak mengembalikan baris, SELECT second kedua mengembalikan baris dengan default.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kesalahan sintaks dalam kode uji UPSERT

  2. Opsi praktis modern untuk pencarian Django dengan Postgres? Perlu beberapa kriteria, tetapi ikon terlalu tidak efisien

  3. Batas kinerja solusi replikasi logis

  4. Spark Dataframes UPSERT ke Tabel Postgres

  5. Cara membuat Pengguna/Database dalam skrip untuk Docker Postgres