这个帖子是这个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 );
}
}
个触发器?
答案 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和触发器函数的基础知识。