[英]PostgreSQL array of type table/setof
我需要在 postgresql 中編寫一個 function 代碼,它必須根據條件從表中“挑選”整行,然后將它們插入到數組中,最后返回該數組。
我實際上是在查詢我需要的行,但是表中有一個特殊的列,我必須首先評估它,看看我是否可以檢索它(插入到數組中),具體取決於正在執行查詢的用戶類型(客戶或工人)。
例如:
特殊列名為“watchers”,有兩個變體:“my_team”和“only_me”,還有一個名為“user_id”的列。
如果該列顯示“my_team”,則該行可以毫無問題地插入到數組中,但如果它顯示“only_me”,我必須比較調用 function 的用戶的 ID 和在該行中注冊的用戶,如果它們匹配我可以把它插入到數組中,否則我不能。
事情是,正如我到目前為止所讀到的那樣,它似乎不能用 arrays 來完成,所以我想知道是否有另一種方法可以做到這一點,也許有一張額外的桌子或什么的?
謝謝你的幫助!
這是我的代碼:
CREATE OR REPLACE FUNCTION public.calculates_permission_by_task(task_id integer)
RETURNS SETOF permission
LANGUAGE plpgsql
STABLE
AS $function$
DECLARE
num int := 5;
record permission;
ret_permissions permission [];
BEGIN
FOR record IN (select
p.id, p.slug
from task as t
join service_request_form as srf on t.service_request_form_id = srf.id
join service_group as sg on srf.service_group_id = sg.id
join worker_group as wg on wg.service_group_id = sg.id
join worker_group_member as wgm on wg.id = wgm.worker_group_id
join role as r on r.id = wgm.role_id
join permission_role as pr on r.id = pr.role_id
join permission as p on p.id = pr.permission_id
where t.id = task_id
and wgm.user_id = 'LFudaU6jzid4SKFlU8MgFAwezyP2'
and pr.value <> 'off'
and pr.value <> 'no')
LOOP
/* Here is where I pretend to do the comparison and insert data into the array */
ret_permission := array_append(ret_permissions, record.id);
END LOOP;
RETURN ret_permissions;
END
$function$
您可以在查詢本身中實現邏輯。
假設您引用的user_id
列對應於wgm.user_id
,它已經在查詢中,則查詢的where
子句將變為:
where
t.id = task_id
and pr.value not in ('off', 'no')
and (
?.watchers = 'my_team'
or (
?.watchers = 'only_me'
or wgm.user_id = 'LFudaU6jzid4SKFlU8MgFAwezyP2'
)
)
你不告訴watches
屬於哪個表,所以我用了?
,您需要將其替換為相關的表別名。
如果watchers
只有兩個可能的值,那么我們可以簡化謂詞:
where
t.id = task_id
and pr.value not in ('off', 'no')
and (?.watchers = 'my_team' or wgm.user_id = 'LFudaU6jzid4SKFlU8MgFAwezyP2')
CREATE TABLE permission (
id integer
, slug text
);
INSERT INTO permission(id,slug) VALUES (1,'WTF' );
CREATE TABLE task (
id integer
, service_request_form_id integer
);
INSERT INTO task(id, service_request_form_id) VALUES (1,1 );
CREATE TABLE service_request_form (
id integer
, service_group_id integer
);
INSERT INTO service_request_form(id, service_group_id) VALUES (1,1 );
CREATE TABLE service_group (
id integer
);
INSERT INTO service_group(id) VALUES (1);
CREATE TABLE worker_group (
id integer
, service_group_id integer
);
INSERT INTO worker_group(id, service_group_id) VALUES (1,1 );
CREATE TABLE worker_group_member (
worker_group_id integer
, role_id integer
, user_id text
);
INSERT INTO worker_group_member(worker_group_id, role_id,user_id) VALUES (1,1,'LFudaU6jzid4SKFlU8MgFAwezyP2' );
CREATE TABLE zrole (
id integer
);
INSERT INTO zrole(id) VALUES (1 );
CREATE TABLE permission_role (
role_id integer
, permission_id integer
, value text
);
INSERT INTO permission_role(role_id,permission_id,value) VALUES (1,1,'Yes' );
CREATE OR REPLACE FUNCTION public.calculates_permission_by_task(task_id integer)
RETURNS SETOF permission
LANGUAGE sql STABLE SECURITY INVOKER ROWS 30 -- COST 1
AS $func$
SELECT p.id, p.slug
FROM permission as p
WHERE EXISTS (
SELECT *
FROM task as t
JOIN service_request_form as srf
on t.service_request_form_id = srf.id
JOIN service_group as sg
on srf.service_group_id = sg.id
JOIN worker_group as wg
on wg.service_group_id = sg.id
JOIN worker_group_member as wgm
on wg.id = wgm.worker_group_id
JOIN zrole as zr
on zr.id = wgm.role_id
JOIN permission_role as pr
on zr.id = pr.role_id
WHERE p.id = pr.permission_id
AND t.id = task_id
and wgm.user_id = 'LFudaU6jzid4SKFlU8MgFAwezyP2'
and pr.value NOT IN( 'off' , 'no' )
-- -------------------------
-- Add the needed logic
-- (From @GMB) here
-- -------------------------
);
$func$
;
-- Usage:
-- --------------
SELECT * -- p.id, p.slug
FROM public.calculates_permission_by_task(42);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.