juc*_*ele 4 postgresql select dynamic-sql psql
我有一个带有长文本列的表.我希望能够选择所有列但限制文本列而无需编写每一列.
select * from resources;
Run Code Online (Sandbox Code Playgroud)
产生的输出太长而无法在psql中正确显示.我可以通过使用substr()或left()在长列上显示某些内容,但之后我需要指定每列.
select id, left(data, 50), file_format_version, ... from resources;
Run Code Online (Sandbox Code Playgroud)
当我查询第一个时,是否有一种方法可以让psql默认截断长列select * from resources?
我不知道如何使用psql的内置选项.
您可以通过@Drazen建议的功能实现您的目标- 更简单:
CREATE OR REPLACE FUNCTION f_trunc_columns(_tbl anyelement, _len int = 25)
RETURNS SETOF anyelement AS
$func$
DECLARE
_typ CONSTANT regtype[] := '{bpchar, varchar}'; -- types to shorten
BEGIN
RETURN QUERY EXECUTE (
SELECT format('SELECT %s FROM %s'
, string_agg(CASE WHEN a.atttypid = 'text'::regtype -- simple case text
THEN format('left(%I, %s)', a.attname, _len)
WHEN a.atttypid = ANY(_typ) -- other short types
THEN format('left(%I::text, %s)::%s'
, a.attname, _len, format_type(a.atttypid, a.atttypmod))
ELSE quote_ident(a.attname) END -- rest
, ', ' ORDER BY a.attnum)
, pg_typeof(_tbl))
FROM pg_attribute a
WHERE a.attrelid = pg_typeof(_tbl)::text::regclass
AND NOT a.attisdropped -- no dropped (dead) columns
AND a.attnum > 0 -- no system columns
);
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
电话示例:
SELECT * FROM f_trunc_columns(NULL::my_table);
SELECT * FROM f_trunc_columns(NULL::"MySchema"."My_funny_tbl", 11);
Run Code Online (Sandbox Code Playgroud)
适用于任何具有任何数据类型列的表.
这构建并执行以下形式的查询:
SELECT "FoO_id", left(c_text, 11), left(c_vc, 11)::character varying
FROM "FoO";
Run Code Online (Sandbox Code Playgroud)它仅缩短所选数据类型的列,并使其他数据类型单独使用.我包括基本字符类型:
bpchar是内部名称character和所有变体.
varchar是character varying所有变体的内部名称.
满足您的需求.
该函数返回所有列的原始列名称和数据类型.我在输入text之前将短列投射到left(),返回text,因此text列不需要另一个投射.所有其他缩短类型都需要转换回原始类型.如果你截断,有些类型会破坏!所以这不适用于所有类型.
您可以附加LIMIT n到函数调用,但是可以使用内置函数轻松扩展该函数LIMIT- 这对于大表来说效率更高,因为plpgsql函数内的查询是独立计划的.
性能并不比平原差SELECT * FROM tbl- 除了上述LIMIT案例或嵌套函数的其他情况.设置返回的PL/pgSQL函数通常最好不要嵌套:
我建在一个默认的最大值.长度为25个字符,将自定义长度作为第二个参数传递,或根据需要调整函数头中的默认值.
此功能可以安全地防止通过恶意制作的标识符进行可能的SQL注入攻击.
相关答案以及更多解释和链接:
...具有您要求的功能,顺便说一句(对于所有列):
| 归档时间: |
|
| 查看次数: |
3110 次 |
| 最近记录: |