我有一个普遍的问题。我有一个创建文件的功能。但是,在该函数中,我目前正在根据参数输入对文件名模式进行硬编码。现在我已经到了需要多个文件名模式的地步。我设计了一种使用另一个表作为文件名映射的方法,如果用户输入该文件名模式id,该函数可以简单地调用该映射。这是我的例子,以帮助更好地说明我的观点:
以下是用于参考目的的表创建和数据插入:
create table some_schema.file_mapper(
mapper_id integer not null,
file_name_template varchar);
insert into some_schema.file_mapper (mapper_id, file_name_template)
values
(1, '||v_first_name||''_''||v_last_name||')
(2, '||v_last_name||''_''||v_first_name||')
(3, '||v_last_name||''_''||v_last_name||');
现在功能本身
create or replace function some_schema.some_function(integer)
returns varchar as
$body$
Declare
v_filename_config_id alias for $1;
v_filename varchar;
v_first_name varchar;
v_last_name varchar;
cmd text;
Begin
v_first_name :='Joe';
v_last_name :='Shmoe';
cmd := 'select file_name_template
from some_schema.file_mapper
where mapper_id = '||v_filename_config||'';
execute cmd into v_filename;
raise notice 'checking "%"',v_filename;
return 'done';
end;
$body$
LANGUAGE plpgsql;
现在我有了这个。我希望能够混合和匹配文件名模式。所以例如我想使用mapper_id 3,如果我执行脚本,我希望返回“Shmoe_Shmoe.csv”文件:
select from some_schema.some_function(2)
问题是每当我得到它来读取“v_filename”变量时它就不会评估它并从函数的变量中返回值。最初,我认为这是一个引用问题(它可能仍然是)。在搞乱引用之后,我已经得到了以下错误:
ERROR: syntax error at or near "_"
LINE 4: ...s/dir/someplace/||v_last_name||'_'||v_firs...
^
QUERY: copy(
select *
from some_schema.some_table)
to '/dir/someplace/||v_last_name||'_'||v_first_name||.csv/;
DELIMITER,
csv HEADER;
CONTEXT: PL/pgSQL function some_schema.some_function(integer) line 27 at EXECUTE statement
正如你所知,它几乎告诉我这是一个引用问题。有没有办法让函数正确评估变量并返回正确的文件名?如果我不清楚并需要详细说明,请告诉我。
答案 0 :(得分:0)
这或多或少说明了format()
的用法。 (原问题略有减少):
CREATE TABLE file_mapper
( mapper_id INTEGER NOT NULL PRIMARY KEY
, file_name_template TEXT
);
INSERT INTO file_mapper(mapper_id, file_name_template) VALUES (1,'one'), (2, 'two');
CREATE OR REPLACE FUNCTION dump_the_shit(INTEGER)
RETURNS VARCHAR AS
$body$
DECLARE
v_filename_config_id alias for $1;
v_filename VARCHAR;
name_cmd TEXT;
copy_cmd TEXT;
BEGIN
name_cmd := format( e'select file_name_template
from file_mapper
where mapper_id = %L;', v_filename_config_id );
EXECUTE name_cmd into v_filename;
RAISE NOTICE 'V_filename := %', v_filename;
copy_cmd := format( e'copy(
select *
from %I)
to \'/tmp/%s.csv\'
csv HEADER;' , 'file_mapper' , v_filename);
EXECUTE copy_cmd;
RETURN copy_cmd;
END;
$body$
LANGUAGE plpgsql;
SELECT dump_the_shit(1);
摘要:
FROM %I
] WHERE the_date = %L
] to \'/tmp/%s.csv\'
]