ブロブのバイトサイズを取得したいと思います。
Postgresql を使用しており、SQL クエリを使用してサイズを取得したいと考えています。このようなもの:
SELECT sizeof(field) FROM table;
これはPostgresqlで可能ですか?
更新: postgresql のマニュアルを読みましたが、ファイル サイズを計算するための適切な関数が見つかりませんでした。また、ブロブは大きなオブジェクトとして保存されます。
ブロブのバイトサイズを取得したいと思います。
Postgresql を使用しており、SQL クエリを使用してサイズを取得したいと考えています。このようなもの:
SELECT sizeof(field) FROM table;
これはPostgresqlで可能ですか?
更新: postgresql のマニュアルを読みましたが、ファイル サイズを計算するための適切な関数が見つかりませんでした。また、ブロブは大きなオブジェクトとして保存されます。
大きなオブジェクトを使用したわけではありませんが、ドキュメントを見てください: 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;
$$;
テスト:
-- 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
値に関する少しの調査が残りの部分に必要でした!
大きなオブジェクトを作成するときにサイズを保存するようにアプリケーションを変更できます。それ以外の場合は、次のようなクエリを使用できます。
select sum(length(lo.data)) from pg_largeobject lo
where lo.loid=XXXXXX
以前の投稿で提案されているように、ラージ オブジェクト API 関数も使用できます。これらは問題なく動作しますが、上で提案した select メソッドよりも桁違いに遅くなります。
select pg_column_size(lo_get(lo_oid)) from table;
サイズをバイト単位で提供します。
きれいに印刷したい場合:
select pg_size_pretty(pg_column_size(lo_get(lo_oid))::numeric) from table;
試してみるlength()
かoctet_length()