Not deleting row in second table - php

I want to delete a row from the database depending on what the file name of the image is. Lets say I have 2 tables below:
Image Table:
ImageId ImageFile
01 cat.png
02 dog.png
03 dog_2.png
Image_Question Table:
ImageId SessionId QuestionId
01 AAA 4
02 ABD 1
03 RTD 11
Lets say in my application I delete the file image dog_2.png, then I want it to delete the row which states dog_2.png in the Image Table (This is working fine) and be able to delete the row from the Image_Question Table where the row contains the same ImageId associated with the ImageId and ImageFile name from the Image Table (This is not working).
So for the above example the 2 tables should now look like this after deletion:
Image Table:
ImageId ImageFile
01 cat.png
02 dog.png
Image_Question Table:
ImageId SessionId QuestionId
01 AAA 4
02 ABD 1
But it does not delete the row from the Image_Question Table, how can I get this row to delete?
Below is the full code where it deletes the row from the Image Table and it contains most of the code which has been setup but not fully completed on deleting a row from the Image_Question Table:
$image_file_name = $_GET["imagefilename"];
$img = "ImageFiles/$image_file_name";
echo "$image_file_name was Deleted";
unlink("ImageFiles/$image_file_name");
$imagedeletesql = "DELETE FROM Image WHERE ImageFile = ?";
if (!$delete = $mysqli->prepare($imagedeletesql)) {
// Handle errors with prepare operation here
}
//Don't pass data directly to bind_param; store it in a variable
$delete->bind_param("s",$img);
$delete->execute();
if ($delete->errno) {
// Handle query error here
}
$delete->close();
$imagequestiondeletesql = "DELETE FROM Image_Question WHERE ImageId = ?";
if (!$deleteimagequestion = $mysqli->prepare($imagequestiondeletesql)) {
// Handle errors with prepare operation here
}
// Don't pass data directly to bind_param; store it in a variable
$deleteimagequestion->bind_param("s",....);
$deleteimagequestion->execute();
if ($deleteimagequestion->errno) {
// Handle query error here
}
$deleteimagequestion->close();

You can use a JOIN query to delete from multiple tables in a single query. I think this sort of statement will work for you:
$sql = "
DELETE img, img_q
FROM Image AS img
LEFT JOIN Image_Question AS img_q
ON img_q.ImageId = img.ImageId
WHERE img.ImageFile = ?";

Related

I am trying to design a PHP/ SQL page to make posts with multiple pictures

My question is how to i saves images on the sql server directed to the same post? specifically, should i have a posts table with an id for each post, then an image table with a column for post id? If this is the case, how would i be able to add a row into the post table, obtain its id, then add rows in the image table referring to the post's id?
any and all help would be appreciated.
Here is quick example:
Database structure
post
------
id (AUTO_INCREMENT)
title
content
post_image
------
id (AUTO_INCREMENT)
post_id (INDEX, FOREIGN KEY to post.id)
path
PHP (using mysqli)
$title = mysqli_real_escape_string($_POST['title']);
$content = mysqli_real_escape_string($_POST['content']);
mysqli_query("INSERT INTO post (title, content) VALUES ('{$title}', '{$content}')");
$postId = mysqli_insert_id();
$images = [ // Here you can process images from $_FILES
"/images/post/{$postId}/image1.png",
"/images/post/{$postId}/image2.png",
];
foreach ($images as $image) {
$safePath = mysqli_real_escape_string($image);
mysqli_query("INSERT INTO post_image (post_id, path) VALUES ({$postId}, '{$safePath}')");
}

How to display both old and new values of particular column in sql on html using php?

Let us assume there is a form which has a text field and a submit button.
Every time I type a text and submit it should be stored in the database and displayed in a table.
Additionally, when I again submit the form the old text in SQL column value should be overwritten with this new value and both values should be displayed in table rows.
So every time I do this I want old data and new data to be appended to table rows.
How to achieve this??
Instead of overwriting the data, why not create a new entry and mark it as active, such that to get the latest data using sql, you order by primary key desc limit 1. If you need the old data you ust get the previous entry.
We have very few information, but here is some idea to achieve it :
1/ Add an last field in your table and update it each time you add a new data, then when you display it just get all data and check the last field to see which one is the last :
So imagine this table :
Table data
===============================
id_data | id_user | data | last
When you display it for your user :
select * from data where id_user = :id_user order by last desc;
This way you will get the last one with last = 1 (true) first then the other.
And when you submit a new data :
// you update all old data as "old"
update data set last = 0 where id_user = :id_user;
// you create a new data
insert into data (id_user, data, last) values (:id_user, :data, 1);
2/ Add a field date so you know wich one are older than other
Table data
==================================
id_data | id_user | data | created
When you display it for your user :
select * from data where id_user = :id_user order by created desc;
This way you will get the data order by the created date with the last one first.
And when you submit a new data :
// you create a new data with the current date
insert into data (id_user, data, created) values (:id_user, :data, NOW());
This solution is better I think so you can have some "historic" of each data.
Is it what you are looking for?
why not just append it with a pipe character like so... "|entry_data" then just explode it when you need it.
var data_array = explode("|",data);
print_r(data_array);
If you want to show all changes only for some users then better to save you last value in main table and create new history table for changes.
table_history
id | id_row | field | before | after
In this case you can without additional query show last value for some users and all data for others.
In this structure you also can save multiple fields data if you need.
And believe me, saving previous value in your table will make you life is easy in future.
In given below code i update field with new one insert data and also append your new data with old I hope this help you
Form from which you insert and update data
if(isset($_POST['submit']) && $_POST['submit']){
$text_field = $_POST['text_field'];
$query ="SELECT * FROM `table_name`"; //replace with your table name
$run=mysqli_query($conn,$query);
$result = mysqli_fetch_row($run);
$data = $result[1];
if(count($result)){
$last_string = $data.','.$text_field;
$update= "UPDATE `table_name` SET `text`='".$last_string."'";
mysqli_query($conn,$update);
}else{
$query = "INSERT INTO `table_name`(`text`) VALUES ('".$text_field."')";
mysqli_query($conn,$query);
}
}
?>
<form action="" method="POST">
<input type="text" name="text_field">
<input type="submit" name="submit">
</form>
view of data which is inserted
<?php
$query ="SELECT * FROM `table_name`";
$run=mysqli_query($conn,$query);
$result = mysqli_fetch_row($run);
if(isset($result) && count($result)){
echo "<p>$result[1]</p>";
}

Replace to another column if exits in MySql

I have a HTML table having values from Mysql. My HTML table looks like this
------- ------ ------ ------
type name b_id Edit
------- ------ ------ ------
Laptop mac E1:23 edit
Desktop dell D2:45 edit
I am inserting values from input textboxes for type and name. And a select dropdown for b_id.
I can edit each row values by clicking editand i have a dropdown displaying all my b_id's.
I need to update b_id values so that, if it already exists replace with new delete the old.
For suppose i'l hit edit on Desktop dell row. And i'l select E1:23(which is already mapped for laptop mac). On saving this, E1:23 should map to desktop dell and previous mapping (laptop mac) should be deleted. I mean it should be empty
My Query
$id = $_REQUEST['id']; // Auto Increment
$b_id = $_REQUEST['b_id']; //b_id from select dropdown on edit
$sql = "SELECT * FROM table_name WHERE b_id='$b_id'";
$rs=parent::_executeQuery($sql);
$rs=parent::getAll($rs);
if($rs) // if b_id already exists
{
//First empty old b_id which has mapped already
$sql2 = "UPDATE table_name SET b_id='$b_id' WHERE id='$id'";
$rs=parent::_executeQuery($sql);
}
So how to empty previous mapped b_id. Not the type and name
If you want to empty the data in b_id, your query should be something like this:
if($rs) // if b_id already exists
{
//First empty old b_id which has mapped already
$sql2 = "UPDATE table_name SET b_id='' WHERE b_id='$b_id'";
$rs=parent::_executeQuery($sql2);
}

How to retrieve an id after details are submitted

I am having trouble with a major flaw with my database design. Below is my four tables:
Session Table:
SessionId SessionName
3 EROEW
Question Table:
QuestionId(PK) QuestionNo QuestionContent SessionId (FK)
11 1 Question1 3
12 2 Question2 3
13 3 Question3 3
Image_Question:
ImageQuestionId (PK) ImageId (FK) SessionId (Fk) QuestionNo (FK)
1 1 3 1
2 2 3 2
Image:
ImageId (PK) SessionId (Fk) QuestionNo (FK)
1 3 1
2 3 2
Now as you can see in the Image_Question Table, the QuestionNo refers to a QuestionNo which is non-unique or in other words a non unique field. Now I head this is bad practice.
Now I know you are going to say why not use QuestionId. Well the problem is that I can't use QuestionId because the images are uploaded to each question before a question is submitted and the only way we can give a question its own QuestionId is after the user has submitted the questions.
So what I tried to do was determine which question an uploaded image belongs to by getting the QuestionNo from the page as well as the SessionId.
Now as I have heard this is a bad way of doing it, I want to change QuestionNo (FK) in Image_Question to QuestionId (FK). But I am not going to be able to upload files and insert details of the uplaod after questions are submitted to get the QuestionId, to me that can't be done.
So my question is that is there a way we can some how store each uploaded image into a temp table, get the question number and sessionid for each image belongs to and then from there be able to find the QuestionId and store the QuestionId value in the Image_Question Table?
Below is my current php code where it inserts the values after image is uploaded:
Be very greatful if somebody can update code below but any answer will be helpful:
move_uploaded_file($_FILES["fileImage"]["tmp_name"],
"ImageFiles/" . $_FILES["fileImage"]["name"]);
$result = 1;
$imagesql = "INSERT INTO Image (ImageFile)
VALUES (?)";
//Dont pass data directly to bind_param store it in a variable
$insert->bind_param("s",$img);
//Assign the variable
$img = 'ImageFiles/'.$_FILES['fileImage']['name']; //GET THE IMAGE UPLOADED
$insert->execute();
$insert->close();
$lastImageID = $mysqli->insert_id;
$_SESSION['lastImageID'] = $lastImageID;
$_SESSION['ImageFile'] = $_FILES["fileImage"]["name"];
$sessid = $_SESSION['id'] . ($_SESSION['initial_count'] > 1 ? $_SESSION['sessionCount'] : ''); GET THE NAME OF THE SESSION
$sessionquery = "SELECT SessionId FROM Session WHERE (SessionName = ?)"; //FIND SESSIONID by finding it's SESSIONNAME
// Bind parameter for statement
$sessionstmt->bind_param("s", $sessid);
// Execute the statement
$sessionstmt->execute();
// This is what matters. With MySQLi you have to bind result fields to
// variables before calling fetch()
$sessionstmt->bind_result($sessionid);
// This populates $sessionid
$sessionstmt->fetch();
$sessionstmt->close();
$imagequestionsql = "INSERT INTO Image_Question (ImageId, SessionId, QuestionNo) //INSERT DETAILS INTO CURRENT IMAGE_QUESTION TABLE
VALUES (?, ?, ?)";
if (!$insertimagequestion = $mysqli->prepare($imagequestionsql)) {
// Handle errors with prepare operation here
echo "Prepare statement err imagequestion";
}
$qnum = (int)$_POST['numimage']; //QUESTION NUMBER IMAGE IS UPLOADED IN
$insertimagequestion->bind_param("iii",$lastImageID, $sessionid, $qnum);
$insertimagequestion->execute();
if ($insertimagequestion->errno) {
// Handle query error here
}
$insertimagequestion->close();
Your biggest problem is the fact that your schema isn't normalized. Doing so should help you some.
Here's how I recommend structuring your database:
Session:
SessionId SessionName
3 EROEW
Question:
QuestionId(PK) QuestionContent SessionId (FK)
11 Question1 3
12 Question2 3
13 Question3 3
Image:
ImageId (PK)
1
2
Image_Question:
ImageId (FK) QuestionId (FK) -- (Composite primary key)
1 11
2 12
The insert order for the tables should be:
Session -> Question -
\
-- Image_Question
/
Image -
You'll be dodging potential update issues, and data conflicts otherwise.

How to retrieve and insert ImageId?

I have a INSERT function where it inserts the image filename in the 'ImageFile' field in the "Image" table, each row has it's own ImageId thanks to auto number. An example of this is below:
ImageId ImageFile
23 orange.jpg
24 flowers.png
25 castle.png
26 orange.jpg
What I want to do is also insert the ImageId into another table with the QuestionId and SessionId so that this table (Image_Question) can use the ImageId to link the Image table with the Image Question table. But how do I code it so that when I insert image details in the table above, then it will retrieve it's ImageId and also store it in the ImageId in the Image_Question table. Example below:
ImageId SessionId QuestionId
23 AAA 1
24 AAA 2
25 AAA 3
26 AAA 4
I have coded the INSERT values for SessionId and QuestionId but just need help retrieving and inserting the ImageId. Below is the current code:
<?php
session_start();
//connect to db
$i = 0;
$insertimage = array();
for($i = 0; $i < $c; $i++ ){
$insertimage[] = "'". mysql_real_escape_string($_SESSION['id'] ) .
($_SESSION['initial_count'] > 1 ? $_SESSION['sessionCount'] : '') ."' ,'".
mysql_real_escape_string( $_POST['numQuestion'][$i] ) ."'";
}
$imagesql = "INSERT INTO Question (ImageId, SessionId, QuestionId)
VALUES (" . implode('), (', $insertimage) . ")";
echo($imagesql);
mysql_close();
?>
mysqli_insert_id() after query execute would do the trick
You can get the most recently generated auto_increment id using MySQL's last_insert_id() function. PHP exposes this through mysql_insert_id(). last_insert_id works on a per-connection basis so there is no need to worry about concurrent inserts crossing ids.

Categories