2016-02-03 73 views
1

我有一個PostgreSQL 9.4.5表與基本字符數據類型的列,即,像這樣創建的:QSqlQuery插入的QByteArray作爲字符串插入的PostgreSQL

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將數據視爲一個字符串,所以它可以在Ubuntu上像在Windows上一樣工作?

+0

基本問題 - 是否有任何理由使用'QByteArray'而不是'QString'?在引用的代碼中,我看不到任何內容。 – klin

回答

0

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'是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參數不存在。 我相信只要在Windows計算機上使用QtSql鏈接到比9.0更早的libpq,就可以解釋爲什麼你在近期的Ubuntu上看到'類文字'的外觀和'十六點'的外觀。

+0

'convert_from'有助於瞭解,謝謝。有趣的是,在Windows上,'QtSql'層自動進行字節轉換(大概爲'UTF-8'),而在Ubuntu上它必須明確地完成。 – Lozzer

+0

@Lozzer:我在答案中加入了一個可能的解釋。我相信它不是真正的Windows vs Ubuntu,而是版本/配置的差異。 –

0

嘗試使用bindValue而不是addBindValue。請參閱此link

+0

恐怕同樣的結果。 – Lozzer