I am new to node.js I don't know whether this is a correct way to write prepared statements in node.js I am using this package https://github.com/mysqljs/mysql I know there are lots of question in stackoverflow covering this but no one suggested this way my colleague suggesting me to do this now I am doubting him..
let query = "INSERT INTO ??(??, ??, ??, ??) VALUES (?, ?, ?, ?)";
let inserts = [`user_active`, `UID`, `rep`, `point`, `status`, `${UID}`, rep, `${point}`, status];
query = mysql.format(query, inserts);
console.log(query) //Spits out the query
You can use ES6 templet string to form the query.
You are already using ES6 templet string in insert statement you can use that to form entire string
let query = ‘INSERT INTO user_active(UID, rep, point, status) VALUES(${UID}, ${rep}, ${point}, ${status})’;
Not able to get perfect syntax for ES6 templet string as I am answering from mobile, google proper syntax for ES6 templet string. Only thing wrong in my syntax is opening and closing quotes for string.
Related
I'm using Nodejs and Express for my project. Which way do you think is better to store data. I'm using two methods to store data but I'm not sure which one is better and secure.
First Method:
var insertQuery = "INSERT INTO mytable (value1,value2) values (?, ?)";
con.query(insertQuery, [value1,value2],(err, rows) => { //Some Code here })
but I heard that I must use SQL variables to prevent from SQL injection and actually I'm not sure is it right or not?
Second Method:
var values = " #v1 :='"+value1"' , #v2 :='"+value2"'";
var insertQuery = "INSERT INTO mytable (value1,value2) values (" + values +")";
con.query(insertQuery, (err,rows)=>{ //Some Code here })
So what do you think?
For your question - first approach is better because it uses prepared statement, which means that at least your input will be escaped, but there are a lot of cases you need to prevent, some of it:
Validate user input
Properly encode all symbols, it's the thing why injection is possible
If you don't want to use any ORM's I advice you to use knex , which can work either as sql builder/builder + runner/ builder+runner+mapper. If you are really interested how to build own sql builder, you can read source code of it.
I am looking for a way to drop values from a list into a prepared SQL string which has question marks as placeholders. I have used this before in PyQT, but there I use the bindValue function. Using pymysql there looks to be no such function.
Here's an example of the type of SQL string I have prepared:
INSERT INTO my_table (`Column1Name`, `Column2Name`, `Column3Name`) VALUES (?,?,?);
I then have a list of values I am looking to insert into (or link to) the question mark placeholders.
my_values_list['string_1', '3', 'anothervalue']
Like I say, I have used this method before in PyQT, so I know this '?' placeholder method works, but without the bindValue function I can't see how to get it to work using pymysql.
Here's how I got it to work using PyQT's QSqlQuery bindValues function if it helps, where query.exec_() executes the SQL string:
if my_values_list:
[self.query.bindValue(i, my_values_list[i]) for i in range(len(my_values_list))]
self.query.exec_()
Here is an example of how to do this with PyMySQL:
query = 'INSERT INTO my_table (Column1Name, Column2Name, Column3Name) VALUES (%s, %s, %s);'
cur.execute(query, ('string_1', '3', 'anothervalue', ))
? is not a valid placeholder here, but %s is valid.
Maybe this post helps you, it's old but it's still mostly valid AFAIU, and I found it gave me a great overview:
What does a question mark represent in SQL queries?
I want to write the values of structure members into a MySQL table. The problem I have is that I wish to read the values of the structure and write the value to the specific column.
string assetNumber = EGMSimulatorObj.EGMConfigurationObj.AssetNumber.ToString();
string query = "INSERT INTO egmtable (Asset_Number) VALUES($assetNumber)";
With the above, I get the following error:
Unknown column '$assetNumber' in 'field list'.
How can I use set VALUES from the structure members or from any local variable?
You need to replace
string query = "INSERT INTO egmtable (Asset_Number) VALUES($assetNumber)";
with something like
string query = "INSERT INTO egmtable (Asset_Number) VALUES("+assetNumber+")";
That is, if you are using Java as programming language. Other languages may require other concatenation notation.
Side note: you should maybe use prepared statements for this, for two reasons: security and execution speed.
At present MySQL is seeing $assetNumber and so is believing it to be a column name. It has not been replaced with the value. You may wish instead to concatenate the variable into the string. I am uncertain which language you are using though.
PHP
$query = "INSERT INTO egmtable (Asset_Number) VALUES (".$assetNumber.")";
Coldfusion
qryString = "INSERT INTO egmtable (Asset_Number) VALUES ("&assetNumber&")";
Java
string query = "INSERT INTO egmtable (Asset_Number) VALUES("+assetNumber+")";
In all these cases though, this is vulnerable to SQL injection. You would instead be better served using similar to cfqueryparam (CF) / mysqli->bind (PHP) to allow the language to ensure the value is properly escaped and so ensure your query is safe. So going down the java route and using passing parameters to a JDBC PreparedStatement as a starting point
query = con.prepareStatement("INSERT INTO egmtable (Asset_Number) VALUES( ? )");
query.setString(1, assetNumber);
If you are able to specify the language you are using then I can provide a more specific answer.
I am working on this code and i am using a simple insert statement and I cant figure out why its not working. If anyone could see what I am doing wrong please let me know. Thanks!
This is the error I am getting:
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 'long,comments)
VALUES (2 ,2012-11-18 21:25:30, 39.3436984, -76.5856958, hh)' at line 1
here is the code:
mysql_query ("INSERT INTO incidents (emergency_type,date_time,lat,long,comments)
VALUES (2 ,$catchDate, $catchLat, $catchLong, $catchDescription)") or die(mysql_error());
echo"<br /> Data inserted";
Long is a reserved word, try `long` surrounded with backticks instead.
Reference https://dev.mysql.com/doc/refman/5.5/en/reserved-words.html
A quick browse around the docs reveals that you should be investigating PDO::prepare and PDO::execute to do this. Your current method appears to be vulnerable to SQL injection.
I'm not a PHP programmer, but something like:
$db = get a db handle from somewhere
$st = $db->prepare('Insert Into Incidents (emergency_type, date_time, lat, `long`, comments) Values (?, ?, ?, ?, ?)');
$st->execute(array(2 ,$catchDate, $catchLat, $catchLong, $catchDescription));
LONG is a keyword/reserved word in mysql. You can use backticks to escape it
INSERT INTO incidents (emergency_type,date_time,lat,`long`,comments)
Or change your table column name to longitude
INSERT INTO incidents (emergency_type,date_time,lat,`long`,comments)
VALUES (2 ,$catchDate, $catchLat, $catchLong, '$catchDescription')
LONG is on the list of MySQL Reserved Keywords. Escape it with backtick instead.
One more thing, values for date_time and comments must be enclosed with single quotes as they are not numeric.
and you query is now vulnerable with SQL Injection, please take time t read the article below
How can I prevent SQL injection in PHP?
Has anyone seen a DBI-type module for Perl which capitalizes, easily, on MySQL's multi-insert syntax
insert into TBL (col1, col2, col3) values (1,2,3),(4,5,6),...?
I've not yet found an interface which allows me to do that. The only thing I HAVE found is looping through my array. This method seems a lot less optimal vs throwing everything into a single line and letting MySQL handle it. I've not found any documentation out there IE google which sheds light on this short of rolling my own code to do it.
TIA
There are two approaches. You can insert (?, ?, ?) a number of times based on the size of the array. The text manipulation would be something like:
my $sql_values = join( ' ', ('(?, ?, ?)') x scalar(#array) );
Then flatten the array for calling execute(). I would avoid this way because of the thorny string and array manipulation that needs to be done.
The other way is to begin a transaction, then run a single insert statement multiple times.
my $sql = 'INSERT INTO tbl (col1, col2, col3)';
$dbh->{AutoCommit} = 0;
my $sth = $dbh->prepare_cached( $sql );
$sth->execute( #$_ ) for #array;
$sth->finish;
$dbh->{AutoCommit} = 1;
This is a bit slower than the first method, but it still avoids reparsing the statement. It also avoids the subtle manipulations of the first solution, while still being atomic and allowing disk I/O to be optimized.
If DBD::mysql supported DBI's execute_for_fetch (see DBI's execute_array and execute_for_fetch) this is the typical usage scenario i.e., you have multiple rows of inserts/updates/deletes available now and want to send them in one go (or in batches). I've no idea if the mysql client libs support sending multiple rows of bound parameters in one go but most other database client libs do and can take advantage of DBI's execute_array/execute_for_fetch. Unfortunately few DBDs actually implement execute_array/execute_for_fetch and rely on DBI implementing it one row at a time.
Jim,
Frezik has it. That is probably the most optimal:
my $sth = $dbh->prepare( 'INSERT INTO tbl (?, ?, ?)' );
foreach(#array) { $sth->execute( #{$_} ); }
$sth->finish;