使用 PostgreSQL 的占位符模板

Pet*_*uss 6 postgresql formatting

我需要一个像这样的函数

SELECT vformat('Hello %%! Bye %%...', array['John','Maria'], '%%');
-- 'Hello John! Bye Maria...'
Run Code Online (Sandbox Code Playgroud)

提供带有占位符的字符串(模板)以及向量中的相应输入,它会返回文本。“占位符标记”是一个自由字符串。

我无法使用 pg9.1 格式(如 sprintf)函数,因为它不允许除 '%' 之外的其他标记(请参阅 ex. Python formatter)并且不允许数组参数(请参阅 ex. vsprintf)。PostgreSQL 9.0(我认为 8.4+)最简单的解决方案是

CREATE FUNCTION array_zipper_string(anyarray,anyarray) RETURNS text AS $$ 
  -- use with bigger array at left
  SELECT string_agg(t.val||coalesce($2[t.idx],''),'')  
  FROM  (SELECT generate_subscripts($1, 1) AS idx, unnest($1) AS val) AS t;
$$ LANGUAGE SQL IMMUTABLE;

CREATE FUNCTION tpl_positional(text,anyarray,varchar DEFAULT '%%') 
RETURNS text AS $$ 
  SELECT array_zipper_string(string_to_array($1,$3),$2);
$$ LANGUAGE SQL IMMUTABLE;
CREATE FUNCTION tpl_positional(
   text, text, varchar DEFAULT '%%',varchar DEFAULT '|' 
) RETURNS text AS $$ 
  SELECT tpl_positional($1,string_to_array($2,$4),$3);
$$ LANGUAGE SQL IMMUTABLE;

-- TESTING:
SELECT tpl_positional('Hello %%! Bye %%...', 'John|Maria');
SELECT tpl_positional('Hello %%!',array['John']);
Run Code Online (Sandbox Code Playgroud)

有众所周知的(开源)函数可以做同样的事情吗?

PS:这样做以及更多(!)...我的愿望清单:

  • 来自标准库的开源
  • 可索引占位符的选项“Hello %%{1}!” 再见%%{2}...'
  • 使用格式化程序的选项,“有 %%2d 只猴子。” 或“有 %%{1|2d} 只猴子。”;

Cha*_* 木匠 10

PostgreSQL FORMAT() 函数根据格式字符串格式化参数。

如果您使用过 C 编程语言,您会发现 FORMAT() 函数与 sprintf() 函数类似。

SELECT FORMAT('Hello, %s','PostgreSQL');

      format
-------------------
 Hello, PostgreSQL
(1 row)
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅http://www.postgresqltutorial.com/postgresql-format/


Cra*_*ger 2

如果 Python 的格式化函数满足您的需要,请通过 PL/Python 包装它并使用它。您需要:

CREATE LANGUAGE plpythonu;
Run Code Online (Sandbox Code Playgroud)

...这可能需要您安装包含 python 语言支持的附加软件包或使用 重新编译--with-python,具体取决于您安装 Pg 的方式或您正在使用的软件包。对于我使用 Fedora 17 软件包来说,它是yum install postgresql-plpython

您需要一个签名,例如:

CREATE OR REPLACE FUNCTION my_format(formatstr text, placeholder text, args VARIADIC text) RETURNS text LANGUAGE 'plpythonu' IMMUTABLE AS $$
 .... body here ....
 $$;
Run Code Online (Sandbox Code Playgroud)

plpython请注意u 的用法。这里u的意思是“不受信任”,即“没有安全模型”。使用不可信语言运行的代码无法受到限制,因此服务器只允许超级用户使用此类语言创建函数。必须编写它们,以便在数据库暴露给不太受信任的用户时,它们不会被欺骗去做作者意图之外的事情。

不幸的是,根据我最后的检查,过程语言对数组的处理不太好。请参阅本文底部的 depesz 文章及其评论。这是可行的,只是比想象的要笨拙。

如果 Python 的格式功能不能满足您的要求,请考虑 Perl。PL/Perl 非常流行,部分原因是与 Python 不同,它有一个安全模型,并且有一个“可信”版本的plperl. 如果您找不到合适的 CPAN 模块来完成您想要的操作,我会感到非常惊讶。函数签名大致相同,只是带有plperl.

请参阅这篇关于 plperl 和 sprintf 的优秀 depesz 文章