Postgres 函数 - 使用 table 映射更新值
Postgres function - using table mapping to update value
我有一个一般性问题。我有一个创建文件的功能。但是,目前在该函数中,我正在根据参数输入对文件名模式进行硬编码。现在我已经到了需要多个文件名模式的地步。我设计了一种使用另一个 table 作为文件名映射的方法,如果用户输入该文件名模式 ID,该函数可以简单地调用该文件名映射。这是我的示例,以帮助更好地说明我的观点:
下面是table的创建和数据插入,供参考:
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 ;
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,如果我执行脚本,我希望得到 returned 的 "Shmoe_Shmoe.csv" 文件:
select from some_schema.some_function(2)
问题是,每当我让它读取 "v_filename" 变量时,它不会计算 return 函数变量的值。最初,我认为这是一个引用问题(现在可能仍然是)。在弄乱了引用之后,我得到了以下错误:
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
如您所知,这几乎是在告诉我这是一个引用问题。有没有办法让函数正确评估变量和 return 正确的文件名?如果我不清楚并需要详细说明,请告诉我。
这或多或少说明了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 ;
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);
总结:
- 使用 %I 作为标识符(表名和列名)[
FROM %I
]
- 将 %L 用于查询常量等文字 [
WHERE the_date = %L
]
- 对普通字符串使用 %s [
to \'/tmp/%s.csv\'
]
我有一个一般性问题。我有一个创建文件的功能。但是,目前在该函数中,我正在根据参数输入对文件名模式进行硬编码。现在我已经到了需要多个文件名模式的地步。我设计了一种使用另一个 table 作为文件名映射的方法,如果用户输入该文件名模式 ID,该函数可以简单地调用该文件名映射。这是我的示例,以帮助更好地说明我的观点:
下面是table的创建和数据插入,供参考:
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 ;
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,如果我执行脚本,我希望得到 returned 的 "Shmoe_Shmoe.csv" 文件:
select from some_schema.some_function(2)
问题是,每当我让它读取 "v_filename" 变量时,它不会计算 return 函数变量的值。最初,我认为这是一个引用问题(现在可能仍然是)。在弄乱了引用之后,我得到了以下错误:
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
如您所知,这几乎是在告诉我这是一个引用问题。有没有办法让函数正确评估变量和 return 正确的文件名?如果我不清楚并需要详细说明,请告诉我。
这或多或少说明了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 ;
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);
总结:
- 使用 %I 作为标识符(表名和列名)[
FROM %I
] - 将 %L 用于查询常量等文字 [
WHERE the_date = %L
] - 对普通字符串使用 %s [
to \'/tmp/%s.csv\'
]