#postgresql #function
#postgresql #функция
Вопрос:
Я новичок в функциях wrt, и мне трудно использовать имя таблицы в теле функции. Я получаю сообщение об ошибке «Ошибка SQL [42703]: ОШИБКА: столбец «tname» не существует» при вызове функции с помощью
select "JsonToView"('data_import.import_360xero_report');
Мой код приведен ниже
create or replace
function data_import."JsonToView"(tname text) returns numeric
language plpgsql
as $function$
begin
do
$$
declare
l_keys text;
begin
drop view if exists v_json_view cascade;
select
string_agg(distinct format('import_data ->> %L as %I', jkey, jkey), ', ')
into
l_keys
from
import_360xero_report,
json_object_keys(import_data) as t(jkey);
execute 'create view v_json_view as select ' || l_keys || ' from ' || tname;
end;
$$;
return 0;
end $function$ ;
Я изменил код, и второй запрос create view работает с именем таблицы, а первый — нет.
Ниже, если мой измененный код
create or replace
function data_import."JsonToView"(tname text) returns numeric
language plpgsql
as $function$
declare
l_keys text;
begin
drop view if exists v_json_view cascade;
execute $a$select
string_agg(distinct format('import_data ->> %L as %I', jkey, jkey), ', ')
into
l_keys
from $a$ ||
tname || $b$,
json_object_keys(import_data) as t(jkey)$b$;
execute 'create view v_json_view as select ' || l_keys || ' from ' || tname;
return 0;
end $function$ ;
Ошибка, которую я получаю, это
SQL Error [0A000]: ERROR: EXECUTE of SELECT ... INTO is not implemented
Hint: You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead.
Where: PL/pgSQL function "JsonToView"(text) line 10 at EXECUTE
Комментарии:
1. Трудно поверить. В какой строке сообщается об ошибке?
2. Что это
begin do
должно делать? Я бы потерял это и внутренние вложенные$$
кавычки.3. @LaurenzAlbe ошибка находится в строке 17. Точное сообщение об ошибке: «Ошибка SQL [42703]: ОШИБКА: столбец «tname» не существует, где: функция PL / pgSQL inline_code_block строка 17 при ВЫПОЛНЕНИИ …»
4. @AdrianKlaver Я перепроверяю, но я думаю, что то, что вы предложили, похоже, работает сейчас
Ответ №1:
Проблема заключается в избыточном вложенном DO
операторе.
Переменная tname
существует только в области действия функции, а не во вложенном DO
операторе. DO
это оператор SQL, а не оператор PL / pgSQL, и в SQL нет переменных. Кроме того, DO
не разрешает параметры.
Избавьтесь от DO
, и все будет в порядке.
Комментарии:
1. Это отлично работает. Я изменил код. Вторая проблема, с которой я столкнулся (и дайте мне знать, нужно ли мне создать для нее отдельный поток), заключается в том, что выполнение запроса с первым оператором select теперь приводит к ошибке
2. Я не думаю, что это проблема, поскольку я не получаю ошибку не удается найти столбец, вместо этого я получаю
SQL Error [0A000]: ERROR: EXECUTE of SELECT ... INTO is not implemented Hint: You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead. Where: PL/pgSQL function "JsonToView"(text) line 10 at EXECUTE
3. Да, этого не должно быть
EXECUTE $$SELECT x INTO var FROM ...$$;
, ноEXECUTE $$SELECT x FROM ...$$ INTO var;
.