2013-04-16 5 views
7

मैं कुछ बाइनरी डेटा को BYTEA कॉलम में डालना चाहता हूं, लेकिन मुझे लगता है कि डोक्सिजन आउटपुट में विवरणों की कमी है, और पिछले कुछ दिनों से http://pqxx.org/ नीचे आ गया है।C++ libpqxx API का उपयोग कर PostgreSQL BYTEA कॉलम में बाइनरी डेटा कैसे सम्मिलित करें?

मैं BYTEA कॉलम के साथ किसी तालिका में somefile.bin की सामग्री डालने के बारे में कैसे जाउंगा?

क्या मैं इन पंक्तियों के साथ है:

pqxx::work work(conn); 
work.exec("CREATE TABLE test (name varchar(20), data BYTEA)"); 
work.exec("INSERT INTO test(name, data) VALUES ('foo', <insert filename.bin here>)"); 
work.commit(); 

यदि यह एक फर्क नहीं पड़ता, मैं PostgreSQL 9.1 में उपलब्ध BYTEA के लिए नए hex स्वरूप का उपयोग करना चाहते हैं।

उत्तर

9

यह पता लगाया। यहाँ एक तालिका में द्विआधारी वस्तुओं का एक समूह को सम्मिलित करने के लिए कैसे दिखा एक उदाहरण है:

pqxx::connection conn(...); 
conn.prepare("test", "INSERT INTO mytable(name, binfile) VALUES ($1, $2)"); 
pqxx::work work(conn); 
for (...) 
{ 
    std::string name = "foo"; 
    void * bin_data = ...; // obviously do what you need to get the binary data... 
    size_t bin_size = 123; // ...and the size of the binary data 

    pqxx::binarystring blob(bin_data, bin_size); 
    pqxx::result r = work.prepared("test")(name)(blob).exec(); 
} 
work.commit(); 

यहाँ बाइनरी डेटा डेटाबेस से बाहर वापस पाने के लिए कैसे:

pqxx::result result = work.exec("SELECT * FROM mytable"); 
for (const auto &row : result) 
{ 
    pqxx::binarystring blob(row["binfile"]); 
    void * ptr = blob.data(); 
    size_t len = blob.size(); 
    ... 
} 
+0

मैं अपने समाधान चाहते के साथ परीक्षण किया गया था, लेकिन मैं conn.prepare का उपयोग कर पसंद नहीं है। यह मुझे सीमित करता है जब मेरे पास एक प्रश्न (प्रदर्शन समस्या) के साथ सम्मिलित करने के लिए 'n' तत्व होता है। मैं एक समाधान पर काम कर रहा हूं (pqxx 5.0.1 के साथ)। – LAL

1

वहाँ pqxx नहीं है: सम्मिलन में bynarystring। मैं निम्नलिखित समाधान का इस्तेमाल किया है कि ऐसा करने के लिए:

=== डेटाबेस ==== में एक wxImage भंडारण

//Getting image string data 
wxImage foto = (...); 
wxMemoryOutputStream stream; 
foto.SaveFile(stream,wxBITMAP_TYPE_PNG); 
wxStreamBuffer* streamBuffer = stream.GetOutputStreamBuffer(); 
size_t tamanho = streamBuffer->GetBufferSize(); 
char* fotoData = reinterpret_cast<char*>(streamBuffer->GetBufferStart()); 
string dados(fotoData, tamanho); 

//Performing the query 
conn->prepare("InsertBinaryData", "INSERT INTO table1(bytea_field) VALUES (decode(encode($1,'HEX'),'HEX'))") ("bytea",pqxx::prepare::treat_binary); 

pqxx::work w = (...); 
w.prepared(dados).exec(); 



=== डेटाबेस से एक wxImage पुन: प्राप्त करने === =

pqxx::result r = w.exec("SELECT bytea_field FROM table1 WHERE (...)"); 
w.commit(); 

const result::tuple row = r[0]; 
const result::field tfoto = row[0]; 

pqxx::binarystring bs(tfoto); 
const char* dadosImg = bs.get(); 
size_t size = bs.length(); 

wxMemoryInputStream stream(dadosImg,size); 
wxImage imagem; 

imagem.LoadFile(stream); 

मुझे आशा है कि यह मददगार हो।

0
इसके बजाय स्टीफन के जवाब के रूप में conn.prepare साथ तैयार एसक्यूएल कथन का उपयोग करता है, तो आप आप बस pqxx::escape_binary समारोह के भार के से एक के साथ बाइनरी डेटा बच सकते हैं चाहता हूँ की

Here दस्तावेज़ीकरण है।

0

चूंकि यह प्रश्न libpqxx के माध्यम से BYTEA डालने के लिए शीर्ष खोज परिणाम है, इसलिए पैरामीटरयुक्त क्वेरी का उपयोग करके इसे करने का एक और तरीका है, जो एक एकल डालने पर अधिक उपयुक्त है।

// Assuming pre-existing pqxx::connection c, void * bin_data, size_t bin_size... 
pqxx::work txn(c); 
pqxx::result res = txn.parameterized("INSERT INTO mytable(name, binfile) VALUES ($1, $2)") 
            (name) 
            (pqxx::binarystring(bin_data, bin_size)) 
            .exec(); 
txn.commit(); 

ध्यान दें कि मानकों नहींquote या esc तरीकों के साथ भाग जाना चाहिए।

भी ध्यान रखें कि pqxx::connection::prepare का उपयोग कर के स्वीकार किए जाते हैं जवाब तैयार क्वेरी कनेक्शन के पूरे जीवनकाल के लिए मौजूद हैं का कारण बनता है। यदि कनेक्शन लंबे समय तक चलने वाला होगा और तैयार क्वेरी की आवश्यकता नहीं है, तो इसे शायद pqxx::connection::unprepare पर कॉल करके हटा दिया जाना चाहिए।

0

मैं std::string के अंदर बाइनरी डेटा का उपयोग करके एक लचीला समाधान के साथ आया हूं।

मैं इस नए समाधान का प्रस्ताव करता हूं क्योंकि वर्तमान उत्तर पुराने हैं (2013) और मैं pqxx 5.0.1 का उपयोग कर एक बहु सम्मिलित क्वेरी की तलाश में था।

समाधान के साथ आपको एक एकल डालने क्वेरी में एकाधिक बाइनरी डेटा जोड़ने के लिए for loop का उपयोग करने में लचीलापन है।

CustomStruct data = .... ; // have some binary data 

// initialise connection and declare worker 
pqxx::connection conn = new pqxx::connection(...);  
pqxx::work w(conn); 

// prepare query 
string query += "INSERT INTO table (bytea_field) VALUES (" 
// convert your data in a binary string. 
pqxx::binarystring blob((void *)&(data), data.size()); 
// avoid null character to bug your query string. 
query += "'"+w.esc_raw(blob.str())+"');"; 

//execute query 
pqxx::result rows = w.exec(query); 

हम डेटाबेस से डेटा पुनः प्राप्त करने के आप अपने डेटा-प्रकार (CustomStruct उदाहरण के लिए) की गुंजाइश होनी चाहिए और आप अपनी पसंद के द्विपदीय प्रारूप में इसे वापस कास्ट करने के लिए सक्षम होना चाहिए चाहते हैं।

// assuming worker and connection are declared and initialized. 
string query = "SELECT bytea_field FROM table;"; 
pqxx::result rows = w.exec(query); 
for(pqxx::result::iterator col = rows.begin(); col != rows.end(); ++col) 
{ 
    pqxx::binarystring blob(col[0]); 
    CustomStruct *data = (CustomStruct*) blob.data(); 
    ... 
} 

यह pqxx 5.0.1, c++11 और postgresSQL 9.5.8

संबंधित मुद्दे