postgresql / plpgsql - 具有循环和多个操作的函数
postgresql / plpgsql - function with a loop and multiple actions
我是 Postgres 的新手,但我已经通过 pgAdmin 4.15 创建了一个函数,Postgres 的版本是 9.6。
问题是我无法让它工作,我认为语法有问题?
INSERT 和 UPDATE 语句正在工作(在函数外),所以它必须是函数语法...
目的是通过 jdbc 插件 (Logstash) 调用此函数,并使用给定的 "input" 字符串作为键更新一些表。
"key"用于SELECT要操作的报警ID。
因此,对于我获得的每个 ID,我需要在这些表上执行一些 UPDATE/INSERT。
# \sf close_event
CREATE OR REPLACE FUNCTION public.close(input text)
RETURNS void
LANGUAGE plpgsql
AS $function$
DECLARE
_event_idnumber INTEGER;
BEGIN
FOR _event_idnumber IN
SELECT id FROM public.alerts WHERE data ->> 'field_name' = input
LOOP
INSERT INTO public.comments ( created_date, content, alert_id, user_id) VALUES (current_timestamp, 'text1 text', _event_idnumber, 1);
INSERT INTO public.comments ( created_date, content, alert_id, user_id) VALUES (current_timestamp, 'text2 text.', _event_idnumber, 1);
INSERT INTO public.analysis ( alert_id, created_date, last_updated, notes) VALUES (_event_idnumber, current_timestamp, current_timestamp, 'text3 text');
UPDATE public.alerts SET status='DONE', outcome='completed', last_updated=current_timestamp, assigned_user_id=1 WHERE id = _event_idnumber;
UPDATE public.alerts SET data = jsonb_set(data, '{other_field}'::text[], input::jsonb) WHERE id = _event_idnumber;
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
END;
$function$;
我读到在某些版本的 postgres 中我必须使用 DO 语句,但不知道如何使用。
我正在按照此页面上的说明进行操作:https://www.postgresql.org/docs/9.6/plpgsql-control-structures.html
因为 SQL 是一种基于集合的语言,用于直接的逻辑操作,您应该处理集合中的追加和更新,而不是像评论中那样处理迭代循环调用。因此,将过程语言 plpgsql
转换为纯 sql
。具体来说,考虑 select 插入 UNION
并组合更新语句。
CREATE OR REPLACE FUNCTION public.close(input text)
RETURNS void
LANGUAGE sql
AS $function$
-- COMMENTS INSERT
INSERT INTO public.comments (created_date, content, alert_id, user_id)
SELECT current_timestamp, 'text1 text', a.id, 1
FROM public.alerts a
WHERE a.data ->> 'field_name' = input
UNION ALL
SELECT current_timestamp, 'text2 text.', a.id, 1
FROM public.alerts a
WHERE a.data ->> 'field_name' = input;
-- ANALYSIS INSERT
INSERT INTO public.analysis (alert_id, created_date, last_updated, notes)
SELECT a.id, current_timestamp, current_timestamp, 'text3 text'
FROM public.alerts a
WHERE a.data ->> 'field_name' = input;
-- ALERTS UPDATE
UPDATE public.alerts a
SET status='DONE',
outcome='completed',
last_updated=current_timestamp,
assigned_user_id=1,
data = jsonb_set(data, '{other_field}'::text[], input::jsonb)
WHERE a.data ->> 'field_name' = input;
$function$;
Online demo (随机使用 40 'postgres'
行 mydata
table)
我是 Postgres 的新手,但我已经通过 pgAdmin 4.15 创建了一个函数,Postgres 的版本是 9.6。
问题是我无法让它工作,我认为语法有问题?
INSERT 和 UPDATE 语句正在工作(在函数外),所以它必须是函数语法...
目的是通过 jdbc 插件 (Logstash) 调用此函数,并使用给定的 "input" 字符串作为键更新一些表。
"key"用于SELECT要操作的报警ID。
因此,对于我获得的每个 ID,我需要在这些表上执行一些 UPDATE/INSERT。
# \sf close_event
CREATE OR REPLACE FUNCTION public.close(input text)
RETURNS void
LANGUAGE plpgsql
AS $function$
DECLARE
_event_idnumber INTEGER;
BEGIN
FOR _event_idnumber IN
SELECT id FROM public.alerts WHERE data ->> 'field_name' = input
LOOP
INSERT INTO public.comments ( created_date, content, alert_id, user_id) VALUES (current_timestamp, 'text1 text', _event_idnumber, 1);
INSERT INTO public.comments ( created_date, content, alert_id, user_id) VALUES (current_timestamp, 'text2 text.', _event_idnumber, 1);
INSERT INTO public.analysis ( alert_id, created_date, last_updated, notes) VALUES (_event_idnumber, current_timestamp, current_timestamp, 'text3 text');
UPDATE public.alerts SET status='DONE', outcome='completed', last_updated=current_timestamp, assigned_user_id=1 WHERE id = _event_idnumber;
UPDATE public.alerts SET data = jsonb_set(data, '{other_field}'::text[], input::jsonb) WHERE id = _event_idnumber;
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
END;
$function$;
我读到在某些版本的 postgres 中我必须使用 DO 语句,但不知道如何使用。
我正在按照此页面上的说明进行操作:https://www.postgresql.org/docs/9.6/plpgsql-control-structures.html
因为 SQL 是一种基于集合的语言,用于直接的逻辑操作,您应该处理集合中的追加和更新,而不是像评论中那样处理迭代循环调用。因此,将过程语言 plpgsql
转换为纯 sql
。具体来说,考虑 select 插入 UNION
并组合更新语句。
CREATE OR REPLACE FUNCTION public.close(input text)
RETURNS void
LANGUAGE sql
AS $function$
-- COMMENTS INSERT
INSERT INTO public.comments (created_date, content, alert_id, user_id)
SELECT current_timestamp, 'text1 text', a.id, 1
FROM public.alerts a
WHERE a.data ->> 'field_name' = input
UNION ALL
SELECT current_timestamp, 'text2 text.', a.id, 1
FROM public.alerts a
WHERE a.data ->> 'field_name' = input;
-- ANALYSIS INSERT
INSERT INTO public.analysis (alert_id, created_date, last_updated, notes)
SELECT a.id, current_timestamp, current_timestamp, 'text3 text'
FROM public.alerts a
WHERE a.data ->> 'field_name' = input;
-- ALERTS UPDATE
UPDATE public.alerts a
SET status='DONE',
outcome='completed',
last_updated=current_timestamp,
assigned_user_id=1,
data = jsonb_set(data, '{other_field}'::text[], input::jsonb)
WHERE a.data ->> 'field_name' = input;
$function$;
Online demo (随机使用 40 'postgres'
行 mydata
table)