Вызов хранимой процедуры внутри хранимой процедуры

Я пытаюсь вызвать функцию внутри функции, используя sql на postgres 9.3.

Этот вопрос связан с другим постом мной.

Я написал следующую функцию. Пока что мне не удалось включить какой-либо оператор сохранения-вывода (COPY), поэтому я пытаюсь обойти это, создав функцию распечатки вложенной функции.

CREATE FUNCTION retrieve_info(TEXT, TEXT) RETURNS SETOF   
retrieve_info_tbl AS $$
 SELECT tblA.id, tblA.method, tblA.species, tblA.location
 FROM tblA
 WHERE method=$1 AND species=$2
 GROUP BY id, method, species
 ORDER BY location
$$ LANGUAGE 'sql';

Вышеуказанная функция работает.

Попытка создать вложенную функцию.

CREATE FUNCTION print_out(TEXT, TEXT) RETURNS void AS $$
 COPY (SELECT * FROM retrieve_info($1, $2)) TO 'myfilepath/test.csv'    
 WITH CSV HEADER;
$$ LANGUAGE 'sql';

Вызов вложенной функции.

SELECT * FROM print_out('mtd1','sp1');

ВЫХОД

Вышесказанное дает это ERROR: column "$1" does not exist SQL state: 42P02 Context: SQL function "print_out" statement 1, Однако при замене arg1, arg2 в print_out() на mtd1, sp1 правильный вывод выводится в test.csv (как показано ниже)

id | method | ind | location
----------------------------
1a | mtd1   | sp3 | locA
1d | mtd1   | sp3 | locB

Как получить arg1, arg2 функции retrieve_info () для правильного вызова arg1, arg2 внутри print_out()?

Я полностью застрял. Буду признателен за любые указатели, спасибо

2 ответа

Решение

КОПИЯ немного странная, так как query аргумент в виде строки, даже если он не записан в виде строки. Результатом является то, что query:

SELECT * FROM retrieve_info($1, $2)

не выполняется в контексте функции, он выполняется в контексте самой COPY. Даже если вы говорите:

copy (select * from t) ...

это больше воспринимается как если бы вы писали:

copy 'select * from t' ...

поэтому к моменту выполнения запроса параметры функции уже не имеют никакого значения, query Аргумент COPY может выглядеть так, как будто он ведет себя как замыкание в других языках, но это не так, он действует скорее как строка, которая передается в eval,

Вы можете обойти эту странность, используя обычный Kludge of Last Resort: динамический SQL. Вы должны получить лучшие результаты, если вы напишите свою функцию для использования преобразования строк и EXECUTE:

create or replace function print_out(text, text) returns void as $$
begin
    execute 'copy ('
         || 'select * from retrieve_info'
         ||     '(' || quote_literal($1) || ',' || quote_literal($2) || ')'
         || ') to ''myfilepath/test.csv'' with csv header;';
end;
$$ language plpgsql;

Являются x а также y намеренно процитировано?

COPY (SELECT * FROM retrieve_info('x','y')) TO 'myfilepath/test.csv'

Вы не отправляете x а также y аргументы print_out в retrieve_info - скорее, вы отправляете строки 'x' а также 'y', Предполагая, что у вас нет записей с method='x' AND species='y'Не удивительно, что вы не получите никаких результатов.

Попробуйте это вместо этого:

COPY (SELECT * FROM retrieve_info(x,y)) TO 'myfilepath/test.csv'
Другие вопросы по тегам