2014-09-27 61 views
1

示例代碼:爲什麼我不能按名稱訪問列?

pqxx::connection c("user=postgres"); 
pqxx::work txn(c); 
pqxx::result r = txn.exec("SELECT d.datname as \"Name\"," 
     "pg_catalog.pg_get_userbyid(d.datdba) as \"Owner\"," 
     "pg_catalog.pg_encoding_to_char(d.encoding) as \"Encoding\"," 
     "d.datcollate as \"Collate\"," 
     "d.datctype as \"Ctype\"," 
     "pg_catalog.array_to_string(d.datacl, E'\\n') AS \"Access privileges\"" 
     " FROM pg_catalog.pg_database d" 
     " ORDER BY 1"); 
try { 
    for(int rownum=0; rownum<r.size(); ++rownum) { 
    const pqxx::result::tuple row = r[rownum]; 
    std::cout << "Column 0 Name: \'" << row[0].name() << "\': " << row[0].c_str() << std::endl; 
    const std::string s = "Name"; 
    std::cout << (row[0].name() == s) << std::endl; 
    std::cout << "dbname: \'" << row[s].c_str() << "\'" << std::endl; // Exception here 
    } 
} catch(const pqxx::argument_error &e) { 
    std::cout << "Argument Error: " << e.what() << std::endl; 
} 

我的輸出如下

Column 0 Name: 'Name': mydb 
1 
Argument Error: Unknown column name: 'Name' 

第一列名爲「姓名」和對字符串測試行命名爲「名」產生真實的陳述。但是,當我通過該字符串訪問它時,我得到一個異常。

回答

4

好吧,完全是asinine。如果你想讓大寫字母等工作,你必須引用這個名字。

因此改變

const std::string s = "Name"; 

const std::string s = "\"Name\""; 

解決了這個問題。很顯然,C接口降低了你所稱的範圍,但不會小寫它所測試的字段。 ARG!我不得不通過libpqxx代碼來弄清楚。

+1

這與libpq無關。這是SQL中標識符的標準規則:http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS – 2014-09-27 10:11:05

+1

@a_horse_with_no_name對於評估的SQL語句中的SQL標識符,但客戶端界面可以自由定義他們自己的案例處理。在處理諸如結果集列名稱之類的東西時,在許多方面,區分大小寫和保留大小寫可能更有意義。我個人認爲'libpqxx'在這裏的行爲是無益的。 – 2014-09-27 12:43:15

+0

我的觀點是,#1界面不應該做任何事情,所以名稱和名稱不匹配,但名稱和名稱匹配,名稱和名稱匹配,或#2,它應該小寫字段名稱以及在測試之前,讓Name = name,name = Name,name = name,Name = Name。名稱和名稱永遠不會匹配的事實非常令人困惑。可以進入PQfnumber()函數的唯一的事情是一個字段名稱,所以它應該按照原樣處理,或者對所有內容進行全面摺疊。 – Rahly 2014-09-27 20:55:28