QSqlQuery 将 QByteArray 作为字符串插入 PostgreSQL
QSqlQuery inserting QByteArray as string into PostgreSQL
我有一个 PostgreSQL 9.4.5 table 有一个基本字符数据类型的列,即像这样创建的:
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,电影名称进入 table 作为字节:
\x417661746172
在 Windows 上,它作为字符输入。
在不显式地将 QByteArray 转换为 QString 的情况下,有什么方法可以告诉 QSqlQuery 或 PostgreSQL 将数据视为字符串,因此它可以像在 Windows 上一样在 Ubuntu 上工作?
尝试使用 bindValue
而不是 addBindValue
。参考这个 link.
A 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'
是 Avatar
在 UTF-8 中作为二进制字符串的文本表示,但仅当 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
,并且 hex
风格仅在 PostgreSQL 9.0 之后可用。在此之前,escape
是唯一的方法,bytea_output
参数不存在。
我相信简单地让 QtSql 与 Windows 机器上早于 9.0
的 libpq 链接可以解释为什么你得到 'text-like' 外观与最近 'hex-like' 外观59=].
我在 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[=10=][=10=]..."
//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"
我有一个 PostgreSQL 9.4.5 table 有一个基本字符数据类型的列,即像这样创建的:
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,电影名称进入 table 作为字节:
\x417661746172
在 Windows 上,它作为字符输入。
在不显式地将 QByteArray 转换为 QString 的情况下,有什么方法可以告诉 QSqlQuery 或 PostgreSQL 将数据视为字符串,因此它可以像在 Windows 上一样在 Ubuntu 上工作?
尝试使用 bindValue
而不是 addBindValue
。参考这个 link.
A 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'
是 Avatar
在 UTF-8 中作为二进制字符串的文本表示,但仅当 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
,并且 hex
风格仅在 PostgreSQL 9.0 之后可用。在此之前,escape
是唯一的方法,bytea_output
参数不存在。
我相信简单地让 QtSql 与 Windows 机器上早于 9.0
的 libpq 链接可以解释为什么你得到 'text-like' 外观与最近 'hex-like' 外观59=].
我在 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[=10=][=10=]..."
//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"