2014-09-27 3 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' 

Первое название столбцов «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 –

+1

@a_horse_with_no_name Это верно для идентификаторов SQL в оцененных выражениях SQL , но клиентские интерфейсы могут свободно определять собственную обработку сообщений. Во многих отношениях может возникнуть больше смысла учитывать регистр символов и сохранять их при работе с такими именами, как имена столбцов набора результатов. Лично я считаю, что поведение libpqxx здесь бесполезно. –

+0

Моя точка зрения заключается в том, что либо # 1 интерфейс не должен ничего с ней делать, поэтому имя и имя не совпадают, но имя и имя совпадают, а совпадение имени и имени или # 2 должно содержать строчные имена полей Перед тестированием, чтобы Name = name, name = Name, name = name, Name = Name. Тот факт, что имя и имя никогда не совпадают, довольно сбивает с толку. ТОЛЬКО вещь, которая может войти в функцию PQfnumber(), является ПОЛЕВОЙ ИМЯ, поэтому она должна обрабатывать все, что есть, или делать полный случай. – Rahly