Database INSERT INTO error - php

I was trying to find out what was wrong with my code.
This is the error I'm recieving
"Cannot add or update a child row: a foreign key constraint fails "
This is my code
<?php
$sql = "INSERT INTO stasjon (navn) VALUES ('skogen', 'voksenlia') ";
$resultat = $kobling->query ($sql);
$sql ="SELECT * FROM stasjon WHERE navn = ('skogen')";
$resultat = $kobling->query ($sql);
while ($rad = $resultat->fetch_assoc()) {
$stasjon_id = $rad['stasjon_id'];
}
$sql = "INSERT INTO linjestasjon (linje_nr, stasjon_id) VALUES ('1','$stasjon_id')";
$resultat = $kobling->query ($sql);
if($kobling->query($sql)) {
echo "Spoerringen $sql ble gjennomfoert.";
} else {
echo "Noe gikk galt med spoerringen $sql ($kobling->error).";
?>
Some of it is in Norwegian because That's the language of the database I'm making. I was trying to add values to two different tables (that had stasjon_id as a foreign key) Thanks in advance

Foreign Key constraints checks in the value that you are inserting or updating to a particular filed exists in some other filed of another table. Suppose I have 2 tables as follows
CREATE TABLE TableA
(
SeqNo INT PRIMARY KEY,
Name VARCHAR(500
)
CREATE TABLE TableB
(
SeqNo INT NULL FOREIGN KEY REFERENCES TableA(SeqNo),
Name VARCHAR(50)
)
So when you insert a new record to the Tableb.SeqNo filed, The value should either be NULL or some value that exists in the TableA.SeqNo.
So Before inserting the values make sure that you are inserting the value that satisfy your foreign key constraint

Related

Insert values from 1 form into 2 sql server tables (PHP) (SQL-Server)

I want to use one form to insert into two different Microsoft sql tables. I tryed to use 2 inserts, but didnt work.
if (isset($_GET['submit'])) {
$sth = $connection->prepare("INSERT INTO DB.dbo.Fehler (QualiID, TestaufstellungID, ModulinfoID, failAfter, Datum, Verbleib, DUTNr) VALUES ($QualiID, $TestaufstellungID,$ModulinfoID,'$failAfter','$Datum','$Verbleib','$DUTNr')");
echo "INSERT INTO DB.dbo.Fehler (QualiID, TestaufstellungID, ModulinfoID, failAfter, Datum, Verbleib, DUTNr) VALUES ($QualiID, $TestaufstellungID,$ModulinfoID,'$failAfter',$Datum,'$Verbleib','$DUTNr')";
$sth->execute();
if($sth)
{
echo "";
}
else
{
echo sqlsrv_errors();
}
$MID = $connection->prepare("MAX(MID) as MID FROM DB.dbo.Fehler WHERE DB.dbo.Fehler.TestaufstellungID = '". $TestaufstellungID . "'");
$MID->execute();
$sth2 = $connection->prepare("INSERT INTO DB.dbo.Fehlerinfo (MID, Tester, Test, Ausfallbedingungen, Fehlerbeschreibung, Ersteller) VALUES ($MID, '$Tester','$Test','$Ausfallbedingungen','$Fehlerbeschreibung','$Ersteller')");
$sth2->execute();
To understand MID is the Primary key of table Fehler and ist the foreign key in the second table Fehlerinfo
Thats why i have the select work around to get the last MID and want to save it in a variable $MID to insert it into the second table.
Is there a smarter solution possible?
As I mentioned in the comments, generally the better way is to do the insert in one batch. This is very over simplified, however, should put you in the right direction. Normally you would likely be passing the values for the Foreign Table in a Table Value Parameter (due to the Many to One relationship) and would encapsulate the entire thing in a TRY...CATCH and possibly a stored procedure.
I can't write this in PHP, as my knowledge of it is rudimentary, but this should get you on the right path to understanding:
USE Sandbox;
--Couple of sample tables
CREATE TABLE dbo.PrimaryTable (SomeID int IDENTITY(1,1),
SomeString varchar(10),
CONSTRAINT PK_PTID PRIMARY KEY NONCLUSTERED (SomeID));
CREATE TABLE dbo.ForeignTable (AnotherID int IDENTITY(1,1),
ForeignID int,
AnotherString varchar(10),
CONSTRAINT PK_FTID PRIMARY KEY NONCLUSTERED(AnotherID),
CONSTRAINT FK_FTPT FOREIGN KEY (ForeignID)
REFERENCES dbo.PrimaryTable(SomeID));
GO
--single batch example
--Declare input parameters and give some values
--These would be the values coming from your application
DECLARE #SomeString varchar(10) = 'abc',
#AnotherString varchar(10) = 'def';
--Create a temp table or variable for the output of the ID
DECLARE #ID table (ID int);
--Insert the data and get the ID at the same time:
INSERT INTO dbo.PrimaryTable (SomeString)
OUTPUT inserted.SomeID
INTO #ID
SELECT #SomeString;
--#ID now has the inserted ID(s)
--Use it to insert into the other table
INSERT INTO dbo.ForeignTable (ForeignID,AnotherString)
SELECT ID,
#AnotherString
FROM #ID;
GO
--Check the data:
SELECT *
FROM dbo.PrimaryTable PT
JOIN dbo.ForeignTable FT ON PT.SomeID = FT.ForeignID;
GO
--Clean up
DROP TABLE dbo.ForeignTable;
DROP TABLE dbo.PrimaryTable;
As i mentioned the answer how it works for me fine atm.
if (isset($_GET['submit'])) {
$failInsert = ("INSERT INTO DB.dbo.Fehler (QualiID, TestaufstellungID, ModulinfoID, failAfter, Datum, Verbleib, DUTNr) VALUES ($QualiID, $TestaufstellungID,$ModulinfoID,'$failAfter','$Datum','$Verbleib','$DUTNr')");
$failInsert .= ("INSERT INTO DB.dbo.Fehlerinfo (MID, Tester, Test, Ausfallbedingungen, Fehlerbeschreibung, Ersteller) VALUES (NULL, '$Tester','$Test','$Ausfallbedingungen','$Fehlerbeschreibung','$Ersteller')");
$failInsert .= ("UPDATE DB.dbo.Fehlerinfo SET DB.dbo.Fehlerinfo.MID = i.MID FROM (SELECT MAX(MID)as MID FROM DB.dbo.Fehler) i WHERE DB.dbo.Fehlerinfo.TestID = ( SELECT MAX(TestID) as TestID FROM DB.dbo.Fehlerinfo)");
$sth = $connection->prepare($failInsert);
$sth->execute();
}

ON DUPLICATE UPDATE not works with some row

I am using ON DUPLICATE UPDATE on my query, some of the result didn't store it. I tried all the possible way, but those still remain the same. here are the database picture.
Those NULL, is the row which didn't store successfully; the result should be 1 instead of NULL.
if($remark){
$query3 = "INSERT INTO `audit_section_remarkrecord` SET remark = '$remark', form_details_subquestion_id = '$form_details_subquestion_id', form_details_section_id = '$form_details_section_id', audit_section_no = '$audit_no' ON DUPLICATE KEY UPDATE
form_details_section_id = '$form_details_section_id' , remark = '$remark'";
$result3 = $db->query($query3);
$query4 = "UPDATE `remarkrecord_update_details` SET form_details_section_id = '$form_details_section_id', userlog = '$user_staff', ipaddress = '$ip' WHERE form_details_subquestion_id = '$form_details_subquestion_id' AND audit_section_no = '$audit_no' ";
$result4 = $db->query($query4);
}else{
}
}
Table Structure
Try changing one of your columns you are inserting value to primary key or add UNIQUE constraint to the column.
ALTER TABLE audit_section_remarkrecord ADD UNIQUE KEY (your column);
As there is currently only a unique key on the Primary Key, an auto-increment, you are going to have difficulty generating a unique key clash on an insert on duplicate key update (IODKU). Therefore, some other unique key needs to be created (even a composite), that will trigger the clash of a unique key and allow IODKU to work as expected.

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;

Check whether records exist in database

I know there are various offered solutions for this topic posted on this site, and I checked (and used) some of those solutions. Nevertheless, I can't figure out why my code below does not work, probably because I'm a starter with respect to php and sql programming ;-(
The code is supposed to add a record with 3 fields (FirstName, LastName, Age) in a table (persons), but only if the record does not already exist. Therefore a check on existing FirstName and Lastname fields is performed. But in case of existing record the condition of the if statement still seems to be true and a copy of the existing record is still inserted into the database. What do I miss?
Thanks in advance for the help.
//check whether item does not exist in database
$query ="SELECT FirstName,LastName FROM persons
WHERE FirstName='$data[1]' AND LastName='$data[2]'";
$result = mysql_query($query);
if($result && mysql_num_rows($result) > 0)
{
echo " <br> record exist";
}
else
{
$theage = (int)$data[3]; //! for conversion of integer values
$sql="INSERT INTO persons (FirstName, LastName, Age)
VALUES ('$data[1]','$data[2]','$theage')";
if (!mysqli_query($con,$sql))
{
die('Error: ' . mysqli_error($con));
}
}
You have to use {} around array values in query
$query ="SELECT FirstName,LastName FROM persons
WHERE FirstName='{$data[1]}' AND LastName='{$data[2]}'";
Also your INSERT query runs on mysqli and SELECT query runs on mysql. You have to use only 1 not both and use below code with mysqli.
$result = mysqli_query($con,$query);
if($result && mysqli_num_rows($result) > 0)
{
echo " <br> record exist";
}
May be this query will help you:
INSERT INTO persons (FirstName, LastName, Age)
SELECT * FROM (SELECT FirstName,LastName) AS tmp
WHERE NOT EXISTS (
SELECT FirstName, LastName FROM persons WHERE WHERE FirstName='$data[1]' AND LastName='$data[2]'
) LIMIT 1;
Check your connection
In first query you have used
mysql_query
then in second case at the time of insert you use
mysqli_query
From the database perspective, modify your Person table design by setting a UNIQUE KEY for the necessary fields i.e :
CREATE TABLE `Persons` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`FirstName` varchar(255) NOT NULL,
`LastName` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_FirstName_LastName` (`FirstName`,`LastName`) USING BTREE
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Do a normal insert, handle the duplicate error
[Err] 1062 - Duplicate entry 'jk-kenneth' for key 'unique_FirstName_LastName'

How can I perform many-to-many insert using MySQL an PHP?

I have a many-to-many MySQL database with three tables entry, tag, and entry_tag.
entry table has id INT AUTO_INCREMENT PRIMARY KEY, title TEXT and entry TEXT columns
tag table has id INT AUTO_INCREMENT PRMARY KEY and tag VARCHAR(15) columns
entry_tag is a mapping tables between entry and tag, and has entry_id INT and tag_id INT, entry_id and tag_id creates PRIMARY KEY.
Now, I would like to INSERT entry.title and entry.entry and related tags tag.tag to the database and respective tables. I would also like to INSERT appropriate mapping information into entry_tag table. Could anyone tell me how can I possible do it? I am using PHP. How can I get the entry.id and tag.id and link them together in the mapping table?
I have:
$sql_query = "INSERT INTO entry SET
title = '$title',
entry = '$entry'";
if (!mysqli_query($link, $sql_query)) {
$error = 'Error adding submitted entry.';
include 'includes/error.html.php';
exit();
}
$sql_query = "INSERT INTO tag SET
tag = '$tag'";
if (!mysqli_query($link, $sql_query)) {
$error = 'Error adding submitted entry.';
include 'includes/error.html.php';
exit();
}
Now, I would like to perform:
$sql_query = "INSERT INTO entry_tag SET
entry_id = '$entry.id',
tag_id = '$tag.id'";
But I stuck on getting the right $entry.id and $tag.id.
Use mysql_insert_id() to capture the ID of the last insert

Categories