Я пытаюсь создать функцию на Postgres 10, которая будет проверять, существуют ли все заданные идентификаторы в целевой таблице.
CREATE OR REPLACE FUNCTION "public"."has_mismatching_ids"(
_ids TEXT[],
_column_name TEXT,
_table_name TEXT,
_schema_name TEXT DEFAULT 'public'
)
RETURNS BOOLEAN AS
$$
DECLARE
result TEXT[] := '{}';
_query TEXT := '';
BEGIN
IF _ids IS NULL THEN
RETURN false;
END IF;
_query := CONCAT('SELECT UNNEST($1) EXCEPT SELECT "', _column_name, '" FROM "', _schema_name ,'"."', _table_name ,'"');
EXECUTE _query INTO result USING $1;
RAISE NOTICE 'Executed';
IF array_length(result, 1) > 0 THEN
RETURN true;
END IF;
RETURN false;
END;
$$
LANGUAGE plpgsql
STABLE
SECURITY INVOKER;
Это моя функция, которая возвращает правильно значение true, если существуют все идентификаторы,но он выдает исключение, если какой-либо из идентификаторов не существует.
CREATE TABLE "public"."categories" ("category_id" TEXT NOT NULL PRIMARY KEY);
INSERT INTO "public"."categories" ("category_id") VALUES ('foo');
INSERT INTO "public"."categories" ("category_id") VALUES ('bar');
Это работает
SELECT FROM "public"."has_mismatching_ids"(ARRAY['foo'], 'category_id', 'categories', 'public');
NOTICE: Executed
has_mismatching_ids
---------------------
f
(1 row)
, но это не удается даже
SELECT FROM "public"."has_mismatching_ids"(ARRAY['foo2'], 'category_id', 'categories', 'public');
ERROR: malformed array literal: "foo2"
DETAIL: Array value must start with "{" or dimension information.
CONTEXT: PL/pgSQL function public.has_mismatching_ids(text[],text,text,text) line 14 at EXECUTE
и странным образомэто работает также, если я пишу функцию, которая использует явные имена и без EXECUTE
SELECT UNNEST(ARRAY['foo', 'foo3']) EXCEPT SELECT "category_id" FROM "public"."categories";
unnest
--------
foo3
(1 row)
Почему моя динамическая функция не работает при сравнении со значениями, которые не существуют в целевой таблице?