mysqlpp: SQL syntax error when using template queries - mysql

I tried to use template queries to construct my sql query. Here's the sample code:
unsigned int version = 2;
try {
// key_version is INT UNSIGNED
mysqlpp::Query query = conn->query("SELECT * FROM agentlist WHERE key_version != %0q");
mysqlpp::StoreQueryResult res = query.store(version);
// string type param also caused the same problem
// mysqlpp::StoreQueryResult res = query.store(std::to_string(version));
} catch (const exception &ex) {
// deal with exceptions
}
And the code would go to catch part. ex.what():
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'2\' at line 1
I think it was caused by SQLQueryParms type, but the neither the tutorial nor the documentation had shown any methods to work around this.
BTW, how do I get parsed query string (with template params substituted)? I tried query.str(version) but it was same as query.str().

My bad. Forgot an important function call query.parse().
And it all works now.

Related

MySQL Syntax with FROM with a var

I got some problems with my MySQL Syntax.
This is my code:
Config.SocietyMoneyTable = 'addon_account_data'
local result = MySQL.Sync.fetchAll("SELECT money FROM #account_table WHERE account_name = #society", {
['#account_table'] = Config.SocietyMoneyTable,
['#society'] = society
})
Error:
[ERROR] [MySQL] [maze_management] An error happens on MySQL for query "SELECT money FROM
'addon_account_data' WHERE account_name = 'society_police'": ER_PARSE_ERROR: You have an
error in your SQL syntax; check the manual that corresponds to your MariaDB server version
for the right syntax to use near ''addon_account_data' WHERE account_name = 'society_police''
at line 1
The Syntax does work when I change the #account_table to the string which is in Config.SocietyMoneyTable. But I need this configed so this is no solution for me.
A query parameter annotated with the # sigil can only be used in place of a scalar value, not a table name or other identifier. You need to use string formatting to get your configurable table name into the query, not a query parameter.
Something like the following:
Config.SocietyMoneyTable = 'addon_account_data'
local queryString = string.format("SELECT money FROM `%s` WHERE account_name = #society",
Config.SocietyMoneyTable)
local result = MySQL.Sync.fetchAll(queryString, {
['#society'] = society
})
I have not tested this code, and I don't use Lua often, so if there are mistakes I will have to leave it to you to resolve them. But it should at least show the principle: identifiers (like table names) must be fixed in the query string, not added as query parameters.

I cannot make binding work with Diesel on MariaDB

I simply wanted to pass an argument to my sql query.
let query = sql("SELECT resa_comment FROM reservation WHERE resa_id = ? ");
let query2 = query.bind::<Integer, _>(1286);
let result : Result<std::vec::Vec<String>, _> = query2.load(&connection);
dbg!(result);
But the result is
[src/bin/show_posts.rs:36] result = Err(
DatabaseError(
__Unknown,
"You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near \'?\' at line 1"
)
)
The SQL query is correct because when I replace the "?" with a constant and remove the "bind", I get a correct result.
I know that I can map the table to a Rust structure but my goal is to pass complex requests with arguments so I was testing Rust and Diesel.
Is there something I missed ? Thanks.
The bind method does not replace question mark, it appends the value to the end of the query. So it should look like this:
let query = sql("SELECT resa_comment FROM reservation WHERE resa_id = ");
// ...
If you need to put value in the middle of the query, then you need to chain bind and sql calls, such as:
sql("SELECT resa_comment FROM reservation WHERE resa_id = ")
.bind::<Integer, _>(1286)
.sql(" AND something > ")
.bind::<Integer, _>(1);
But note that you should avoid writing raw sql if it is not necessary.

Unknown SQL syntax error for ScalikeJDBC with SQL interpolation

To avoid DRY, I'm attempting to create an sql INSERT statement with variable column names and the data to fill those columns via ScalikeJDBC's sql interpolation:
case class MySQLInsertMessage(tableName:String, columns:List[String], values:List[String])
def depositMessage(msg: MySQLInsertMessage): Unit = {
NamedDB('MySQLMsgDepositor) localTx { implicit session =>
val sqlStmt = sql"INSERT INTO ${msg.tableName} (${msg.columns}) VALUES (${msg.values})"
println("The sql statement is: " + sqlStmt.statement)
println("The parameters are: " + sqlStmt.parameters)
sqlStmt.update().apply()
}
}
And when I call this with:
depositMessage(MySQLInsertMessage("My_Table", List("key", "email"), List("42", "user#email.com")))
the resulting console printout is:
The sql statement is: INSERT INTO ? (?, ?) VALUES (?, ?)
The
parameters are: List(My_Table, key, email, 42, user#email.com)
You
have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near ''My_Table'
('key', 'email') VALUES ('42', 'user#emai' at line 1
java.sql.SQLSyntaxErrorException: You have an error in your SQL
syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near ''My_Table' ('key', 'email') VALUES
('42', 'user#emai' at line 1
I've tried wrapping the sql"..." as such instead:sql"""...""", but that doesn't seem to make a difference. I can execute the expected statement just fine in my MySQL workbench GUI. Any idea what my syntax error is?
Stemming from the hint from #scaisEdge, it seems ScalikeJDBC, when using its syntax, will always place single quotes around any parameterized values. And judging from here - https://github.com/scalikejdbc/scalikejdbc/issues/320 - this is a known issue.
With a MySQL INSERT statement (or others), your table name or column values may not have single quotes around them, though they are allowed to have backticks.
You can use their SQLSyntax.createUnsafely(str:String) method, or, if I wanted to do this as I was doing above, instead of using sql"...", I could use the old way of SQL(s"INSERT INTO ${msg.tableName} (${msg.columns.mkString(",")})")
Note - I believe both of these leave you open to injection attacks. Since, for me, this is a local API and you'd have to have the DB's username and password regardless to use it, I'm going with the createUnsafely way of doing things, with a little regex "cleaner" for a little inelegant piece of mind:
def depositMessage(msg: MySQLInsertMessage): Unit = {
NamedDB('MySQLMsgDepositor) localTx { implicit session =>
val unsafeSQLRegex = "[`'\"]".r
val table = SQLSyntax.createUnsafely(s"`${unsafeSQLRegex.replaceAllIn(msg.tableName, "")}`")
val columns = SQLSyntax.createUnsafely(msg.columns.map(value => unsafeSQLRegex.replaceAllIn(value, "")).mkString("`", "`, `", "`"))
val sqlStmt = sql"INSERT INTO $table ($columns) VALUES (${msg.values})".update().apply()
}
}
}

go convert empty interface to string

I'm using the mymysql package and I'm trying to create a function which gets an SQL query and some parameters (as variadic empty interface):
func FindByQuery(statement string, params ...interface{}) (diver *DiverT, err error) {
values := make([]interface{}, len(params))
for i := range params {
values[i] = params[i]
}
// Both statements result in the same error...
row, _, execError := Db.QueryFirst(statement,values...)
row, _, execError := Db.QueryFirst(statement,params...)
// Additional code...
}
When I call this method using some kind of SQL, I always get an SQL error. I do something like:
FindByQuery("SELECT * FROM Diver WHERE Name=?", "Markus")
Which results in the following error:
Received #1064 error from MySQL server: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?%!(EXTRA string=Markus)' at line 1"
What should I do that the parameter is converted correctly to a string (or whatever it is, if I have different parameter(s))?
Try using printf format syntax:
FindByQuery("SELECT * FROM Diver WHERE Name=%s", "Markus")

CakePHP 1.3 Plugin: Database Error

I am attempting to create a plugin for CakePHP 1.3, but I am having the following error that is frustrating me:
1064: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the
right syntax to use near 'process' at line 1
I have tried multiple things but have not come up with a solution;
Basically I call the following from my app_controller.php file:
var $uses = array('Visitor.Visitors');
function beforeRender(){
$this->Visitors->process($this->here);
}
And then I have the following in my visitor.php model file in my plugin
class Visitor extends VisitorsAppModel {
var $name = 'Visitor';
function process($url = null){
$this->deleteInactive();
if($this->_isBot() == FALSE){
$this->_updateVisitor($url);
}
}
}
The strange thing is that even if I comment out the above function I still get the same MySQL error 1064.
Help!
Try changing 'Visitors' in $this->Visitors->process($this->here); to 'Visitor' (singular).
It seems also that you have swapped 'Visitors' and 'Visitor' in the $uses array of your app_controller.php file:
var $uses = array('Visitor.Visitors');
should be
var $uses = array('Visitors.Visitor');