MySQL - Update a record and maintain referential integrity - php

I'm working in MySQL 5.5.
I've got a Contacts table like this
CREATE TABLE Contacts
(
ID INTEGER NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT,
Name VARCHAR(255) NOT NULL,
Institution VARCHAR(255),
Address VARCHAR(255),
Email VARCHAR(255) NOT NULL UNIQUE,
Phone VARCHAR(10)
);
and an Inventories tables like this
CREATE TABLE Inventories
(
ID INTEGER NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT,
InventoryParametersID INTEGER NOT NULL UNIQUE,
ContactID INTEGER NOT NULL,
LocationID INTEGER NOT NULL,
Year INTEGER,
DateUploaded TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
Comments VARCHAR(255),
FOREIGN KEY (ContactID) REFERENCES Contacts(ID)
);
In my webform, contacts upload inventories. Here's the behavior I want:
- When a new contact uploads an inventory, do an insert with their new info
- When an existing contact (determined by email address) uploads another inventory, update their info AND retain referential integrity with the Inventories table
How do I do this?
Here's what I've tried:
CASE
FOREIGN KEY (ContactID) REFERENCES Contacts(ID)
REPLACE INTO Contacts (`Name`, `Institution`, `Address`, `Email`, `Phone`) VALUES (?, ?, ?, ?, ?);
RESULT
No change
CASE
FOREIGN KEY (ContactID) REFERENCES Contacts(ID)
ON UPDATE CASCADE
REPLACE INTO Contacts (`Name`, `Institution`, `Address`, `Email`, `Phone`) VALUES (?, ?, ?, ?, ?);
RESULT
No change

A REPLACE deletes find row and add a new. So your ON UPDATE CASCADE doesn't work. Why do you not use an INSERT ... ON DUPLICATE KEY UPDATE?
INSERT INTO Contacts (Name, Institution, Address, Email, Phone)
VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE
Name = VALUES(NAME),
Institution = VALUES(Institution) ...
MySQL DOC

Related

How to automatical add data to a table with a foreign key php [MariaDB]

How can I use php to add data to the foreign such that the IDs match:
In this example, I have a table for a 'member' and a separate table for 'emails'. A member can have multiple emails and therefore a separate table is created that stores emails with the member ID as a foreign key.
How can I write code that inserts data into both tables when fields have been submitted?
My most recent (unsuccessful) attempt:
PHP block:
$query=
"INSERT INTO Members(FIRST_NAME, LAST_NAME, TITLE, INSTITUTION) VALUES ('$first_name',
'$last_name','$title','$institution');
INSERT INTO EMAIL(Members_ID, EMAIL) VALUES
(LAST_INSERT_ID(), '$email');
INSERT INTO WEBSITE(Members_ID, WEBSITE) VALUES
(LAST_INSERT_ID(), '$website');";
mysqli_query($connection,$query) or die(mysqli_error($connection));
SQL Block:
CREATE TABLE Members(
ID INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
FIRST_NAME TEXT(16),
LAST_NAME TEXT(16,
TITLE TEXT(7), /** 7 CHARS for 'Student'*/
INSTITUTION VARCHAR(2048),
PRIMARY KEY(ID)
);
CREATE TABLE EMAIL(
Members_ID INT UNSIGNED NOT NULL UNIQUE,
EMAIL VARCHAR(2048),
FOREIGN KEY (Members_ID) REFERENCES Members(ID)
);
CREATE TABLE WEBSITE(
Members_ID INT UNSIGNED NOT NULL UNIQUE,
WEBSITE VARCHAR(2048),
FOREIGN KEY (Members_ID) REFERENCES Members(ID)
);
You could use, for example mysqli_multi_query, after having retrieved the ID assigned to the first insertion (I wouldn't rely too much on the LAST_INSERT_ID() in this case):
$conn = mysqli_connect(...);
$query = "INSERT INTO Members (FIRST_NAME,LAST_NAME,TITLE,INSTITUTION) VALUES ('$first_name','$last_name','$title','$institution')";
mysqli_query($conn, $query);
$lid = mysqli_insert_id($conn);
$query = "INSERT INTO EMAIL (Members_ID,EMAIL) VALUES ($lid,'$email');";
$query .= "INSERT INTO WEBSITE (Members_ID,WEBSITE) VALUES ($lid,'$website');";
mysqli_multi_query($conn, $query);

INSERT... ON DUPLICATE KEY UPDATE issue

I am having a mysql table named company_profile. It may have only one record. So I tried to insert and update data of the table using INSERT.... ON DUPLICATE KEY UPDATE query.
This is how I tried it:
$sql = "INSERT INTO company_profile (
company_name
, tel
, mobile
, fax
, email
) VALUES (?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
company_name= VALUES(company_name)
, tel = VALUES(tel)
, mobile = VALUES(mobile)
, fax = VALUES(fax)
, email = VALUES(email)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('sssss', $company_name
, $telephone
, $mobile
, $fax
, $email
);
$stmt->execute();
My problem is when I updating the data, it always inserting a new record into my table.
Can anybody tell me what would be the problem of this?
My table structure looks like this:
CREATE TABLE IF NOT EXISTS company_profile (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
company_name VARCHAR(120) NOT NULL,
tel VARCHAR(20) NOT NULL,
mobile VARCHAR(20) NOT NULL,
fax VARCHAR(20) DEFAULT NULL,
email VARCHAR(60) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
First, it is redundant to define a key as being both unique and primary key. Just define id to be primary key.
Then, you need a unique constraint/index on the columns used for duplication (the two are functionally equivalent for this purpose). I am guessing uniqueness is based on the company name:
create unique index unq_company_profile_company_name on company_profile(company_name);

DUPLICATE KEY UPDATE in PRO Prepaid Statement

I'm using PDO to handle (MYSQL)Database.When i save the result this SQL didn't update the column values it will create a new line with new saving values.What is the mistake i done.Is there anyone can help me to understand this behavior with PDO
$SQL =<<<'EOD'
CREATE TABLE IF NOT EXISTS pard_admin_config(
title varchar(255) NOT NULL,
online varchar(100),
offline varchar(100),
email varchar(100),
metades varchar(200),
metakey varchar(200),
copyright varchar(200),
pard_host varchar(100),
pard_database varchar(100),
username varchar(100),
password varchar(100)
)
EOD;
$pardConfig->query($SQL);
$stmt = $pardConfig->prepare("INSERT INTO pard_admin_config (title, online, offline, email, metades, metakey, copyright, pard_host, pard_database, username, password) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
title='?', online='?', offline='?', email='?', metades='?', metakey='?', copyright='?', pard_host='?', pard_database='?', username='?', password='?'");
$ConfigData = array($adminConfig->TITLE,
$adminConfig->ONLINE,
$adminConfig->OFFLINE,
$adminConfig->EMAIL,
$adminConfig->METADESCRIPTION,
$adminConfig->METAKEYWORDS,
$adminConfig->COPYRIGHT,
$adminConfig->HOST,
$adminConfig->DATABASE,
$adminConfig->USERNAME,
$adminConfig->PASSWORD);
$stmt->execute($ConfigData);
this is not PDO behavior, but mysql
You need to specify either the same values twice, or use values() function
ON DUPLICATE KEY UPDATE
title= values(title), online=values(online), and so on
also note that placing placeholders in quotes makes no sense.

Cannot insert into table - Foreign key constraint issue in mysql

I have two tables main_jobs and sub_jobs with the structures below:
$query="create table if not exists main_jobs (
id int not null auto_increment, primary key(id),
industry int(3),
company_name varchar(255),
job_title varchar(255),
email varchar(255),
website varchar(255),
introduction text not null,
application_details text,
advert_date date,
expiry_date date,
upload_date date,
no_deadline int(1) default 0,
logo varchar(255),
featured varchar(20),
source varchar(10) default 'admin',
email_status int default 0,
views int(11) default 1,
short_url varchar(100),
tags varchar(255),
FOREIGN KEY (industry) REFERENCES industry (id))";
if(mysql_query($query,$link)){echo "main_jobs created<br>";} else{ die(mysql_error()); }
$query="create table if not exists sub_jobs (
id int not null auto_increment, primary key(id),
parent_id int(11) not null, FOREIGN KEY (parent_id) REFERENCES main_jobs (id),
title varchar(255),
description text not null,
category int (3), FOREIGN KEY (category) REFERENCES category (id),
job_type varchar(20),
job_level varchar(50),
min_qualification varchar(50),
min_experience int(3),
max_experience int(3),
min_salary int(11),
max_salary int(11),
show_salary int(1) default 1,
denomination varchar(10),
views int(11) default 1,
short_url varchar(100),
email varchar(255),
website varchar(255))";
if(mysql_query($query,$link)){echo "sub_jobs created<br>";} else{ die(mysql_error()); }
I want to insert records but it shows up this error:
Cannot add or update a child row: a foreign key constraint fails (`myjobmag_db`.`sub_jobs`, CONSTRAINT `sub_jobs_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `main_jobs` (`id`))
These are mysql queries and have been staring at them for hours but cannot identify the problem:
Insert into main_jobs (Runs successfully)
$resultobj=otherquery("insert into main_jobs(industry, company_name, job_title, email, website, introduction, application_details, advert_date, expiry_date, upload_date, no_deadline, logo) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", "ssssssssssss", array($industry, $company_name, $job_name, $email, $website, $profile, $application, $advert_date, $expiry_date, $date_uploaded, $no_deadline, $logo));
I pick the id of the last insert (confirms that it exists in main_jobs table, this is do manually because of the error) and run insert into sub_jobs
$parent= $resultobj['obj']->insert_id;
mysql_query("insert into sub_jobs(id, parent_id, title, description, category, job_type, job_level, min_qualification, min_experience, max_experience, min_salary, max_salary, show_salary, denomination, email, website) values('', $parent, '$subtitle', '$description', '$category', '$type', '$level', '$min_qualification', '$min_experience', '$max_experience', '$min_salary', '$max_salary', '$show_salary', '$denomination', '$sub_email', '$sub_website')", $link) or die(mysql_error($link));
In my last test the id in main_jobs table is 2616 and it actually exists, yet i get an error.
Kindly assist!

Need to insert SQL without duplicates

The table is currently this:
CREATE TABLE `feed_items` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`feed_id` int(11) NOT NULL,
`remote_id` varchar(32) NOT NULL DEFAULT '',
`title` varchar(255) NOT NULL DEFAULT '',
`link` varchar(255) NOT NULL DEFAULT '',
`updated_time` datetime NOT NULL,
`created_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
I need to find a way so that if i pull multiple RSS feeds into one table, and articles with the same Title have the same value of 'remote_id', how can i make sure I do not insert a duplicate value?
I am currently using
$this->db->query('INSERT INTO feed_items(feed_id, remote_id, link, title, created_time, updated_time) VALUES (?, ?, ?, ?, ?, NOW()) ON DUPLICATE KEY UPDATE remote_id=remote_id', array($this->feed_id, $this->remote_id, $this->link, $this->title, $this->created_time, $this->remote_id));
I was wondering if there is a better way?
Add a UNIQUE constraint to those two columns.
ALTER TABLE `feed_items` ADD UNIQUE INDEX `constraint` (`link`, `remote_id`);
You can use ON DUPLICATE for avoiding such conditions: Check: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Hope it helps
Try this:
$this->db->query('INSERT INTO feed_items(feed_id, remote_id, link, title, created_time, updated_time) SELECT ?, ?, ?, ?, ?, NOW() WHERE not exists(SELECT 1 FROM feed_items f2 WHERE f2.title = ? and f2.remote_id = ?)', array($this->feed_id, $this->remote_id, $this->link, $this->title, $this->created_time, $this->title, $this->remote_id));
Just to clarify - this solution changes the insert into ... values statement to an insert into...select statement, with a not exists() clause attached. This not exists clause will prevent the insert from doing anything if it finds a record that matches one that is already present. It won't throw an error if there is a pre-existing record.
Thanks for the replies!
I actually managed to solve it a few hours after posting this, I made the remote_id a unique column and then did the following for the SQL
INSERT INTO feed_items(feed_id, remote_id, link, title, created_time, updated_time) VALUES (?, ?, ?, ?, ?, NOW()) ON DUPLICATE KEY UPDATE remote_id=remote_id

Categories