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

PostgreSQL - Menulis sql dinamis dalam prosedur tersimpan yang mengembalikan kumpulan hasil

Ada ruang untuk perbaikan:

CREATE OR REPLACE FUNCTION report_get_countries_new (starts_with text
                                                   , ends_with   text = NULL)
  RETURNS SETOF lookups.countries AS
$func$
DECLARE
   sql text := 'SELECT * FROM lookups.countries WHERE country_name >= $1';
BEGIN
   IF ends_with IS NOT NULL THEN
      sql := sql || ' AND country_name <= $2';
   END IF;

   RETURN QUERY EXECUTE sql
   USING starts_with, ends_with;
END
$func$ LANGUAGE plpgsql;
-- the rest is default settings

Poin utama

  • PostgreSQL 8.4 memperkenalkan USING klausa untuk EXECUTE , yang berguna karena beberapa alasan. Rekap dalam manual:

    String perintah dapat menggunakan nilai parameter, yang dirujuk dalam perintah sebagai $1, $2 , dll. Simbol-simbol ini mengacu pada nilai yang diberikan dalam USING ayat. Metode ini sering lebih disukai daripada memasukkan nilai data ke dalam string perintah sebagai teks:metode ini menghindari overhead run-time dari mengubah nilai menjadi teks dan sebaliknya, dan jauh lebih rentan terhadap serangan injeksi SQL karena tidak perlu mengutip atau melarikan diri.

    IOW, ini lebih aman dan lebih cepat daripada membangun string kueri dengan representasi teks dari parameter, bahkan ketika dibersihkan dengan quote_literal() .
    Perhatikan bahwa $1, $2 dalam string kueri mengacu pada nilai yang disediakan di USING klausa, tidak ke parameter fungsi.

  • Saat Anda mengembalikan SELECT * FROM lookups.countries , Anda dapat menyederhanakan RETURN deklarasi seperti yang ditunjukkan:

    RETURNS SETOF lookups.countries
    

    Di PostgreSQL ada tipe komposit yang ditentukan untuk setiap tabel secara otomatis. Gunakan. Efeknya adalah bahwa fungsinya tergantung pada jenisnya dan Anda mendapatkan pesan kesalahan jika Anda mencoba mengubah tabel. Jatuhkan &buat ulang fungsi dalam kasus seperti itu.

    Ini mungkin atau mungkin tidak diinginkan - umumnya memang begitu! Anda ingin mengetahui efek samping jika Anda mengubah tabel. Cara Anda memilikinya, fungsi Anda akan terputus secara diam-diam dan memunculkan pengecualian pada panggilan berikutnya.

  • Jika Anda memberikan default eksplisit untuk parameter kedua dalam deklarasi seperti yang ditunjukkan, Anda dapat (tetapi tidak harus) menyederhanakan panggilan jika Anda tidak ingin menetapkan batas atas dengan ends_with .

    SELECT * FROM report_get_countries_new('Zaire');
    

    bukannya:

    SELECT * FROM report_get_countries_new('Zaire', NULL);
    

    Waspadai fungsi yang berlebihan dalam konteks ini.

  • Jangan mengutip nama bahasa 'plpgsql' bahkan jika itu ditoleransi (untuk saat ini). Ini adalah pengenal.

  • Anda dapat menetapkan variabel pada waktu deklarasi. Menghemat satu langkah ekstra.

  • Parameter diberi nama di header. Lepaskan kalimat yang tidak masuk akal:

     starts_with ALIAS FOR $1;
     ends_with ALIAS FOR $2;
    


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menonaktifkan integritas referensial di Postgres 8.2?

  2. PostgreSQL tidak menggunakan indeks parsial

  3. PostgreSQL, seret dan tukar

  4. Fungsi Escape untuk ekspresi reguler atau pola LIKE

  5. Bagaimana make_time() Bekerja di PostgreSQL