There are many examples around which parse the JSON and then insert the respective fields into MySQL table.
My case is different in a way that I am creating a json at runtime.
my table looks like this:
mysql> describe turkers_data;
+-----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------+------+-----+---------+-------+
| id | char(36) | NO | PRI | NULL | |
| sentences | json | NO | | NULL | |
+-----------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
based on the input received, I build a json using json_encode method in php, which I alredy validated on jsonlint and it is of course valid.
example json:
{
"opening": "[\"John arrived at Sally's house to pick her up.\",\"John and Sally were going to a fancy restaurant that evening for a dinner.\",\"John was little nervous because he was going to ask Sally to marry him.\"]",
"first_part": "[\"aa\",\"bb\"]",
"first_mid": "[\"Waiter shows John and Sally to their table.\"]",
"mid_part": "[\"cc\",\"dd\"]",
"mid_late": "[\"John asks Sally, \\\"Will you marry me?\\\"\"]",
"last_part": "[\"ee\",\"ff\",\"gg\"]"
}
I use following code to insert into mysql table using mysqli
$opening = array("John arrived at Sally's house to pick her up.", "John and Sally were going to a fancy restaurant that evening for a dinner.", "John was little nervous because he was going to ask Sally to marry him.");
$mid_early = array("Waiter shows John and Sally to their table.");
$mid_late = array('John asks Sally, "Will you marry me?"');
$json_data->opening = json_encode($opening);
$json_data->first_part = json_encode($jSentence_1);
$json_data->first_mid = json_encode($mid_early);
$json_data->mid_part = json_encode($jSentence_2);
$json_data->mid_late = json_encode($mid_late);
$json_data->last_part = json_encode($jSentence_3);
$data = json_encode($json_data);
echo($data);
$sql = "INSERT INTO turkers_data (id, sentences)
VALUES ($id, $data)";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
but it does not work, i get the error:
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 '"opening":"[\"John arrived at Sally's house to pick her up.\",\"John and Sally w' at line 2
I do not know what is wrong. I could not find much information on how to do this, I read that it is not recommended to have json data dumped as it is into mysql table, but in my case i am unsure of how many sentences are going to there. Also, I believe this serves the purpose for the time being, I plan to just get that JSON from mysql back and process the data in python.
Also pardon me for using json, JSON, MySQL, mysql, I do not know the standard yet.
You are having a problem with your SQL insert because you have this:
$sql = "INSERT INTO turkers_data (id, sentences) VALUES ($id, $data)";
There is no escaping of quotes on $data, and the $data is not wrapped in single quotes either.
You should build this as a prepared statement and bind the params which will do all that for you:
$sql = "INSERT INTO turkers_data (id, sentences) VALUES (?,?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ss', $id, $data );
$stmt->execute();
The above assumes you are using mysqli, and not PDO. If its PDO, this is syntax for PDO method:
$sql = "INSERT INTO turkers_data (id, sentences) VALUES (?,?)";
$stmt = $conn->prepare($sql);
$stmt->execute(array($id, $data));
EDIT
Last ditch effort (AND ILL-ADVISED), if your php and mysql do not support prepared statements (it should!), then you can resort to the old method of wrapping and escaping your fields in the sql build string:
$sql = "INSERT INTO turkers_data (id, sentences)
VALUES (
'". $conn->real_escape_string($id) ."',
'". $conn->real_escape_string($data) ."'
)";
But this is NOT ADVISED! If at all costs you should try to get prepared statements to work, or upgrade your PHP, or mysqli extensions.
Related
I hope I'm missing something easy here.
I have an array created in js, say: var ids = [1,2,3,4,5];
Now I want this array to populate a column in my SQL database table.
I have the pipeline setup for adding single elements to my table like this:
request is sent via ajax:
$.ajax({
type: "POST",
url: "some.php",
data: {
ids: ids,
}
});
some.php receives the data (connection, etc. is set up):
$ids = $_POST['ids'];
SQL is used to insert single values to the column COL_ID
$sql = "INSERT INTO `mydb`.`dbtable`(`COL_ID`) VALUES ('$ids)";
This pipeline works for single values (e.g. of ids = 2 but fails for an array.
What I'd want is for COL_ID to contain each array element as a row
| COL_ID |
|-------- |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
I suspect it's in the SQL query. Any help is welcome.
First, use prepared statements, don't insert post data directly into a database query. Using post data directly means you are vulnerable to sql injection attacks.
As #DanielReed indicated, the correct format is
INSERT INTO table_name (column_list) VALUES (value_list_1), (value_list_2), (value_list_3);
You can build this dynamically:
$ids = $_POST['ids'];
// Make sure we get the correct number of ? for prepared statements
$params = str_repeat('(?), ', count($ids));
// Strip the trailing space and comma
$params = substr($params, 0, -2);
$sql = 'INSERT INTO `mydb`.`dbtable`(`COL_ID`) VALUES ' . $params;
Now you can use $sql as your query and $ids as the values for the prepared statement. This prevents sql injection.
PHP receives it as an array.
SQL Syntax wants it in the following syntax:
INSERT INTO table_name (column_list)
VALUES
(value_list_1),
(value_list_2),
...
(value_list_n);
So what you could do is:
$sql = "INSERT INTO `mydb`.`dbtable`(`COL_ID`) ";
foreach($ids as $value){
$sql .= "(".$value.") ";
}
I have a program that can perform inserts and updates to the database, I get the data from API.
This is sample data when I get:
$uname = $get['userName'];
$oname = $get['offerName'];
$visitdata= $get['visits'];
$convdata = $get['conversion'];
I save this data to database sql. (sucess) this is a sample:
$sql = "INSERT INTO data_tester(username_data, name_offer_data, visit_data, conversion_data) VALUES('$uname','$oname', '$visitdata', '$convdata')";
Sample data in database table
id | username_data | name_offer_data | visit_data | conversion_data
1 | MOJOJO | XXX AU | 177 | 13
2 | MOJOJO | XX US | 23 | 4
Now, I want to save data $uname, $oname, $visitdata, $convdata if NOT EXIST and UPDATE $visitdata, $convdata where $uname, $oname if EXIST
How to run the code with a simple query.
Please give me an example.
Thank you.
The feature you are looking for is called UPSERT and it is the part of SQL-2008 Standard. However not all DBMS-s implement it and some implement it differently.
For instance on MySQL you can use:
INSERT ... ON DUPLICATE KEY UPDATE
syntax (link to docs)
or
REPLACE INTO
syntax (link to docs).
These methods require you to have a proper PRIMARY KEY: (username_data name_offer_data) in your case.
Some PHP frameworks support this feature too provided you are using ActiveRecord (or similar) class. In Laravel it is called updateOrCreate and in Yii it is called save(). So if you are using a framework try to check its documentation.
If you are using neither framework nor modern DBMS you have to implement the method yourself. Run SELECT count(*) from data_tester WHERE username_data = ? AND name_offer_data = ?, check if it returned any rows and call an appropriate UPDATE/INSERT sql
it's simple, try this:
if(isset($get['userName'])){
$sql = "SELECT * FROM data_transfer WHERE userName = ".$userName.";";
$result = connection()->query($sql);
$rs = mysqli_fetch_array($result);
connection()->close();
//if is not void, means that this username exists
if ($rs != ''){
mysqli_free_result($result);
//InsertData
}
else{
mysqli_free_result($result);
//UpdateData
}
*chech that you have to use your PrimaryKey on where clause to ensure there are only one of this. if you use an ID and you don't get it by $_GET, you'll have to modify something to ensure non-duplicated data. For example, checking that userName cannot be duplicated or something similar
You can simply use replace into command instead of insert into command.
$sql = "REPLACE INTO data_tester(username_data, name_offer_data, visit_data, conversion_data) VALUES('$uname','$oname', '$visitdata', '$convdata')";
It is one of mysql good and useful feature. I used it many times.
Please ensure there is a unique key on column username_data, if so Mysql's ON DUPLICATE KEY UPDATE is suitable for this case, the SQL statement is like that:
$sql = "INSERT INTO data_tester(username_data, name_offer_data, visit_data,
conversion_data) VALUES('$uname','$oname', '$visitdata', '$convdata')
ON DUPLICATE KEY UPDATE username_data = '$uname', name_offer_data =
'$oname', visit_data = '$visitdata', conversion_data = '$convdata'"
I am trying to output encrypted data stored in a table in a BLOB format, but it's not working. I inserted it using prepared statements, and when I checked on the mysql command line client, it showed the entry has been recorded, but the blob fields are empty, and every other field has some value. Also, the blob field must not be null, as I have specified it while table creation, so I considered that the command line cannot show the blob field data.
So using php, I have tried to return a base64_encode value of the blob field, but it didn't help. It's still empty. What do I do?
P.S.: It's not an image, it's encrypted text with AES-256.
$stmt = $conn->prepare("INSERT INTO data_store (eid, ekey, ecipher) VALUES (?, ?, ?)");
if($stmt->bind_param("sbb", $eid, $ekey, $ecipher)) {
echo "Successful";
}
// set parameters and execute
$eid=$postedID;
$ekey=$postedKey;
$ecipher=$postedCipher;
$stmt->execute();
$stmt->close();
$conn->close();
After that I tried to return the BLOB value encoding it, but it returns nothing whereas the value of id which is a string does show up. How do I solve this? I need to encrypt the data and later decrypt it plaintext for the website.
How do I achieve this?
Thanks a lot.
P.S.: I haven't tried decrypting yet, I need the encrypted value first, so suggesting to decrypt it first won't be a very helpful one.
The table looks like this-
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| eid | varchar(255) | NO | PRI | NULL | |
| ekey | blob | NO | | NULL | |
| ecipher | blob | NO | | NULL | |
+-------------+---------------------+------+-----+---------+----------------+
The problem was solved when I changed the parameters to string "s", this seems to work correctly since the variables I held the data into were strings, so it fits in.
So the corrected code is:
$stmt = $conn->prepare("INSERT INTO data_store (eid, ekey, ecipher) VALUES (?, ?, ?)");
if($stmt->bind_param("sss", $eid, $ekey, $ecipher)) {
echo "Successful";
I am not saying this is a perfect solution, but it seems to solve my problem for now, I would be extremely helped if someone presents a way of using the blob in php instead of string. Thank you.
Specifying b tells mysqli to send the data in separate packets to the server.
Documentation here
However, what the documentation fails to detail is how you should specify the packet data. One would assume, like the other types, you should just set up a referenced variable containing the data. It turns out you need to use send_long_data
With this function you actually have control over each chunk of data, so it's up to you to make sure you don't send a packet too large for your server to handle.
Try something like this
$stmt = $conn->prepare("INSERT INTO data_store (eid, ekey, ecipher) VALUES (?, ?, ?)");
//Initialise variables
$eid = $postedID;
$ekey = NULL;
$ecipher = NULL;
if($stmt->bind_param("sbb", $eid, $ekey, $ecipher)) {
// Send blobs
$ekey_chunks = str_split($postedKey, 8192);
foreach ($ekey_chunks as $chunk) {
$stmt->send_long_data(1, $chunk);
}
$ecipher_chunks = str_split($postedCipher, 8192);
foreach ($ecipher_chunks as $chunk) {
$stmt->send_long_data(2, $chunk);
}
$stmt->execute();
$stmt->close();
}
$conn->close();
Source this blog
By according to this question I have 2 table Source and details .
The Source table is as follows:
+----+----------+---------------+-----------+
| id | item_name|items_download | category |
+----+----------+---------------+-----------+
| |
+----+----------+---------------+-----------+
The details table is as follows:
+------+----------+-----+------+
| name | download | time| ip |
+------+----------+-----+------+
| |
+------+----------+-----+------+
At first step I want to get data from Source table (in real time) and put into details table by this code:
$get= "INSERT INTO `details` (`name`, `download`) SELECT `Source`.`item_name`,`Source`.`items_download` FROM `Source`"
At next step I want to get visitor IP address for each file.
for example if someone downloaded testfile I want to have this output:
+----------+---------+--------------+-----------+
| name | download | time | ip |
+----------+----------+-------------+-----------+
| testfile | 32 |download time|192.168.0.0|
+----------+----------+-------------+-----------+
| file2 | 0 | | |
+----------+----------+-------------+-----------+
To do this i use this code:
$ip = $_SERVER['REMOTE_ADDR'];
$update = "UPDATE details SET ip = '$ip', dldate = NOW()"
But its happened for all files, all of the file get same IP and time. I know its need a condition WHERE but I don't know what should I type as a condition to get IP address for each file that download.
Imho you don't need any UPDATE query. You just do an INSERT everytime a user requests a file:
<?php
$fileid = $_GET['fileid'];
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$sql = "SELECT * FROM Source WHERE id=" . (int)$fileid;
foreach ($pdo->query($sql) as $row) {
$statement = $pdo->prepare("INSERT INTO details (name, download, time, ip) VALUES (?, ?, NOW(), ?)");
$statement->execute(array(
$row['item_name'],
$row['items_download'],
$_SERVER['REMOTE_ADDR'],
));
}
?>
Some hints on the code above:
Use prepared statements - never inject any value directly into an SQL string.
It might be useless to insert file_name and items_download into the details table everytime. You have this information in your table "Source" anyway. So usually you would just put Source.id into your details table.
You should use your id column, which you have in your first table view, but it stragely disappears in the later ones.
Your id column should also be your PRIMARY_KEY AUTO INCREMENT column. Then each row has its own unique and indexed id.
But aside from that, what do you use to identify which file the user downloads? If it's the filename then simply use that:
EDIT: Add an id column to your details table!
$update = "UPDATE details SET ip = '$ip', dldate = NOW()
WHERE name = '$fileNameValue' LIMIT 1"
On a related note, you can not update multiple columns with the same shorthand reference of device = ip = '$ip' you have to specify each column in isolation and with an absolute target data to insert (here, the variable) .
If this is a typo you should edit and update your question.
Please also see Gerfried's answer regarding using prepared statements, they are the way you should be doing these things.
I think you need to get the session of user when he downloads the file and add it to the WHERE condition.
my table(s) structure (MySQL / each one is same as below)
+-------+--------------+------+------+-------------------+
| Field | Type | Null | Key | Default |
+-------+--------------+------+------+-------------------+
| id | int(11) | NO | PRI | AUTO INCREMENT |
| lesson| varchar(255) | NO | | LESSON_NAME |
| exam | char(50) | NO |UNIQUE| NO DEFAULT |
| quest | text | NO | | NO DEFAULT |
| answer| text | NO | | NO DEFAULT |
| note | text | NO | | NO DEFAULT |
+-------+--------------+------+------+-------------------+
and i'am posting some values to add this table via ajax ($post) - PHP 5.0
in database.php there is a function to get posted data and add to table
function update_table ($proper_table, $name, $question, $answer, $note) {
$sql = "INSERT INTO $proper_table (id, lesson, exam, quest, answer, note) VALUES ('', '', $name, $question,$answer,$note) ON DUPLICATE KEY UPDATE exam = $name, quest = $question, answer = $answer, note = $note";
$result= mysql_query($sql)or die(mysql_error());
}
$proper_table variable is taken by another variable to add this record to correct table.
(NOTE: Original table fields and variables are different (Turkish), to be more understandable i traslated to english but the syntax is the same as you see.)
Question : I want to check that if there is a record that exam field is same then all these variables will be used for updating this record, otherwise let function put this record to proper table as a new record.
But i'am getting error like below
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
is there any faulty coding? and what can be the solution?
Thanks right now...
function update_table ($proper_table, $name, $question, $answer, $note) {
$sql = "INSERT INTO $proper_table (lesson, exam, quest, answer, note) VALUES ('', '$name', '$question','$answer','$note') ON DUPLICATE KEY UPDATE quest = VALUES(quest), answer = VALUES(answer), note = VALUES(note)";
$result= mysql_query($sql)or die(mysql_error());
}
Just breaking this out I'll detail the changes
$sql = "INSERT INTO $proper_table
// Removed the PK (primary key) AI (auto increment) field - don't need to specify this
(lesson, exam, quest, answer, note)
// Likewise removed PK field, and added quotes around the text fields
VALUES ('', '$name', '$question','$answer','$note')
ON DUPLICATE KEY UPDATE
// If you specify VALUES(fieldName) it will update with the value you specified for the field in the conflicting row
// Also removed the exam update, as exam is the UNIQUE key which could cause conflicts so updating that would have no effect
quest = VALUES(quest), answer = VALUES(answer), note = VALUES(note)";
You need to wrap you string variables in single quotes in your SQL '$name' for example. Otherwise mysql thinks you are referencing column names.
With that query, when you add ON DUPLICATE KEY UPDATE... it will update when the id es the same than the id that you are sending, in this case you are not sending an id as parameter so it will never update because you have the id with auto-increment.
A solution could be that you read the table where exam equals the parameter you are sending, something like this:
SELECT id FROM $proper_table;
If it is null the you execute an insert, if it is not null the you update taking as parameter the id that you are getting from the select
id auto-increments, so presumably you don't want to set an empty string as id.
Try:
$sql = "INSERT INTO $proper_table (lesson, exam, quest, answer, note) VALUES ('', $name, $question,$answer,$note) ON DUPLICATE KEY UPDATE exam = $name, quest = $question, answer = $answer, note = $note";
You have to make it like this
<?php
function update_table($proper_table, $name, $question, $answer, $note, $id) {
$sqlQuery = "INSERT INTO '".$proper_table."' SET
name = '".$name."',
question = '".$question."',
answer = '".$answer."',
note = '".$note."' WHERE id = '".$id."'";
$result= mysql_query($sqlQuery)or die(mysql_error());
}
?>