2014-05-06 19 views
14

ALTER TABLE etiketinde bir pgsql olayı tetikleyicide hangi tablonun değiştirildiğini bilmek isterim.Postgres olay tetikleyicisinden SQL metni nasıl alınır

pg değişkenleri bunu kapsamaz ve GET STACKED DIAGNOSTICS tarafından ortaya konan değişkenleri de kapsamaz.

Kullanılabilir değişkenlerde, işlevi başlatmadan sorumlu SQL komutunun metnini görmek için tetikleme işlevinin kendisinde herhangi bir yol var mı?

ALTER TABLE base1 ADD COLUMN col1 int; 

olay tetikleyici çağıran sorumlu

örneğin eğer

, ardından ALTER TABLE base1 ADD COLUMN col1 int metnin kendisini görmek için olay tetikleyici içinde herhangi bir yolu var mı?

+6

'SEC current_query() '. Ancak, yalnızca olay tetikleyicisinin ne işe yaradığını gösteren * en üst düzey * sorgusunu gösterecektir - bir PL/PgSQL işleviyle bir "ALTER TABLE" yaptıysanız. Olay tetikleyicileri, komut hakkında daha fazla bilgi eklemek için genişletilecek, ancak şu anda 9.3/9.4'te çok sınırlı. –

+0

@CraigRinger - teşekkürler. uzantıları dört gözle bekliyorum! –

+2

C'de bir olay tetikleyicisi yazarsanız, ayrıca komutun ayrıştırma ağacına da sahipsiniz. http://www.postgresql.org/docs/9.3/static/event-trigger-interface.html Kesinlikle buna güvenmenin en iyi yolu değil, ancak bu özellik bulana kadar olan bir şey uzatıldı. – pozs

cevap

15

PostgreSQL 9.5'ten başlayarak, ddl_command_end olay tetikleyicileri için pg_event_trigger_ddl_commands() işlev kullanılabilir. TAG filtresini kullanarak, herhangi bir ALTERed tablosunu işlemek için kullanılabilir. object_identity (veya objid) hangi tablonun ALTERed olduğunu bilmenin orijinal problemini çözmek için kullanılabilir. Komutu almak için olduğu gibi, mevcut, ancak bir iç tip pg_ddl_command.

CREATE TABLE t (n INT); 

CREATE FUNCTION notice_event() RETURNS event_trigger AS $$ 
DECLARE r RECORD; 
BEGIN 
    FOR r IN SELECT * FROM pg_event_trigger_ddl_commands() LOOP 
     RAISE NOTICE 'caught % event on %', r.command_tag, r.object_identity; 
    END LOOP; 
END; 
$$ 
LANGUAGE plpgsql; 

CREATE EVENT TRIGGER tr_notice_alter_table 
    ON ddl_command_end WHEN TAG IN ('ALTER TABLE') 
    EXECUTE PROCEDURE notice_event(); 

ALTER TABLE t ADD c CHAR; 

çıkışlar: NOTICE: caught ALTER TABLE event on public.t