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

Kesalahan PostgreSQL:argumen string kueri EXECUTE adalah nol

Pesan kesalahannya adalah

Anda memiliki dua EXECUTE perintah:

_query := 'CREATE TABLE public.'
        || quote_ident(_table_name) || ' ( ) INHERITS (public.evidence)';
EXECUTE _query;

...

EXECUTE 'INSERT INTO public.'
      || quote_ident(_table_name) || ' VALUES ($1.*)' USING NEW;

Satu-satunya bagian yang dapat menjadi NULL adalah table_name .
Satu-satunya kesempatan untuk table_name menjadi NULL ada di sini:

SELECT raised_local_time FROM notifications WHERE id=_notification_id
INTO _raised_local_time;

Jadi penyebabnya pasti salah satu dari dua alasan :

  1. NEW.notification_id adalah NULL .

  2. Tidak ada baris di notifications untuk NEW.notification_id yang diberikan .

Coba fungsi pemicu yang dimodifikasi ini untuk debugging :
CREATE OR REPLACE FUNCTION partition_evidence_by_month()
  RETURNS trigger AS
$func$
DECLARE 
   _table_name text;
BEGIN
   SELECT 'evidence-' || to_char(raised_local_time, 'YYYY-MM')
   FROM   public.notifications -- schema-qualify to be sure
   WHERE  id = NEW.notification_id
   INTO   _table_name;

   IF _table_name IS NULL THEN
      RAISE EXCEPTION '_table_name is NULL. Should not occur!';
   END IF;

   IF NOT EXISTS (   -- create table if it does not exist
      SELECT 1
      FROM   pg_catalog.pg_class c
      JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
      WHERE  c.relkind = 'r'
      AND    c.relname = _table_name
      AND    n.nspname = 'public') THEN

      EXECUTE 'CREATE TABLE public.'
            || quote_ident(_table_name) || ' ( ) INHERITS (public.evidence)';
   END IF;

   EXECUTE 'INSERT INTO public.'
         || quote_ident(_table_name) || ' VALUES $1'  -- Use NEW row directly
   USING  NEW;       -- write data to the partition table

   RETURN NULL;
END
$func$ LANGUAGE plpgsql;
  • Hapus variabel yang tidak digunakan dan sederhanakan kode. (Ini jelas merupakan contoh yang disederhanakan.)

    • Antara lain, Anda tidak perlu date_trunc() sama sekali. Cukup masukkan stempel waktu asli ke to_char() .

    • Tidak ada gunanya menggunakan varchar(n) . Cukup gunakan text atau varchar .

    • Hindari terlalu banyak tugas jika tidak perlu - relatif mahal di PL/pgSQL.

  • Tambahkan RAISE untuk memeriksa hipotesis saya.
    Jika Anda mendapatkan pesan kesalahan, membedakan antara dua kemungkinan penyebab adalah langkah berikutnya. Seharusnya sepele ...




  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 menguji entri crontab?

  2. Cara Membangun Kembali Budak PostgreSQL yang Tidak Konsisten

  3. Bisakah saya menetapkan (dalam dbase) batas ukuran pada bidang byte di PostgreSQL?

  4. Pola &Pengubah Template untuk Pemformatan Tanggal/Waktu di PostgreSQL

  5. Cara Membuat Total Periode Bergulir