我有一个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上运行吗?
答案 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”