在PostgreSQL查询中获取大对象的大小?

Bob*_*Bob 13 sql postgresql blob

我想获得blob的字节大小.

我正在使用Postgresql,并希望使用SQL查询获取大小.像这样的东西:

SELECT sizeof(field) FROM table;
Run Code Online (Sandbox Code Playgroud)

这在Postgresql中是否可行?

更新:我已阅读postgresql手册,但无法找到合适的函数来计算文件大小.此外,blob存储为大对象.

Edm*_*und 15

不是说我使用过大型对象,而是查看文档:http://www.postgresql.org/docs/current/interactive/lo-interfaces.html#LO-TELL

我认为你必须使用与某些文件系统API要求相同的技术:寻找到最后,然后告诉位置.PostgreSQL具有似乎包含内部C函数的SQL函数.我找不到太多文档,但这有效:

CREATE OR REPLACE FUNCTION get_lo_size(oid) RETURNS bigint
VOLATILE STRICT
LANGUAGE 'plpgsql'
AS $$
DECLARE
    fd integer;
    sz bigint;
BEGIN
    -- Open the LO; N.B. it needs to be in a transaction otherwise it will close immediately.
    -- Luckily a function invocation makes its own transaction if necessary.
    -- The mode x'40000'::int corresponds to the PostgreSQL LO mode INV_READ = 0x40000.
    fd := lo_open($1, x'40000'::int);
    -- Seek to the end.  2 = SEEK_END.
    PERFORM lo_lseek(fd, 0, 2);
    -- Fetch the current file position; since we're at the end, this is the size.
    sz := lo_tell(fd);
    -- Remember to close it, since the function may be called as part of a larger transaction.
    PERFORM lo_close(fd);
    -- Return the size.
    RETURN sz;
END;
$$; 
Run Code Online (Sandbox Code Playgroud)

测试它:

-- Make a new LO, returns an OID e.g. 1234567
SELECT lo_create(0);

-- Populate it with data somehow
...

-- Get the length.
SELECT get_lo_size(1234567);
Run Code Online (Sandbox Code Playgroud)

似乎LO功能主要是通过客户端或通过低级服务器编程来使用,但至少它们为它提供了一些SQL可见功能,这使得上述功能成为可能.我做了一个查询,SELECT relname FROM pg_proc where relname LIKE 'lo%'让自己开始.其余部分需要对C编程的模糊记忆以及对模式x'40000'::intSEEK_END = 2价值的一些研究!

  • 为了避免“结果超出范围”错误并使其适用于大于 2GB 的大型对象,请使用 `lo_seek64` 和 `lo_tell64`。 (2认同)

小智 15

您可以在创建大对象时更改应用程序以存储大小.否则,您可以使用如下查询:

select sum(length(lo.data)) from pg_largeobject lo
where lo.loid=XXXXXX
Run Code Online (Sandbox Code Playgroud)

您还可以使用大对象的API函数,如在以前的文章中提出,他们的工作好了,但幅度慢于选择方法上面建议的顺序.

  • 不幸的是,从 PostgreSQL 9.0 开始,`pg_largeobject` 目录不再公开访问:https://www.postgresql.org/docs/current/static/catalog-pg-largeobject.html。 (2认同)

Chr*_*ers 6

select pg_column_size(lo_get(lo_oid)) from table;
Run Code Online (Sandbox Code Playgroud)

给你大小的字节数.

如果你想要漂亮的印刷:

select pg_size_pretty(pg_column_size(lo_get(lo_oid))::numeric) from table;
Run Code Online (Sandbox Code Playgroud)

  • 不知怎的,它总是比实际多 4 个字节,为什么? (2认同)

i-g*_*i-g 5

尝试length()octet_length()


小智 5

这是我的解决方案:

select
lo.loid,
pg_size_pretty(sum(octet_length(lo.data)))
from pg_largeobject lo
where lo.loid in (select pg_largeobject.loid from pg_largeobject)
group by lo.loid;
Run Code Online (Sandbox Code Playgroud)