PL / pgSQL: нельзя использовать переменную справа от оператора `in` - PullRequest
0 голосов
/ 10 мая 2018

Я пишу функцию с использованием PostgreSQL 10 и не могу понять, как извлечь подзапрос, который я использую, в переменную.Мой код выглядит следующим образом:

create function "is_valid_slot_task"() returns trigger as $$
<<block>>
declare
    schedule_id integer;
    ...
begin
    block.schedule_id := (select distinct c."schedule_id"
                          from "slot" as s
                          join "column" as c on c."column_id" = s."column_id"
                          where s."slot_id" = new."slot_id");
    if block.schedule_id
       in
       (select distinct c."schedule_id"
        from "slot_task" as st
        join "slot" as s on s."slot_id" = st."slot_id"
        join "column" as c on c."column_id" = s."column_id"
        where st."task_id" = new."task_id")
    ...

Он работает как положено (вы можете попробовать его здесь ).

Мой вопрос заключается в том, как можно извлечь подзапрос направая часть in в переменную, похожую на эту

create function "is_valid_slot_task"() returns trigger as $$
<<block>>
declare
    schedule_id integer;
    schedule_ids integer[];
    ...
begin
    block.schedule_id := (select distinct c."schedule_id"
                          from "slot" as s
                          join "column" as c on c."column_id" = s."column_id"
                          where s."slot_id" = new."slot_id");
    block.schedule_ids := (select distinct c."schedule_id"
                           from "slot_task" as st
                           join "slot" as s on s."slot_id" = st."slot_id"
                           join "column" as c on c."column_id" = s."column_id"
                           where st."task_id" = new."task_id");
    if block.schedule_id
       in
       block.schedule_ids
       ...

Разница в том, что я пытаюсь объявить переменную, которой я хочу присвоить результат подзапроса (list / array / collection Целые числа), а затем я использую это в правой части оператора in.

Эта последняя версия не работает, я получаю SQL Error [42601]: ERROR: syntax error at or near "block" ....Здесь вы можете увидеть это в действии .

Как я мог сделать эту работу?Что я делаю неправильно?Есть ли решение?

Моя цель - позже использовать результат подзапроса, чтобы не вводить один и тот же запрос несколько раз, и понять, почему я не смог этого сделать.Я также пробовал разные типы данных в объявлении: any, %ROWTYPE, но я просто не мог понять, что происходит.

1 Ответ

0 голосов
/ 10 мая 2018

Переменная schedule_ids является массивом, вы должны присвоить ей значение массива, используя array_agg().Затем используйте ANY (array expression) вместо оператора IN:

block.schedule_ids := (select array_agg(distinct c."schedule_id")
                       from "slot_task" as st
                       join "slot" as s on s."slot_id" = st."slot_id"
                       join "column" as c on c."column_id" = s."column_id"
                       where st."task_id" = new."task_id");
if block.schedule_id = any (block.schedule_ids)

DbFiddle.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...