我想获得blob的字节大小。
我正在使用Postgresql,并希望使用SQL查询获取大小。像这样:
SELECT sizeof(field) FROM table;
这是否可以在Postgresql中使用?
更新:我已阅读postgresql手册,但找不到合适的函数来计算文件大小。此外,blob存储为大对象。
答案 0 :(得分:14)
并非我使用大型对象,而是查看文档:{{3}}
我认为你必须使用与某些文件系统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;
$$;
测试它:
-- 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);
似乎LO功能主要是通过客户端或通过低级服务器编程来使用,但至少它们为它提供了一些SQL可见功能,这使得上述功能成为可能。我对SELECT relname FROM pg_proc where relname LIKE 'lo%'
进行了查询以使自己开始。其余部分需要对C编程的模糊记忆以及对x'40000'::int
和SEEK_END = 2
模式的一些研究!
答案 1 :(得分:14)
您可以在创建大对象时更改应用程序以存储大小。否则,您可以使用以下查询:
select sum(length(lo.data)) from pg_largeobject lo
where lo.loid=XXXXXX
您也可以使用大型对象API函数,如前一篇文章所述,它们可以正常工作,但比上面建议的select方法慢一个数量级。
答案 2 :(得分:7)
select pg_column_size(lo_get(lo_oid)) from table;
以字节为单位给出大小。
如果你想要漂亮的印刷:
select pg_size_pretty(pg_column_size(lo_get(lo_oid))::numeric) from table;
答案 3 :(得分:5)
尝试length()
或octet_length()
答案 4 :(得分:2)
这是我的解决方案:
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;
答案 5 :(得分:1)
如果 blob 列的类型是 oid
SELECT length(lo_get(blob_column)) FROM table;
<块引用>
lo_get ( loid oid [, offset bigint, length integer ] ) → bytea
提取大对象的内容或其子字符串。
– https://www.postgresql.org/docs/current/lo-funcs.html
<块引用>长度 ( bytea ) → 整数
返回二进制字符串中的字节数。
– https://www.postgresql.org/docs/current/functions-binarystring.html
答案 6 :(得分:0)
到目前为止,我找到了复杂的解决方案。只需
@Suppress("UNCHECKED_CAST")
fun <E : Event> E.toAdapter() : EventAdapter<E>? {
return when(this) {
is MessageCreateEvent -> MessageCreateAdapter(this) as EventAdapter<E>
is MessageUpdateEvent -> MessageUpdateAdapter(this) as EventAdapter<E>
else -> null
}
}