2010-03-22 72 views
2

我想創建一個包含文件路徑的記錄。使用NpqSQL驅動程序將插入完成到啓用UTF8的Postgres數據庫中。NpgSQL插入文件路徑包含反斜槓「\」

我的表定義:

CREATE TABLE images 
(
    id serial, 
    file_location character varying NOT NULL 
) 

我的SQL語句,包括執行它的代碼(歸結到最低限度):

string sqlStatement = "INSERT INTO images (file_location) VALUES ('\\2010')"; 

NpgsqlConnection dbConnection = new NpgsqlConnection(connectionString); 
dbConnection.Open(); 
NpgsqlCommand dbCommand = new NpgsqlCommand(sqlStatement , dbConnection); 
int result = dbCommand.ExecuteNonQuery(); 
dbConnection.Close();  

當使用pgAdmin的插入上述說法,它工作正常。通過Visual Studio的C#使用 Npgsql的驅動程序,它失敗與此異常:

"ERROR: 22021: invalid byte sequence for encoding \"UTF8\": 0x81" 

由於米倫準確地解釋說,Postgres的解釋語句作爲一個octal號(\ O201 == 0×81)。

由於米倫也描述,E面前的道路並沒有幫助。

所以快速回顧一下:爲什麼NpqSQL會停止插入\\2010

+0

你讀過「4.1.2.1字符串常量」和「4.1.2.2與C風格的逃逸字符串常量。」從手冊(http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS)? – 2010-03-22 18:32:54

+0

@Milen:「反斜槓後面的任何其他字符都是字面意義的,因此,要包含反斜槓字符,請寫兩個反斜槓(\\\)。」我的邏輯告訴我,'\\'是在八進制字節值'\ 2 ...'之前考慮的? – Chau 2010-03-23 15:05:19

+2

你還沒有展示真實的代碼,所以我想你的解釋器/編譯器將雙反斜線解釋爲一個轉義反斜線,然後Postgres只看到一個反斜槓後面跟着一些數字。它被解釋爲八進制數(o201,x81)。 – 2010-03-23 15:32:12

回答

1

Milen值得讚揚,因爲我將答案引向了答案 - 謝謝!

顯然NpgSQL在將我的SQL語句插入到Postgres之前執行一次轉義迭代。因此,要解決我的問題,我代替我的反斜槓的所有occurances以兩個反斜槓來代替:

string path = ... my path ... 
path = path.Replace("\\", "\\\\"); 
sqlStatement = "INSERT INTO images (file_location) VALUES ('" + path + "')"; 
+0

C#對正常字符串中的轉義序列使用反斜槓(http://msdn.microsoft.com/zh-cn/library/362314fe.aspx)。因此,要在字符串中包含單個反斜槓,您需要兩個反斜槓。但是存在「逐字字符串文字」,前綴爲@,在這種情況下可能會有所幫助(@「c:\ Docs \ Source \ a.txt」與「c:\\ Docs \\ Source \\ a.txt 「)。 – 2010-03-25 15:04:03

+0

@Milen:是的,@通常非常有用,但是當字符串傳遞給NpgSQL時,反斜槓被刪除:( – Chau 2010-04-13 09:33:11

3

(已實現我的意見看起來像一個答案,以便它們轉換相應。)

您還沒有表現出真正的代碼,所以我想你的解釋器/編譯器解釋的雙反斜線作爲轉義反斜線,然後的Postgres只看到一個反斜槓後跟一些數字。它被解釋爲八進制字節值(八進制201 =十六進制81)。

關於「escape」字符串常量(以「E」開頭的字符串) - 在你的情況下,它們是完全不必要的。在標準的SQL反斜槓中沒有特別的意義。

有關詳細信息,請參閱手冊(http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS)中的「4.1.2.1。字符串常量」和「4.1.2.2。帶C風格轉義的字符串常量」。

+0

@Milen:謝謝你的努力。我編輯了我的原始文章幷包含了代碼。我仍然無法理解,但'\\'轉換爲'\'。 – Chau 2010-03-25 13:18:41