QSqlQuery将QByteArray作为字符串插入PostgreSQL



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

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(中,并且hex风格仅在PostgreSQL 9.0之后可用。在此之前,escape是唯一的方法,bytea_output参数不存在。我相信,简单地将QtSql与Windows机器上早于9.0的libpq链接可能会解释为什么在最近的Ubuntu上你会得到"类似文本"的外观而不是"类似十六进制"的外观。

尝试使用 bindValue 而不是 addBindValue 。请参阅此链接。

我在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 = "‰PNGrnx1an..."
//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">

相关内容

  • 没有找到相关文章

最新更新