C++DB is the database layer that was designed to work with C++CMS. This customized version is used within Ye Ol' Pi Shack.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

147 lines
5.1 KiB

  1. /*! \page query Fetching Query Results
  2. First read about \ref stat "how to prepare" statements
  3. \section query_fetch Fetching a Results
  4. The result is represented by cppdb::result class. It stores the query result. The prepared statement result can be fetched
  5. using \ref cppdb::statement::query() "statement::query()" function.
  6. \code
  7. cppdb::statement st = sql << "SELECT name,age FROM students";
  8. cppdb::result r = st.query();
  9. \endcode
  10. \note \ref cppdb::statement "statement" can be converted to \ref cppdb::result "result" automatically that actually causes calling \ref cppdb::statement::query() "query()" function.
  11. So the same code above can be written using syntactic sugar as following:
  12. \code
  13. cppdb::result r = sql << "SELECT name,age FROM students";
  14. \endcode
  15. \section query_meta Fetching Meta-data on the Result:
  16. Following meta-data can be fetched about the result:
  17. - Number of columns using \ref cppdb::result::cols() "cols()" member function.
  18. - The name of columns using \ref cppdb::result::name() "name()" member function. These names can be used
  19. for retrieval of the data using \ref cppdb::result "fetch()" member functions.
  20. \section query_iter Getting the Result Data
  21. In order to iterate over rows of the result you should use \ref cppdb::result::next() "next()" function that
  22. returns true if the next row exits and false otherwise. Once \ref cppdb::result::next() "next()" returned true
  23. you can fetch the values using \ref cppdb::result "fetch()" family of functions.
  24. There are 3 kinds of prototypes for \c fetch() functions.
  25. -# <tt>bool fetch(int column,type &value)</tt> - fetch the value from column (index starts from 0) returning false if the value in NULL.
  26. -# <tt>bool fetch(std::string const &column_name,type &value)</tt> - fetch the value from column using its name returning false if the value in NULL.
  27. -# <tt>bool fetch(type &value)</tt> - fetch the value from the next column in current row (starting from 0) returning false if the value in NULL.
  28. Where type is one of C++ numeric types, \c std::string for text, \c std::tm for date-time types and \c std::ostream for Blob types. Fetching
  29. a value would try to do the best in casting between result type and the type you provide, for example fetching numeric or date-time types
  30. would convert them to string representation, it would try to do the casting between string and std::tm and numeric types if possible.
  31. If conversion fails, cppdb::bad_value_cast is thrown.
  32. For example:
  33. \code
  34. cppdb::result r = sql << "SELECT name,age FROM users WHERE age > ?" << 18.0;
  35. while(r.next()) {
  36. std::string name;
  37. double age;
  38. r.fetch(0,name);
  39. r.fetch(1,age);
  40. std::cout << name << " is " << age << " years old" << std::endl;
  41. }
  42. \endcode
  43. Another way to get values directly is by using cppdb::result::get(int) or cppdb::result::get(std::string const &) template member functions
  44. that allow to fetch values from columns directly using column index or column name:
  45. \code
  46. cppdb::result r = sql << "SELECT name,age FROM users WHERE age > ?" << 18.0;
  47. while(r.next()) {
  48. std::cout << r.get<std::string>("name") << " is " << r.get<double>("age") << " years old" << std::endl;
  49. }
  50. \endcode
  51. Unlike \c fetch() function, \c get() functions throw cppdb::null_value_fetch if the value was null.
  52. \section query_syntacx Syntactic Sugar
  53. There is also overloaded operator ">>" that provide syntactic sugar for fetching data and the example above an be written as:
  54. \code
  55. cppdb::result r = sql << "SELECT name,age FROM users WHERE age > ?" << 18.0;
  56. while(r.next()) {
  57. std::string name;
  58. double age;
  59. r >> name >> age;
  60. std::cout << name << " is " << age << " years old" << std::endl;
  61. }
  62. \endcode
  63. \note Operators \c >> function remain variable unchanged when the result is NULL value.
  64. In order to fetch both meta-data and the value you can use \ref cppdb::into "into()" manipulator
  65. that passes both reference to the value and a tag. For example
  66. \code
  67. cppdb::null_tag_type age_tag,name_tag;
  68. std::string name;
  69. double age;
  70. r >> cppdb::into(name,name_tag) >> cppdb::into(age,age_tag);
  71. \endcode
  72. \section query_row Fetching a Single Row
  73. Sometimes it is useful to fetch a single row of data and not iterate over it. This can be done using cppdb::statement::row()
  74. function that works like \ref cppdb::statement::query() "query()" but also calls \ref cppdb::result::next() "next()" first time
  75. and checks if more then one rows had been fetched (in which case it throws \ref cppdb::multiple_rows_query "multiple_rows_query" exception).
  76. For example:
  77. \code
  78. cppdb::statement st = sql<<"SELECT password WHERE username=?" << user
  79. cppdb::result r = st.row();
  80. if(!r.empty()) {
  81. if(pass == r.get<std::string>(0)) {
  82. // ok
  83. }
  84. else {
  85. // wrong password
  86. }
  87. }
  88. else {
  89. // no such user
  90. }
  91. \endcode
  92. You can also use cppdb::row manipulator to make it shorter:
  93. \code
  94. cppdb::result r = sql<<"SELECT password WHERE username=?" << user << cppdb::row
  95. if(!r.empty())
  96. ...
  97. else
  98. ...
  99. \endcode
  100. You can also use operator \c >> right after \ref cppdb::row "row" manipulator, but in case
  101. the empty result was fetched a \ref cppdb::empty_row_access "empty_row_access" exception would be thrown.
  102. \code
  103. double age;
  104. sql<<"SELECT age WHERE username=?" << user << cppdb::row >> age;
  105. \endcode
  106. */