Обобщить получение / создание хранимой процедуры от одного элемента ко многим - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть сервер express.js, на котором запущено приложение, и с этого сервера я могу получить доступ или создать "option_id" в PostgreSQL (версия 11) с помощью хранимой процедуры.

SELECT(get_or_create_variant_id(info_about_variant));

Иногда мне также необходимо получить несколько этих идентификаторов вариантов, используя другую хранимую процедуру, которая принимает несколько вариантов и возвращает несколько идентификаторов.

SELECT(get_or_create_variant_ids([info_about_variant, info_about_another_variant]));

Что является лучшимспособ обобщить получение / создание одного идентификатора, чтобы сделать несколько одновременно?Я обрабатываю это в цикле в моей хранимой процедуре, но мне кажется, что я должен иметь возможность использовать JOIN вместо.

CREATE OR REPLACE FUNCTION get_or_create_variant_id(
  variant_in VARIANT_TYPE
) RETURNS INT AS $$
DECLARE variant_id_out INTEGER;
BEGIN
  -- I'll be changing this to a ON CONFLICT block shortly
  SELECT(get_variant_id(variant_in) INTO variant_id_out);
  IF (variant_id_out IS NOT NULL) THEN
    RETURN variant_id_out;
  ELSE
    INSERT INTO public.variant (
        [some_fields]
    )
      VALUES (
        [some_values]
      )
      RETURNING variant_id INTO variant_id_out;
    RETURN variant_id_out;
  END IF;
END;
$$ LANGUAGE plpgsql;

-- What is the best way to avoid a loop here?
CREATE OR REPLACE FUNCTION get_or_create_variant_ids(
  variants_in VARIANT_TYPE []
) RETURNS INT [] AS $$
DECLARE variant_ids_out INTEGER [];
DECLARE variants_in_length INTEGER;
DECLARE current_variant_id INTEGER;
BEGIN
  SELECT (array_length(variants_in, 1) INTO variants_in_length);
  FOR i IN 1..variants_in_length LOOP
    SELECT(get_or_create_variant_id(variants_in[i]) INTO current_variant_id);
    SELECT(array_append(variant_ids_out, current_variant_id) INTO variant_ids_out);
  END LOOP;
  RETURN variant_ids_out;
END;
$$ LANGUAGE plpgsql;

-- Everything below is included for completeness, but probably less relevant to my question.
CREATE TYPE variant_type AS (
   [lots of info about the variant]
);
CREATE OR REPLACE FUNCTION get_variant_id(
  variant_in VARIANT_TYPE
) RETURNS INT AS $$
DECLARE variant_id_out INTEGER;
BEGIN
  SELECT variant_id into variant_id_out
  FROM public.variant
  WHERE
     [I want them to]
  ;
  RETURN variant_id_out;
END;
$$ LANGUAGE plpgsql;

1 Ответ

0 голосов
/ 21 декабря 2018

Вы можете избежать явного цикла, используя встроенные функции массива - в этом случае unnest функцию и конструктор массива .

CREATE OR REPLACE FUNCTION get_or_create_variant_ids_v2(
  variants_in VARIANT_TYPE []
)
RETURNS integer []
LANGUAGE sql AS $$
  SELECT ARRAY(
    SELECT get_or_create_variant_id(u.v)
    FROM unnest(variants_in) AS u(v)
  )
$$ LANGUAGE sql;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...