PHP is updating instead of inserting - php

I am creating a page where the user fill a report and that report is inserted to the database
I have below my php page that is supposed to insert new values to table reports, but it is updating instead
<?php
include 'connectionfile.php' ;
$ref = $_POST['ref'];
$title =$_POST['titl'];
$type = $_POST['type'];
$content = $_POST['content'];
session_start();
$sql = "insert into reports (reference, title,id_type, content) values ('".$ref."', '".$title."', '". $type."','".$content."');";
$result =mysqli_query($con,$sql ); ?>
Is it because id_type (primary key of table type) is a foreign key -in table report- of value 1 and 2?
Because if I insert id_type=1 for example, id_report (primary key of table report) increments by 1, same goes to id_type=2
Answer might be clear,my knowledge in web development was forgotten.

With the SQL-Query you provided, no update is possible. You can make an UPDATE ON DUPLICATE KEY, but this is not in this query. Please note, that you do not have to and should not specify any value for an automatically setted parameter (AUTO_INCREMENT).

Related

MySQL one-to-may relationship

After looking around on stackoverflow, I'm still having a little trouble understanding the one-to-many relationship in mysql. I have a request coming in from the user (form submission) which will be stored in one table. This is a dynamic form that lets the user add extra fields therefore those will be stored in a separate table. So in short, in my db design, there will be one table for the users with PRIMARY KEY AUTO INCREMENT and there will be another table for the hostnames PER user (multiple fields -array) and using a foreign key that references to the primary key in the user table. Sorry if this is long but trying to make this a good question.
Example:
User Table: (ONE)
1. John Doe, blah, 11-12-15
2. Sally Po, blah, 11-14-15
3. John Doe, blah, 11-15-15
(these are three separate requests)
(numbers are primary key auto incr.)
Host Name Table: (MANY)
1. www.johndoe.com
1. www.johndoe2.com
1. www.johndoe3.com
2. www.sallypo.com
2. www.sallypo2.com
(these numbers (foreign key) should match the primary key for each request)
Code (Leaving out the actual queries + pretty sure I shouln't be using last_id):
$sql = "CREATE TABLE IF NOT EXISTS userTable (
id int AUTO_INCREMENT,
firstName VARCHAR(30) NOT NULL,
date DATE NOT NULL,
PRIMARY KEY (id)
)";
//query
$sql = "CREATE TABLE IF NOT EXISTS hostNamesTable (
id int NOT NULL,
hostName VARCHAR(90) NOT NULL,
FOREIGN KEY (id) REFERENCES userTable(id)
)";
//query
$sql = "INSERT INTO userTable (firstName, date)
VALUES ('$firstName', '$date')";
//query
$last_id = mysqli_insert_id();
for($i = 0; $i < sizeof($hostName); $i++){
$sql = "INSERT INTO hostNamesTable (id, hostName)
VALUES ('$last_id', '$hostName[$i]')";
//query
}
What am I doing wrong? (is this the right way to go about it?)
note: I was trying to get the last_id of the user Table so that I can use it in the hostName table as the foreign key
EDIT: I'm using MySQLi with php
EDIT 2:
After the changes, this is the error I am getting now: Cannot add or update a child row: a foreign key constraint fails (d9832482827984hb28397429.hostNamesTable, CONSTRAINT hostNamesTable_ibfk_1 FOREIGN KEY (id) REFERENCES userTable (id))Error: INSERT INTO hostNamesTable (id, hostName, ) VALUES ('', 'secondhost.net')
--Looks like the $last_id isn't even being recorded?
EDIT 3: Started working. Not sure what it was but I think it was because of some type.
why dont you just add an extra column in the hostNames table which is called "ref_user" and contains the ID of the user you are reffering to? So you can use unique IDs in both tables.
Make a query like:
SELECT * FROM hostNames WHERE ref_user = (SELECT id FROM userTable WHERE <uniqueColumn> = <uniqueIdentifierOfUser>);
But the included request must return only one line from users.
try adding mysqli $link as a parameter in your mysqli_insert_id
$last_id = mysqli_insert_id($link);
i presume you have this somewhere in your code
$link = mysqli_connect("localhost", "mysql_user", "mysql_password", "mysql_db");
if this doesn't work, try using mysql LAST_INSERT_ID() function
$last_id = $mysqli->query("SELECT LAST_INSERT_ID() AS last_id")->fetch_object()->last_id;

INSERT INTO two different tables, but have the same ID?

I have a database of Users and another table for Teachers. Teachers have all the properties as a user but also an e-mail address. When inserting into the DB how can I insert the info, ensuring that the ID is the same for both?
the ID currently is on automatic incrament.
this is what I have at the moment:
$sqlQuery="INSERT INTO user(firstName,lastName,DOB,title,password,classRoomID)
VALUES('$myFirstName','$myLastName','$myDOB','$myTitle','$newPassword','$myClassRoom')";
$result=mysql_query($sqlQuery);
$sqlQuery = "INSERT INTO teacher(email) VALUES ('$myEmail')";
$result=mysql_query($sqlQuery);
thank you!
use MYSQL function LAST_INSERT_ID()
OR php mysql http://ro1.php.net/manual/en/function.mysql-insert-id.php
why to use separate table for teachers. instead, you can have email field with in user table and additional field with flag (T ( for teacher) and U (for user). Default can be a U. This have following Pros.
Will Not increase table size as email would be varchar
Remove extra overhead of maintaining two tables.
Same Id can be used
If you want to have that as separate table then answer you selected is good one but make sure last insert id is called in same connection call.
After the first insert, fetch the last inserted id:
$last_id = mysqli_insert_id(); // or mysql_insert_id() if you're using old code
Or you could expand your second query and use mysql's integrated LAST_INSERT_ID() function:
$sqlQuery = "INSERT INTO teacher(id, email) VALUES ((SELECT LAST_INSERT_ID()), '$myEmail')";
Try this:
$sqlQuery="INSERT INTO user(firstName,lastName,DOB,title,password,classRoomID)
VALUES('$myFirstName','$myLastName','$myDOB','$myTitle','$newPassword','$myClassRoom')";
$result=mysql_query($sqlQuery);
$id = mysql_insert_id();
$sqlQuery = "INSERT INTO teacher(id, email) VALUES (' $id ','$myEmail')";
$result=mysql_query($sqlQuery);
Insert data into two tables & using the same ID
First method
$sqlQuery1 = "INSERT INTO user(firstName,lastName,DOB,title,password,classRoomID) VALUES('$myFirstName','$myLastName','$myDOB','$myTitle','$newPassword','$myClassRoom')";
$result1 = mysqli_query($conn, $sqlQuery1);
$lastID = mysqli_insert_id($conn);
$sqlQuery2 = "INSERT INTO teacher(email, lastID) VALUES ('$myEmail', 'lastID')";
$result2 = mysqli_query($conn, $sqlQuery2);
If the first method not work then this is the second method for you
$sqlQuery1 = "INSERT INTO user(firstName,lastName,DOB,title,password,classRoomID) VALUES('$myFirstName','$myLastName','$myDOB','$myTitle','$newPassword','$myClassRoom')";
$result1 = mysqli_query($sqlQuery1);
$sqlQuery2 = "INSERT INTO teacher(email) VALUES ('$myEmail')";
$result2 = mysqli_query($sqlQuery2);
You can set the Foreign Key in your database table (phpMyAdmin/ MySQL Workbench) to let the Foreign Key follow the Primary Key (ID). Then the data after insert will auto-follow the Primary Key ID.
Example here,
Teachers table set ID - Primary Key
Users table set UserID - Foreign Key (will follow the Teachers table ID)
if you're using MySQL WorkBench, you can refer to this link to set a foreign key.
https://dev.mysql.com/doc/workbench/en/wb-table-editor-foreign-keys-tab.html
Hope I can help any of you.
Though you can use the LAST_INSERT_ID() function in order to get the last insert id, the best approach in this case is to create a column reference to user id table.
teacher
id | user_id | email
So the teacher.id could be anyting, but the user_id column is the real reference to user table.
If you use InnoDB table, you can make the database consistent using Foreign keys
You Should Use A Transaction In MySQL. First insert In One Table And GET LAST_INSERT_ID().
Insert LAST_INSERT_ID() In Second Table.
$sqlQuery="INSERT INTO user(firstName,lastName,DOB,title,password,classRoomID)
VALUES('$myFirstName','$myLastName','$myDOB','$myTitle','$newPassword','$myClassRoom')";
$sqlQuery = "INSERT INTO teacher(LAST_INSERT_ID(), email) VALUES (' $id ','$myEmail')";
$result=mysql_query($sqlQuery);

Insert on duplicate key update always updates all values

I'm trying to update a row or insert a new one if it exists. If there's an UPDATE I just like to update the "updated" column with the current timestamp otherwise "added" AND "updated" get the same value (timestamp)
//1385982893 is from PHP with time() cause it's needed elsewhere too
INSERT INTO table (id, code, added, updated) VALUES (236, 'abcdefghi', 1385982893, 1385982893)
ON DUPLICATE KEY UPDATE
id = values(id), code = values(code), added = values(added),updated = 1385982893
ID is the primary key. code is UNIQUE
The problem is that "added" always gets updated with the current timestamp (like updated)
You just need to to remove the added = values(added) and it won't get updated:
INSERT INTO table (id, code, added, updated) VALUES (236, 'abcdefghi', 1385982893, 1385982893)
ON DUPLICATE KEY UPDATE
id = values(id), code = values(code),updated = 1385982893
Then do not set added in Update
INSERT INTO table (id, code, added, updated) VALUES (236, 'abcdefghi', 1385982893, 1385982893)
ON DUPLICATE KEY UPDATE
id = values(id), code = values(code), updated = 1385982893

PHP/MySQL INSERT feature logic error

I recently asked a question about writing to multiple tables: PHP/MySQL insert into multiple data tables on submit
I have now tried out this code and there are no errors produced in the actual code but the results I am getting are strange. When a user clicks register this 'insert.php' page is called and the code can be found below.
<?php
$username = $_POST["username"];
$password = $_POST["password"];
$institution = $_POST["institution"];
$conn = pg_connect("database connection information"); //in reality this has been filled
$result = pg_query($conn, "INSERT INTO institutions (i_id, name) VALUES (null, '$institution') RETURNING i_id");
$insert_row = pg_fetch_row($result);
$insti_id = $insert_row[0];
// INSTITUTION SAVED AND HAS ITS OWN ID BUT NO MEMBER OF STAFF ID
$resultTwo = pg_query($conn, "INSERT INTO staff VALUES (NULL, '$username', '$password', '$insti_id'");
$insert_rowTwo = pg_fetch_row($resultTwo);
$user_id = $insert_rowTwo[0];
// USER SAVED WITH OWN ID AND COMPANY ID
// ASSIGN AN INSTITUTION TO A STAFF MEMBER IF THE STAFF'S $company_id MATCHES THAT OF THE
// INSTITUION IN QUESTION
$update = pg_query($conn, "UPDATE institutions SET u_id = '$user_id' WHERE i_id = '$insti_id'");
pg_close($conn);
?>
What the result of this is just the browser waiting for a server response but there it just constantly waits. Almost like an infinite loop I'm assuming. There are no current errors produced so I think it may be down to a logic error. Any ideas?
The errors:
RETURNING clause is missing in the second INSERT statement.
Provide an explicit list of columns for your second INSERT statement, too.
Don't supply NULL in the INSERT statements if you want the column default (serial columns?) to kick in. Use the keyword DEFAULT or just don't mention the column at all.
The better solution:
Use data-moidifying CTE, available since PostgreSQL 9.1 to do it all in one statement and save a overhead and round trips to the server. (MySQL knows nothing of the sort, not even plain CTEs).
Also, skip the UPDATE by re-modelling the logic. Retrieve one id with nextval(), and make do with just two INSERT statements.
Assuming this data model (you should have supplied that in your question):
CREATE TABLE institutions(i_id serial, name text, u_id int);
CREATE TABLE staff(user_id serial, username text, password text, i_id int);
This one query does it all:
WITH x AS (
INSERT INTO staff(username, password, i_id) -- provide column list
VALUES ('$username', '$password', nextval('institutions_i_id_seq'))
RETURNING user_id, i_id
)
INSERT INTO institutions (i_id, u_id, name)
SELECT x.i_id, x.user_id, '$institution'
FROM x
RETURNING u_id, i_id; -- if you need the values back, else you are done
Data model
You might think about changing your data model to a classical n:m relationship.
Would include these tables and primary keys:
staff (u_id serial PRIMARY KEY, ...)
institution (i_id serial PRIMARY KEY, ...)
institution_staff (i_id, u_id, ..., PRIMARY KEY(i_id, u_id)) -- implements n:m
You can always define institution_staff.i_id UNIQUE, if a user can only belong to one institution.

Insert new row in a table and auto id number

I want to insert a new row in my table. I want the id to be generated right automatically and not asked from the user. The user only provides title and text. I wrote this code in PHP:
<?php
$hostname = "localhost";
$database = "mydb";
$username = "myuser";
$password = "mypsw";
$link = mysql_connect( $hostname , $username , $password ) or
die("Attention! Problem with the connection : " . mysql_error());
if (!$link)
{
die('Could not connect: ' . mysql_error());
}
mysql_query("SET NAMES ‘utf8’",$link);
mysql_select_db("mydb", $link);
$lastid=mysql_insert_id();
$lastid=$lastid+1;
$sql="INSERT INTO announcements VALUES ('$lastid',CURDATE(),'$_POST[title]','$_POST[text]')";
if (!mysql_query($sql,$link))
{
die('Error: ' . mysql_error());
}
mysql_close($link);
header("Location: announcement.php");
?>
Sadly when I test it on my website, I get this error:
Error: Duplicate entry '0' for key 'PRIMARY'
Is mysql_insert_id() not working? What is wrong?
Don't do this. mysql will happily create an auto_increment column for you:
CREATE TABLE x (
id int not null primary key auto_increment
^^^^^^^^^^^^^^---add this to your PK field
);
INSERT INTO x (id) VALUES (null); // creates id = 1
INSERT INTO x (id) VALUES (null); // creates id = 2
mysql_insert_id() only returns the last id created by the CURRENT connection. You haven't inserted any data yet when you first run it, so you get back nothing.
Your version is incredibly vulnerable to race conditions. There is NO guarantee that the last ID you retrieve with mysql_insert_id() will not ALSO get retrieved by another copy of the script running in parallel, and get sniped out from under this copy of the script.
The primary key column on announcements should be auto_increment. When you do mysql_insert_id() it retrieves the id from the last query executed from that connection.
Because the INSERT is the query you are currently performing, it errors.
Try
INSERT INTO announcements
(date_field, title, text)
VALUES (CURDATE(),'$_POST[title]','$_POST[text]')
Just replace 'date_field', 'title', and 'text' with the applicable column names.
Alternatively the following should also work, as a NULL value in the AutoIncrement value should be acceptable
INSERT INTO announcements VALUES (NULL,CURDATE(),'$_POST[title]','$_POST[text]')
As mentioned in the other suggestion posted, you should make sure that the primary key field of the announcements table is set to be auto_increment.
Just for completion, you would use mysql_insert_id() when you want to use the id for the row you just inserted, i.e. if you then want to select the row you just inserted you could do
'SELECT * FROM announcements WHERE id = '.mysql_insert_id()
The problem is that you are asking for last insert id and you didn't inserted anything.
Convert your ID field in db to be autoincrement if its not.
Insert into database your announcment
Then ask for id using mysql_insert_id to get it.
But I see that you are not using it only when inserting then you don't need that functionality anyhow. Just insert without ID like this
"insert into announcements (InsertDate, Title, Text) VALUES (CURDATE(), '$_POST[title]', '$_POST[text]')";
and you should really be careful with your queries when using values from $_POST or $_GET or any other user typed value. There is possibility to execute SQLInjection through your form fields, so I suggest you to use mysql escape command or use parameters.
I hope this helps.
Assuming your table is set up properly, with the id field as AUTO_INCREMENT, you just need to perform an INSERT where you do not specify a value for id. That means you must specify the names of the columns you are inserting. So this line:
$sql="INSERT INTO announcements VALUES ('$lastid',CURDATE(),'$_POST[title]','$_POST[text]')";
becomes this
$sql="INSERT INTO announcements (`date`,`title`,`text`) VALUES (CURDATE(),'$_POST[title]','$_POST[text]')";
I guessed what your column names might be. Obviously they need to match your table definition.
If you do this, then the mysql_insert_id() function will return the id of the row you just inserted. (That is, it gives you the value of the previous insert, not the next one.)
You probably want to add "auto increment" to the table when creating it.
This will add an id automatically when inserting something.
e.g.
CREATE TABLE announcements
(
id int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
some_date int(11),
title varchar(200),
text varchar(3000)
);
mysql_insert_id "Retrieves the ID generated for an AUTO_INCREMENT column by the previous query " - http://php.net/manual/en/function.mysql-insert-id.php

Categories