2013-04-16 65 views
7

いくつかのバイナリデータをBYTEAカラムに挿入したいのですが、Doxygenの出力には詳細が不足していて、最近数日は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を使用して好きではありません。 1つのクエリ(パフォーマンスの問題)で挿入する 'n'要素があるときは、私の制限です。私は解決策(pqxx 5.0.1)に取り組んでいます。 – LAL

1

pqxxはありません。 :挿入時にnarystring。私はそれを行うには、次のソリューションを使用:データベースにAN wxImageを格納

=== ==== DATABASE FROM AN 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(); 



=== === =

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

pqxx::escape_binary機能のバイナリデータを単純にエスケープすることができれば、ステファンの回答のようにconn.prepareのように準備されたSQL文を使用する代わりに、 Hereはドキュメントです。

0

この質問は、libpqxxを介してBYTEAを挿入するためのトップ検索結果であるため、パラメータ付きクエリを使用して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を使用して1つの挿入クエリで複数のバイナリデータを追加する柔軟性が得られます。

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.1c++11postgresSQL 9.5.8

関連する問題