QSqlQuery将QByteArray作为字符串插入PostgreSQL

时间:2016-02-03 10:50:18

标签: c++ postgresql qt qsqlquery qbytearray

我有一个PostgreSQL 9.4.5表,其中包含一个基本字符数据类型的列,即如下所示:

CREATE TABLE films (
    code        char(5) CONSTRAINT firstkey PRIMARY KEY,
    title       varchar(40) NOT NULL);

然后我使用QSqlQuery插入数据,使用绑定的QByteArray:

QSqlQuery query;
query.prepare("INSERT INTO films VALUES (1, ?)");
const QByteArray film("Avatar");
query.addBindValue(film);
query.exec();

在Ubuntu 15.10上,电影名称以字节形式进入表格:

\x417661746172

在Windows上,它以字符形式显示。

没有显式地将QByteArray强制转换为QString,有没有办法告诉QSqlQuery或PostgreSQL将数据视为字符串,所以它可以像在Windows上一样在Ubuntu上运行吗?

3 个答案:

答案 0 :(得分:0)

尝试使用bindValue代替addBindValue。请参阅此link

答案 1 :(得分:0)

QByteArray没有关于它包含的字符串编码的信息(甚至它包含的字节序列可以解释为编码字符串)。

如果它恰好包含UTF-8编码的字符串,您可能

  • 将其绑定为包含QString::fromUtf8(film.constData())的字符串,而不仅仅是film

  • 让Qt驱动程序将其作为bytea传递,但让PostgreSQL通过INSERT查询将其转换为文本:

    query.prepare("INSERT INTO films VALUES (1, convert_from(?,'UTF-8')))");
    

这也适用于其他编码,上面的UTF-8就是一个例子。

关于Windows / Ubuntu之间的区别:目前还不清楚为什么QtSql的行为会有所不同,但也许这与postgres配置有所区别。

'\x417661746172'是UTF-8中Avatar的文本表示形式,作为二进制字符串,但仅当bytea_output设置为hex时才显示。如果bytea_output设置为escape,则该文件将完全Avatar,并且无法从文本本身中识别出来。

psql命令行客户端中的示例:

test=> set bytea_output=hex;
SET
test=> select 'Avatar'::bytea;
     bytea      
----------------
 \x417661746172
(1 row)

test=> set bytea_output=escape;
SET
test=> select 'Avatar'::bytea;
 bytea  
--------
 Avatar
(1 row)

bytea的转义也发生在QPSQL等驱动程序中的客户端,以及自PostgreSQL 9.0以来仅可用的hex风格。在此之前,escape是唯一的方法,bytea_output参数不存在。 我相信只需将QtSql与Windows机器上的9.0之前的libpq链接​​,就可以解释为什么你会在最近的Ubuntu上获得“类似文本”的外观与“类似十六进制”的外观。

答案 2 :(得分:0)

我在Windows上有相同的问题机智Qt 5.6,在debian上有PostgresSQL 9.6。 使用64位进行编译时,bytea将读取为二进制。 使用32位进行编译时,bytea将读取为十六进制。

CREATE TABLE image (
   id serial,
   name text,
   picture bytea
 );

sql_query.prepare("SELECT id, name, picture FROM image");
...
QByteArray name = sql_query.value("name").toByteArray();
QByteArray Picture = SQL_query.value("Picture").toByteArray();

varchar read with both (32-bit and 64-bit) into QByteArray as string.

//Output 64-Bit application:
name = "Test", Picture = "‰PNG\r\n\x1a\n\0\0..."
//Output 32-Bit application:
Name = "Test", Picture = "x89504e470d0a1a0a0000..."

我是在打开以下查询后添加的,现在可以使用

  QSqlQuery sql_query;
  sql_query.exec("SET bytea_output = 'escape'");

两个postgres驱动程序均来自pg 9.5,64位来自已安装的Postgres,32位是从zip文件中下载的。两者都具有相同的名称“ libpq.dll”