Save mysql query into database - php

I am trying to allow users (In my place of work) to run a query, and if they choose, save it into a database so that they can just run it again later with a single click (Like if they are updating a database). I am having a problem with this, though. Simply running the query isn't an issue, but the query doesn't save correctly. The query is something like this:
LOAD DATA INFILE 'path/to/file/file.txt' INTO TABLE table FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n';
I can get it to save into the database correctly if I escape the backslashes when typing out the query, but that causes the query to run incorrectly on submit. I am wondering if there is a way that I can automatically escape backslashes. Or would it just be easier/better to separate the two features? If any more information is needed let me know, and thanks in advance.

I did some tinkering, and I got it. Here is the solution I came up with:
First, I used str_replace on the update.
$q = str_replace(array("\t", "\n"),array("\\t","\\n"), $_POST['update']);
Then, I prepared it as suggested.
if($stmt = $con->prepare("insert into queries (Query_Name, Query, Description) values (?, ?, ?);")){
$stmt->bind_param('sss', $qn, $q, $qd);
$stmt->execute();
$stmt->store_result();
$stmt->close();
}
Finally, I ran a mysqli_multi_query (because sometimes there is more than one query in a submission, which caused it to fail) to run the query(s) the user puts in.
$query = mysqli_multi_query($con, $q);
Thanks to everyone who offered suggestions!

You have to unescape the query before using it.
Create a method dedicated to run queries from the database like "myClass->unescapeAndExecute($escapedQueryFromDb);"

Related

How to get affected row count on WordPress query?

This code is to use in WordPress plugin.
The following is my code I am using to insert data from CSV file to database:
$sql="LOAD DATA LOCAL INFILE '".$fileurl."' INTO TABLE ".$table_name."
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\r\n' IGNORE 1 LINES (`first_name`,`last_name`, `email`, `mobile_phone`, `address_1`, `address_2`, `city`, `state`, `zip`, `about_us` );
";
$query = $wpdb->query($sql);
When I do this var_dump($query); it shows int(0), and data is successfully inserted in table. My question is how can I get number of inserted rows?
You can find the affected rows in your query using below.
$count = $wpdb->query($sql);
$count is your affected rows.
Very old question, I know, and perhaps this answer is trivially obvious, but posting in the hope it might be useful to someone who stumbled across it as I did.
In this particular case with LOAD DATA, one option might be to simply run an sql COUNT() before and after the LOAD DATA, and then take the difference:
$count_before = $wpdb->query("SELECT COUNT(*) FROM $table_name");
// LOAD DATA ...
$count_after = $wpdb->query("SELECT COUNT(*) FROM $table_name");
$new_rows = $count_after - $count_before;
I understand this may not work well if there is other simultaneous activity on the table; though you may be able to lock the table to prevent conflicting updates and to make the LOAD DATA even faster. You might be able to get this with $wpdb->affected_rows and that's also worth checking.
No doubt since it's 2 years ago since you asked this, you have any number of other working solutions; hopefully this is useful to anyone googling for a solution here.
Object $wpdb contains a lot of useful things. You can watch this by dump this object to see public properties.
One of them is what you search:
echo $wpdb->affected_rows;
You cannot get this information using a LOAD DATA statement with wpdb::query(). It doesn't understand the statement, so doesn't automatically fetch the number of affected rows. You can't get it yourself, either, because the necessary wpdb class properties (use_mysqli, dbh) are not public.

Error when Passing string values from Python request to PHP

What I am Trying to do
What I am attempting to do is, pass values from my python application to my web api where it gets saved to my database.
The problem
The reason why I am posting is because, I can send integers, 1,2,3 to my database from my python and that saves fine. But If I send "test","ape","tree" nothing is placed in the database. (PS, the data type is varchar(6) )
I can also pass string into the database (using post) from the browser and it works.
What have done
I have created my API , database and python script that passes the data around.
Python.
import requests
load={'par':'ape12'} //This doesnt save "ape" to the database
#load={'par':'3'} //This saves "3" to the database
r=requests.post("http://my-server.com/load.php",data=load)
PHP
<?php
//Connect to DB
include ("connectDB.php");
$loadgot=$_POST['load'];
mysqli_query($con,"INSERT INTO detect(l_result)
VALUES ($loadgot)");
mysqli_close($con);
?>
Hoping someone could assist me in this regard.
Thank you
You need to pass a properly formed query to mysql. The value needs to be surrounded by quotes, but also needs to escape any characters which will break out from the quoted environment. In practice, the best solution these days is to use parametrised queries (see example) like:
$stmt = mysqli_prepare($con, "INSERT INTO detect(l_result) VALUES (?)");
mysqli_stmt_bind_param($stmt, $loadgot);
mysqli_stmt_execute($stmt);
Or if you really want to use text query (you really shouldn't), you can do:
$loadgot_safe = mysqli_real_escape_string($con, $loadgot);
mysqli_query($con,"INSERT INTO detect(l_result) VALUES ('$loadgot_safe')");
The reason why you MUST NOT use:
mysqli_query($con, "INSERT INTO detect(l_result) VALUES ('$loadgot')");
is that anyone can submit multiple values - for example value1'), ('value2 will expand to INSERT INTO detect(l_result) VALUES ('value1'), ('value2') - which is definitely not what you want.
Modify the 'ape12' to "'ape12'".
Because, in MySQL we give the query like this
INSERT INTO detect(l_result) VALUES 'Value1';
So pass the values to MySQL with quotes. But no need for the integers.
From #e4c5 comment. Users wont give the quotes while entering the input. So we ensure the query inside the script. So try to changed the code like this
mysqli_query($con,"INSERT INTO detect(l_result) VALUES ('$loadgot')");

How to execute two sql queries in php?

I am trying to execute this code in a php page to store some data on my database.
The thing is that I want to Insert data, but due to a foreign key constraint it is impossible. So, in my php code I want to execute two sql queries. The first one to disable foreign key checks and the second one to insert the data.
When I try it in phpmyadmin it works. But manually. I would like to put it on php code.
This is my code. The parameter $conexion is the one that executes my sql queries.
Any ideas?
$sql = "SET foreign_key_checks=0";
$sql. = "INSERT INTO routes (title, distance, subtitle) VALUES ('".$_POST['title']."','".$_POST['distance']."', '".$_POST['subtitle']."');";
$conexion->multi_query($sql);
Try to avoid using multi_query. Sending a small query to the MySQL server doesn't really affect performance and does prevent kind of limit the effect of something like SQL injection.
In your case there's no need for multi_query. If you send two queries in a script, both go over on the same connection. The SET query affect the current connection.
// Protect against SQL injection
$title = $conexion->escape_string($_POST['title']);
$distance = $conexion->escape_string($_POST['distance']);
$subtitle = $conexion->escape_string($_POST['subtitle']);
// Execute queries
$conexion->query("SET forgeign_key_checks=0");
$conexion->query("INSERT INTO routes (title, distance, subtitle) VALUES ('$tittle', '$distance', '$subtitle')");
Apart from the comment above, you need a semi-colon between your sql statements
multi_query - Executes one or multiple queries which are concatenated by a semicolon.

SELECT and INSERT not selecting

When I execute
INSERT INTO `survey`
(`id`,`name`,`date_start`,`date_end`)
values
(:id,:name,NULL,DATE_ADD(NOW(), INTERVAL 1 MINUTE))
on duplicate key UPDATE `name`=:name;
SELECT coalesce(:id,LAST_INSERT_ID()) as 'id'
it inserts a new data fine, but doesn't select the id (which is needed later on in my php code)
I've tried this suggestion
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
but this SQL throws errors (due to duplicate parameters)
SELECT ASCII(substr(`perm` FROM floor(:i/8)+1))&(1<<(:i%8))>0 as perm FROM `user` WHERE `id`=:id
I'm in a lose-lose situation, re-writing all my SQL code to not have duplicate parameters would be very messy, doing a separate select straight after inserting may not return the id I want. Any suggestions would be great
You cannot run two queries at the same time, only one at the time.
If you want to do the whole thing at once then create a stored procedure.
Same goes for complex queries, when it gets complicated you want to have your logic in the database.
Here is an example:
DELIMITER //
CREATE PROCEDURE sp_insert_survey(IN `p_id`,
IN `p_name`,
IN `p_date_start`,
IN `p_date_end`)
BEGIN
INSERT INTO `survey`(`id`,`name`,`date_start`,`date_end`)
VALUES (p_id, p_name, p_date_start, p_date_end);
SELECT `id`,`name`,`date_start`,`date_end`
FROM survey WHERE `id` =LAST_INSERT_ID();
END //
DELIMITER ;
Call the sp from PDO:
$stmt = $db->prepare('CALL sp_insert_survey(?, ?, ?, ?)');
then fetch the data as a SELECT query.
Upon typing this up, one of the similar questions that came up on the right getting last inserted row id with PDO (not suitable result) gave a suitable answer in the question itself, although I'm a little dubious considering the method is being questioned itself.
$db->lastInsertId();
Seems to work for me, but in the question linked it isn't working as desired for the questioner, so I'm not entirely settled with this answer. It does seem to be a bit of a hack.

Why is my SQL insert statement failing to execute through my php script?

In a php script, I've attempted an insert statement several different ways:
$query = "INSERT INTO table (charfield,charfield,intfield,decimalfield) VALUES ('$stringvar','$stringvar',$intvar,$decimalvar)";
$query = "INSERT INTO table (charfield,charfield,intfield,decimalfield) VALUES ('".$stringvar."','".$stringvar."',".$intvar.",".$decimalvar.")";
$query = 'INSERT INTO table (charfield,charfield,intfield,decimalfield) VALUES ("'.$stringvar.'","'.$stringvar.'",'.$intvar.','.$decimalvar.')';
$query = 'INSERT INTO table (charfield,charfield,intfield,decimalfield) VALUES ("'.$stringvar.'","'.$stringvar.'","'.$intvar.'","'.$decimalvar.'")';
I've executed it several different ways too using combinations of these:
mysql_real_escape_string($query);
mysql_query($query);
$result = #mysql_query($query);
I've echo'd out the statement that is being concatenated and it looks fine. Even if I copy and paste that into phpmyadmin sql editor, it executes fine. The database is MySQL and the user has the correct permissions.
What am I doing wrong?
EDIT:
Error message using or die:
Access denied for user 'schaffins'#'localhost' (using password: NO)
I've added a user with the rights to select, insert, and update and I'm connecting using that user in the php before executing anything.
Also, I was able to insert into another table I made in the same script.
This issue isn't with your insert - the error is connecting to the database so its not even getting as far as running the insert statement.
Double-check the credentials you are passing into mysql_connect()... from the error message "Access denied for user 'schaffins'#'localhost' (using password: NO)" it appears the problem is with your password.
You can't use mysql_real_escape_string on the entire query. That will escape quotes that are part of the query syntax. You need to use it on the values to insert in the query.
Sometimes the database connection happens only after certain actions &| validations take place. Make sure you have an open connection before attempting to execute any sql. If the connection is nested within an if/else code block, the conditions may not be satisfied and the db connection will not be established.
Try finding the db connection and moving (or copying) to a more 'globalized' location within the php - aka somewhere in the php that ensures the db connection is made before any if statements that might exclude the connection from being established based on conditionals that aren't allowing

Categories