Postgres — использовать имя таблицы (переданное в параметре) в теле функции

#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; .