忽略PostgreSQL的BEFORE TRIGGER中的结果?

时间:2015-08-02 16:44:38

标签: postgresql triggers plpgsql dynamic-sql

这个帖子是这个thread的一部分挑战,我正在通过BEFORE TRIGGER为一个部分寻找更好的解决方案。 我只是想启动一个触发器来转换为正确的括号。 我在想是否应该从触发器返回NULL或触发前的其他东西。

代码

CREATE OR REPLACE FUNCTION f_create_my_trigger_events(_arg1 int, _arg2 text, _arg3 text)
  RETURNS void AS
$func$
BEGIN

EXECUTE format($$
    DROP TRIGGER IF EXISTS insbef_ids ON events
    CREATE TRIGGER insbef_ids
    BEFORE INSERT ON events
    FOR EACH ROW EXECUTE PROCEDURE insbef_events_function(%1$L)$$
    , translate(_arg2, '[]', '{}'), translate(_arg3, '[]', '{}')
);

END
$func$ LANGUAGE plpgsql;

我使用函数

RETURN NULL; -- result ignored since this is an

我不确定这一行:trigger TODO right?AFTER之前,因为我认为在sudo -u postgres psql detector -c "SELECT f_create_my_trigger_events(1,'[112]','[113]');"触发器中就是这种情况,但在触发器之前不是这样。
我只是想启动一个触发器来转换正确的括号。

测试命令是LINE 3: CREATE TRIGGER insbef_ids ^ QUERY: DROP TRIGGER IF EXISTS insbef_ids ON events CREATE TRIGGER insbef_ids BEFORE INSERT ON events FOR EACH ROW EXECUTE PROCEDURE insbef_events_function('{112}') CONTEXT: PL/pgSQL function f_create_my_trigger_events(integer,text,text) line 4 at EXECUTE statement 因为对返回的东西的误解而得到以下错误,我想。

BEFORE

如何在PostgreSQL 9.4中管理public class Program { public static void Main( string[] args ) { /** * Load the bitmap and convert it to a byte array * then save the file to the desktop */ byte[] imageBytes = ImageToByte( new Bitmap( "C:/Users/Krythic/Desktop/NovaEngine.png" ) ); File.WriteAllBytes( "C:/Users/Krythic/Desktop/NovaImageData.txt" , imageBytes ); /** * Load the saved image bytes, then convert them back into an image and save it to the * desktop under a new name. */ byte[] convertedImageBytes = File.ReadAllBytes("C:/Users/Krythic/Desktop/NovaImageData.txt"); Bitmap image = ConvertToBitmap(convertedImageBytes); image.Save("C:/Users/Krythic/Desktop/ConvertedImage.png"); } public static byte[] ImageToByte( Bitmap img ) { ImageConverter converter = new ImageConverter(); return ( byte[] )converter.ConvertTo( img , typeof( byte[] ) ); } private static Bitmap ConvertToBitmap( byte[] imagesSource ) { ImageConverter imageConverter = new ImageConverter(); Image image = ( Image )imageConverter.ConvertFrom( imagesSource ); return new Bitmap( image ); } } 个触发器?

1 个答案:

答案 0 :(得分:3)

首先,您需要在 BEFORE 触发器中传递行变量。传递NULL取消行的操作:

CREATE OR REPLACE FUNCTION insbef_events_function() 
  RETURNS TRIGGER AS 
$func$
DECLARE
   m int[]; 
BEGIN
   FOREACH m SLICE 1 IN ARRAY TG_ARGV[0]::int[]
   LOOP
      INSERT INTO events (measurement_id, event_index_start, event_index_end) 
      SELECT NEW.measurement_id, m[1], m[2];  -- Postgres array subscripts start with 1
   END LOOP;

      -- do something with _result ...

   RETURN NEW;  -- NULL would cancel operation in BEFORE trigger!
END 
$func$ LANGUAGE plpgsql;

我演示了在RETRUN NULL触发器in my previous answer中使用AFTER。您无法对BEFORE触发器执行相同的操作。 The documentation:

  

触发的行级触发器BEFORE可以返回null来发出触发信号   经理跳过这一行的其余操作(即   不会触发后续触发器,而INSERT / UPDATE / DELETE会触发   不会出现这一行)。如果返回一个非空值,那么   操作以该行值继续。

还有更多。阅读手册。

但是既然你现在传递的是两个一维数组而不是一个二维数组,你需要调整你的触发逻辑:

CREATE OR REPLACE FUNCTION insbef_events_function() 
  RETURNS TRIGGER AS 
$func$
DECLARE
   a1 int[] := TG_ARGV[1]::int[];
   a2 int[] := TG_ARGV[2]::int[];
BEGIN
   FOR i in array_lower(a1, 1) .. array_upper(a1, 1)
   LOOP
      INSERT INTO events (measurement_id, event_index_start, event_index_end) 
      SELECT NEW.measurement_id  -- or TG_ARGV[0]::int instead?
           , a1[i]
           , a2[i];
   END LOOP;

   RETURN NEW;  -- NULL would cancel operation in BEFORE trigger!
END 
$func$  LANGUAGE plpgsql;

现在你的责任是两个阵列都有相同数量的元素 更改触发器的功能现在看起来像这样:

CREATE OR REPLACE FUNCTION f_create_my_trigger_events(_arg1 int, _arg2 text, _arg3 text)
  RETURNS void AS
$func$
BEGIN
   EXECUTE format(
    $$DROP TRIGGER IF EXISTS insbef_ids ON measurements; -- on measurements ..
      CREATE TRIGGER insbef_ids
      BEFORE INSERT ON measurements  -- .. according to previous posts!!
      FOR EACH ROW EXECUTE PROCEDURE insbef_events_function(%s, %L, %L)$$
    , _arg1
    , translate(_arg2, '[]', '{}')
    , translate(_arg3, '[]', '{}')
   );
END
$func$  LANGUAGE plpgsql;

在使用这种先进的自动化设计之前,您需要了解SQL,plpgsql和触发器函数的基础知识。