Các thư viện sql hiện nay đa số đều hoạt động theo kiểu nhận một chuỗi và thực hiện.
VD:
C++ Code:
  1. int i = 300, a= 10, b = 1;
  2. mysql_query (mysql, std::string("SELECT * FROM Tb1 WHERE Field1 > ") + i + ";");
  3. mysql_query (mysql, std::string("INSERT INTO Tb1 VALUES (") + i + ", " + j + ");");

Dễ thấy, nhược điểm của phương pháp trên là:
- Không kiểm tra được tính hợp lệ (cú pháp, ngữ nghĩa) của câu truy vấn một cách trực tiếp, mà phải thông qua debug,
- Cú pháp xây dựng câu truy vấn phức tạp (thao tác chuỗi trong C++ chưa bao giờ là đơn giản).

Vậy nên mình có ý tưởng về một thư viện static sql cho C++, tương tự như thư viện Boost.Xpressive (thư viện Regex cho phép xây dựng các biểu thức regex trong thời gian biên dịch).
Cú pháp của nó sẽ có kiểu như sau:
C++ Code:
  1. i = 300, a = 10, b = 1;
  2.  
  3. table tb1 ("Tb1");
  4. field<int> fd1 ("Field1", tb1);
  5.  
  6. query query1 = select >> fd1 >> from >> tb1 >> where >> (fd1 > i);
  7. query query2 = insert >> into >> tb1 >> values >> (_1, _2); // _1, _2 là các placeholder
  8.  
  9. query1(); // thực hiện query1
  10. query2(a, b); // thực hiện query2

Ở đây, các query sẽ là các function object. Được xây dựng bằng kỹ thuật template-expression: select thực chất là một đối tượng thuộc một kiểu (VD select_t), from là đối tượng kiểu from_t, ...

Thông qua operator overloading, đối tượng query sẽ được xây dựng dần dần qua các đối tượng trung gian.
VD:
Code:
select: kiểu select_t
select >> fd1: kiể select_field_t
select >> fd1 >> from: kiểu select_field_from_t
...
C++ Code:
  1. table tb1 ("Tb1");
  2. field<int> fd1 ("Field1", tb1);
  3.  
  4. query1 = select >> fd1 >> from >> tb1 >> where >> (fd1 > "abc"); // lỗi biên dịch vì int không so sánh được với char*
  5. query2 = insert >> tb1 >> values >> (_1, _2); // lỗi biên dịch vì không có operator>>(insert_t, table) mà chỉ có operator>>(insert_t, into_t)
  6. ...

Tóm lại, ưu điểm của phương pháp này là:
- Compile-time checking: sử dụng trình biên dịch C++ để kiểm tra tính hợp lệ của câu lệnh SQL
- Sử dụng cú pháp C++, và khá gần với cú pháp SQL
- Không phải đụng đến các thao tác chuỗi.
- (có thể) tối ưu hoá câu truy vấn ngay lúc biên dịch

Ý tưởng là vậy, còn cách thực hiện thì có ai có ý kiến gì không ?
Nên sử dụng Boost.Proto hay Boost.Phoenix xây dựng từ đầu ?