2014-05-10 130 views
3

我是一名前數字設備公司工程師(與Rdb/RTR/VMS一起在很多非常大的系統上工作,並且在C年擁有10年的分佈式系統處理經驗......但很久以前)。libpq調用提供「UTF8」:0xe6 0x62 0x40

我在尋找關於這個錯誤在實踐中意味着什麼的建議,因爲我會去診斷問題。這裏是Postgres的錯誤消息

ERROR: invalid byte sequence for encoding "UTF8": 0xe6 0x62 0x40

環境MAC Maveriks XOS,GNU C時,Xcode,Postgres的9.3。 (服務器端)使用libpq

我是Postgres的新手,但寫了C查詢集,以將有關用戶表,列,數據類型,長度,序數位置的所有元數據從Postgres中提取出來,並將它們保存在內存中我自己的目錄並動態生成所有簡單的用戶表查詢。

該查詢使其通過查詢準備調用。

寫作防守我檢查了兩次錯誤:

if ((res = PQprepare(db, statement_name, insert_query, data->nParam, NULL)) == NULL) 
    Dbms_Crash(db, NULL, "Dbms_insert() PQprepare returned NULL"); 

if (PQresultStatus(res) != PGRES_COMMAND_OK) 
    Dbms_Crash(db, res, "Dbms_insert() Failed"); 

PQclear(res); 

這是我提出的疑問

insert_query: 
INSERT INTO image_metadata (latitude,longitude,altitude,filename,utc_datetime) 
VALUES ($1::double precision,$2::double precision,$3::double precision,$4::character varying,$5::timestamp without time zone); 

這裏我解析器轉儲失敗呼叫:

res = PQexecPrepared(db, 
         statement_name, 
         data->nParam, 
         (const char* const *)data->ptParam[i], 
         data->pdlParam[i], 
         data->pParamfmt, 
         PGFORMAT_STRING); 

ERROR: invalid byte sequence for encoding "UTF8": 0xe6 0x62 0x40

我過去在utc_datetime日期格式Postgres需要YYYY-MM-DD HH:MM:SS用於OSI協調世界時日期的問題,我餵養它YYYY:MM:DD這一個錯誤成爲下一個。 (所以我的數組間接,索引等工作作爲Postgres打印違規日期,第五個參數)

我寫了明顯的參數傾卸器來看看我餵它,但我知道它得到了日期當我修正日期格式時錯誤消失。

UTF8消息是來自文件名字符串還是其中一個雙精度字段?
傳遞二進制是一個壞主意,只是傳遞字符串可能會導致更少的問題?

我的模式最終會說30個表,這種類型的服務器端內存對齊錯誤是非常令人擔憂的。我的目標是編寫零SQL代碼。

+0

你作爲_filename_參數傳遞了什麼字符串? – klin

+0

所以我成功地加載了15行UTF8錯誤是間歇性的。文件名是正確的,當我從PGAdmin看時,時間戳也是如此。雙精度是所有三個高度,經度和緯度的垃圾。所以我會看看那裏。[d] 列名[latitude]參數長度:8 列名[longitude]參數長度:8 列名[altitude]參數長度:8 列名[filename]參數長度:94 Columnname [utc_datetime]參數長度:19 – user3624412

+0

「data」的結構定義是什麼data-> ptParam []'應該是一個指向字符串指針的指針數組,這看起來很尷尬。也許省略'[i]'索引? – wildplasser

回答

2

在你的PQprepare()函數中,最後一個參數是NULL。 這意味着所有查詢參數都是文本格式。 如果你把它們中的一部分作爲二進制傳遞,你只發送了一個垃圾。 我的建議是在準備好的查詢中爲參數使用文本格式。

+0

謝謝,我會這樣做。 – user3624412

+0

修復完成,再次感謝。我在系統表中注意到Postgres中的SQLCA和SQLDA結構,但它們沒有被libpq接口公開。如果存在對此的訪問層,則可以強制內存對齊,並將C結構模板放在連續的內存塊上,並解決數據定義和映射中的許多問題。同時將gizzions的內存分配從一個或兩個調用中切斷。我以前使用過這種技術,可以生成數百個表格的數據訪問層的70%,並且沒有阻抗不匹配。我想我可以看看Postgres的源代碼。 – user3624412

+1

請做。如果您在特定領域找到改進空間並且可以提供詳細建議*請*讓pgsql-hacker知道。修補程序甚至更好,但在提出討論之前不要花費大量時間在修補程序上;有時候事情並沒有因爲某種原因而以特定的方式完成。另外,我建議你檢查一下'libpqtypes'(我想把它放在'libpq'中),它可以讓事情變得更簡單。 –