2012-04-16 14 views
9

मैं एक ब्लॉब के बाइट आकार प्राप्त करना चाहता हूं।PostgreSQL क्वेरी में बड़ी वस्तु का आकार प्राप्त करें?

मैं पोस्टग्रेस्क्ल का उपयोग कर रहा हूं और SQL क्वेरी का उपयोग कर आकार प्राप्त करना चाहता हूं। कुछ ऐसा:

SELECT sizeof(field) FROM table; 

क्या यह पोस्टग्रेस्क्ल में संभव है?

अपडेट: मैंने पोस्टग्रेस्क्ल मैनुअल पढ़ा है और फ़ाइल आकार की गणना करने के लिए उचित फ़ंक्शन नहीं मिला। इसके अलावा, ब्लॉब को एक बड़ी वस्तु के रूप में संग्रहीत किया जाता है।

+0

कृपया इस तरह के एक प्रश्न पोस्ट करने से पहले मैनुअल पढ़ें: http://www.postgresql.org/docs/current/static/functions.html –

+2

परिभाषित करें "ब्लॉब डेटा "। एक बाइट कॉलम '? या 'pg_largeobject' में संग्रहीत एक बड़ी वस्तु? अपनी टेबल परिभाषा दिखाएं। –

+0

पोस्टग्रेस एसक्यूएल में लॉबजेक्ट के आकार को प्राप्त करने के डुप्लिकेट] (http://stackoverflow.com/questions/9248738/obtaining-the-size-of-lobject-in-postgressql)? –

उत्तर

12

ऐसा नहीं है कि मैं बड़ी वस्तुओं का उपयोग किया है की कोशिश करो, लेकिन डॉक्स पर देख रहे हैं: http://www.postgresql.org/docs/current/interactive/lo-interfaces.html#LO-TELL

मुझे लगता है कि आप के रूप में कुछ फाइल सिस्टम एपीआई की आवश्यकता होती है उसी तकनीक का उपयोग करने के लिए है: के लिए की तलाश अंत, फिर स्थिति बताओ। PostgreSQL में 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); 

ऐसा लगता है एलओ कार्यक्षमता ग्राहक के माध्यम से या निम्न स्तर के सर्वर प्रोग्रामिंग के माध्यम से ज्यादातर इस्तेमाल किया जा बनाया गया है , लेकिन कम से कम उन्होंने इसके लिए कुछ SQL दृश्य फ़ंक्शंस प्रदान किए हैं, जो उपरोक्त संभव बनाता है। मैंने खुद को शुरू करने के लिए SELECT relname FROM pg_proc where relname LIKE 'lo%' के लिए एक प्रश्न किया था। सी प्रोग्रामिंग की अस्पष्ट यादें और मोड के लिए थोड़ा सा शोध x'40000'::int और SEEK_END = 2 मूल्य बाकी के लिए आवश्यक थे!

10

जब आप बड़ी वस्तु बनाते हैं तो आप आकार को स्टोर करने के लिए अपना एप्लिकेशन बदल सकते हैं। नहीं तो आप के रूप में एक क्वेरी का उपयोग कर सकते हैं:

select sum(length(lo.data)) from pg_largeobject lo 
where lo.loid=XXXXXX 

तुम भी उपयोग कर सकते हैं बड़ी वस्तु एपीआई काम करता है, के रूप में एक पिछली पोस्ट में सुझाव दिया है, वे ठीक से काम करते हैं, लेकिन परिमाण धीमी गति से चयन विधि ऊपर सुझाई गई एक आदेश हैं ।

+0

यह सबसे साफ समाधान है। धन्यवाद – MarekM

+1

दुर्भाग्य से, 'pg_largeobject' कैटलॉग अब सार्वजनिक रूप से सुलभ नहीं है क्योंकि PostgreSQL 9.0: https://www.postgresql.org/docs/current/static/catalog-pg-largeobject.html। – ochedru

4
select pg_column_size(lo_get(lo_oid)) from table; 

आपको बाइट्स में आकार देता है।

आप सुंदर मुद्रण चाहते हैं:

select pg_size_pretty(pg_column_size(lo_get(lo_oid))::numeric) from table; 
संबंधित मुद्दे