ошибка при использовании предложения Union postgresql 9.5

CREATE OR REPLACE FUNCTION public.get_locations(
    location_word varchar(50)
    ) 
RETURNS TABLE
(
    country varchar(50),
    city varchar(50)
)
AS $$
DECLARE
location_word_ varchar(50);
BEGIN
location_word_:=concat(location_word, '%');
RETURN QUERY EXECUTE format('   (SELECT c.country, ''::varchar(50) as city FROM webuser.country c 
                                    WHERE lower(c.country)  LIKE %L  LIMIT 1)
                                UNION
                                (SELECT c.country,ci.city FROM webuser.country c
                                    JOIN webuser.city ci ON c.country_id=ci.country_id
                                    WHERE lower(ci.city) LIKE %L LIMIT 4)', 
                                    location_word_,
                                    location_word_ )    ;

END
$$ language PLPGSQL STABLE;

Это ошибка, которую я получаю;

  • ОШИБКА: синтаксическая ошибка в или около "%"
  • СТРОКА 2: ГДЕ ниже (c.country) LIKE 'a%' LIMIT 1)

Почему я получаю эту ошибку?

ИЗМЕНИТЬ

Когда я только что заменил ''::varchar(50) на ''''::varchar(50), все заработало!


person lowdegeneration    schedule 15.09.2016    source источник
comment
%L — это опечатка вместо '%L' в кавычках. Могут быть и другие проблемы, но это должно исправить ошибку, о которой вы сообщили.   -  person Tim Biegeleisen    schedule 15.09.2016
comment
Почему функция PL/pgSQL? Почему динамический SQL? Это можно сделать намного проще с помощью простой функции SQL и без динамического SQL. dpaste.com/1A96R5C   -  person a_horse_with_no_name    schedule 15.09.2016
comment
@a_horse_with_no_name я не знаю, я обычно использую этот способ... хорошо, если я не могу это исправить, я буду использовать ваш код...   -  person lowdegeneration    schedule 15.09.2016
comment
@Tim Biegeleisen, мне жаль, что это не сработало...   -  person lowdegeneration    schedule 15.09.2016


Ответы (1)


Попробуйте следующую исправленную функцию:

CREATE OR REPLACE FUNCTION public.get_locations(
    location_word varchar(50)
    ) 
RETURNS TABLE
(
    country varchar(50),
    city varchar(50)
)
AS $$
DECLARE
location_word_ varchar(50);
BEGIN
location_word_:=concat(location_word, '%');
RETURN QUERY EXECUTE format('   (SELECT c.country, ''''::varchar(50) as city FROM webuser.country c 
                                    WHERE c.country ILIKE ''%L'' LIMIT 1)
                                UNION
                                (SELECT c.country,ci.city FROM webuser.country c
                                    JOIN webuser.city ci ON c.country_id=ci.country_id
                                    WHERE ci.city ILIKE ''%L'' LIMIT 4)', 
                                    location_word_,
                                    location_word_ )    ;

END
$$ language PLPGSQL STABLE;
person Kostya Zhevlakov    schedule 15.09.2016
comment
Заполнитель %L будет добавлять одинарные кавычки по мере необходимости. не включайте их в строку формата ''%L'', так как во время выполнения будут создаваться дополнительные одинарные кавычки. Виновником является ''::varchar(50), который должен быть ''''::varchar(50), как вы это сделали. - person a_horse_with_no_name; 15.09.2016
comment
Затем попробуйте объединить строку запроса и location_word_, например: .. ILIKE ' || location_word_ || ' LIMIT ... - person Kostya Zhevlakov; 15.09.2016
comment
Или вы можете попробовать использовать двойной % в следующей строке: location_word_:=concat(location_word, '%%');. В дополнение к спецификаторам формата, описанным выше, специальная последовательность %% может использоваться для вывода буквального символа %. - person Kostya Zhevlakov; 15.09.2016