我想将一些二进制数据插入到BYTEA列中,但我发现Doxygen输出缺少详细信息,http://pqxx.org/在过去几天内已经停止。
我如何将somefile.bin的内容插入带有BYTEA列的表中?
我所拥有的是:
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
格式。
答案 0 :(得分:10)
想出来。下面是一个示例,说明如何将一堆二进制对象插入表中:
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();
...
}
答案 1 :(得分: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);
我希望它有所帮助。
答案 2 :(得分:0)
如果你想要的话,不要像在Stéphane的答案中那样使用带有conn.prepare
的准备好的SQL语句,而只需使用pqxx::escape_binary
函数的一个重载来转义二进制数据。 Here是文档。
答案 3 :(得分: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
来删除它。
答案 4 :(得分: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