SOCI / soci

Official repository of the SOCI - The C++ Database Access Library
http://soci.sourceforge.net/
Boost Software License 1.0
1.37k stars 472 forks source link

soci::rowset+postgresql backend +use expression #1046

Closed linoxoidunix closed 1 year ago

linoxoidunix commented 1 year ago

Why can't I use this syntax with postgresql backend? soci::rowset<"some class or structure"> results = sql.prepare << "SELECT * from games where user_name=:name", soci::use(name,user.getName()); postgresql complains about using use in this statement.

vadz commented 1 year ago

What's the exact error message, i.e. what do you mean by "complains"?

linoxoidunix commented 1 year ago

I don't know what name scheme or name DB table or nameColumn when i compile my program. I read this parametres from file in runtime. I use approx this syntax: class MyRow; class DBTableInfo { public: std::string nameScheme; std::string nameTable; std::string nameColumn; } DBTableInfo dbTbInfo; std::string someValue; soci::rowset < MyRow > results = sql.prepare << "SELECT * from \ ":nameScheme \ ". \ ":nameTable \ " where \ ":nameColumn \ "=:name", soci::use(nameScheme,dbTbInfo.nameScheme), soci::use(nameTable,dbTbInfo.nameTable), soci::use(nameColumn,dbTbInfo.nameColumn), soci::use(name,someValue). Postgresql don't resolve use \ " :nameScheme \ "or \ " :nameTable \ " or \ " :nameColumn \ " Right now, I can't provide the error code to the printscreen, since I don't have the opportunity to make my code publicly available right now. If the printscreen of the error or the help message that postgresql produces is so important to you, I can try to do it this week, but I can't promise it.

zann1x commented 1 year ago

When using the :<word> syntax, you're instructing SOCI to create a prepared statement. Each :<word> occurrence is replaced with a respective statement placeholder. But placeholders in prepared statements aren't meant to be used for column or table names as you are trying to do it in your example. You are limited by the database capabilities here.

What you should do instead is to concatenate the statement string during runtime and to only use the :<word> syntax for the column's value in your WHERE clause.

linoxoidunix commented 1 year ago

yeah. That's pretty much how I understood it. so I just generate a std::string runtimeString at runtime with stringstream and pass it to sql.prepare << runtimeString; without using the soci::use operator

vadz commented 1 year ago

Your original SQL query (SELECT * from games where user_name=:name) looked like it ought to work, but the one you gave into a later comment where you try to use a parameter for the table name definitely can't work, as already explained, so I'm closing this as invalid.