Вызов хранимой процедуры внутри хранимой процедуры
Я пытаюсь вызвать функцию внутри функции, используя 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'