Need to insert SQL without duplicates - php

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

Related

Why am I getting an SQL error when trying to insert a null?

Ok when trying to execute the following insert I'm getting an 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 '2, 3, 4, 5)' at line 1
$insertSQL = sprintf("INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2) VALUES (%s, %s, %s, %s, %s, %s)",
$passport_file,
$address_file,
$photo_file,
$transcript_file,
$essay1_file,
$essay2_file);
mysqli_select_db($STCi, $database_STC);
$Result1 = mysqli_query($STCi, $insertSQL) or die(mysql_error($STCi));
Those variables are being set using the following code
$_FILES['id_file']['error'] == UPLOAD_ERR_OK?$passport_file=filesDB('id_file'):$passport_file = NULL;
$_FILES['address_file']['error'] == UPLOAD_ERR_OK?$address_file = filesDB('address_file'):$address_file = NULL;
$_FILES['photo']['error'] == UPLOAD_ERR_OK?$photo_file = filesDB('photo'):$photo_file = NULL;
$_FILES['transcript']['error'] == UPLOAD_ERR_OK?$transcript_file = filesDB('transcript'):$transcript_file = NULL;
$_FILES['essay1']['error'] == UPLOAD_ERR_OK?$essay1_file = filesDB('essay1'):$essay1_file = NULL;
$_FILES['essay2']['error'] == UPLOAD_ERR_OK?$essay2_file = filesDB('essay2'):$essay2_file = NULL;
filesDB is my own function I'm running to rename the uploaded files and move them into the correct locations and any that are running through that are fine. The problem comes out with 'address_file' as it is an optional file and whenever nothing is uploaded for it I get the error.
So basically MySQL is throwing an error when I'm trying to insert NULL, or am I missing something obvious?
CREATE TABLE `applicants` (
`applicant_id` int(11) NOT NULL AUTO_INCREMENT,
`id_file` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`address_file` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`photo` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`name_change` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`transcript` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`english_result` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`essay1` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`essay2` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`stage` varchar(20) DEFAULT 'New',
`date_applied` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`applicant_id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
use a prepared stamement instead of manually creating a query with sprintf:
if ($stmt = mysqli_prepare($STCi, "INSERT INTO applicants
(id_file, address_file, photo, transcript, essay1, essay2)
VALUES (?, ?, ?, ?, ?, ?)"))
{
mysqli_stmt_bind_param($stmt, "ssssss",
$passport_file,
$address_file,
$photo_file,
$transcript_file,
$essay1_file,
$essay2_file);
mysqli_stmt_execute($stmt) or die(mysql_error($STCi));;
}
You're doing an sprintf, and inserting 'NULL', meaning you have a PHP varaible that is NULL.
Your SQL query should look like this after the sprintf:
INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2)
VALUES (null, 2,3,4,5,6)"
but it looks like this:
INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2)
VALUES ( , 2,3,4,5,6)"
And that's an error.
To fix this, you could actually insert the string null here (if you insert it without ', it will not be seen as a string, as you are not using prepared statements). So you query would look like so:
INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2)
VALUES ( null , 2,3,4,5,6)"
Do this by not assiging NULL to the variable, but just assign 'null'. Verify by first echoing your query. It should have the null in it wihtout any quotes.
A better method is to use actual prepared statements: http://php.net/manual/en/mysqli.prepare.php
I think you are confusing the php null value and the mysql null value - they arent the same thing. I think you want something like:
$_FILES['id_file']['error'] == UPLOAD_ERR_OK?$passport_file=filesDB('id_file'):$passport_file = 'NULL';
Note I have quoted the "null". This will put a text null into the sql statement, which will then be interpreted as the keyword 'null' in mysql.
If you leave the php assignment as the value null then a sort of blanky thing is passed to mysql, when it wants the text string 'null' :)
in order to insert null values you should be using prepared statements
$stmt = $STCi->prepare("INSERT INTO applicants (id_file, address_file, photo, transcript, essay1, essay2) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param("ssssss",
$passport_file,
$address_file,
$photo_file,
$transcript_file,
$essay1_file,
$essay2_file);
$stmt->execute();

Mysql Create Table If Not Exists else.... Information Schema

Quick one hopefully - not sure where I'm going wrong here but this doesn't seem to work full stop.
Running MySQL query through PHP...
Current code
$uu = mysql_query("
IF EXISTS(SELECT table_name FROM information_schema.tables
WHERE table_schema = 'schema_example' AND table_name = 'test_q')
THEN
insert into `test_q` (code, va_desc, price, category)
values ('$code', '$desc', '$price', '$categ')
on duplicate key update va_desc='$desc', price='$price', category='$categ'
ELSE
CREATE TABLE `test_quote` (
`code` varchar(30) NOT NULL,
`va_desc` text NOT NULL,
`price` text NOT NULL,
`category` text NOT NULL,
PRIMARY KEY (`code`),
UNIQUE KEY `id` (`code`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
insert into `test_q` (code, va_desc, price, category)
values ('$code', '$desc', '$price', '$categ')
END IF;
")or die(mysql_error());
Really appreciate some help on what I need to change, at the moment this does absolutely nothing and doesn't return any specific errors. :/
Having said that if I run it in phpMyAdmin it returns the following (although I can't understand why):
#1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MariaDB server
version for the right syntax to use near
'ELSE CREATE TABLE `test_quote`(
`code` varchar(30) NOT NULL,
`va_desc` text NO' at line 7
You don't need to query INFORMATION_SCHEMA. You can use the IF NOT EXISTS option to CREATE TABLE.
mysql_query("CREATE TABLE IF NOT EXISTS `test_q` (
`code` varchar(30) NOT NULL,
`va_desc` text NOT NULL,
`price` text NOT NULL,
`category` text NOT NULL,
PRIMARY KEY (`code`),
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1");
mysql_query("insert into `test_q` (code, va_desc, price, category)
values ('$code', '$desc', '$price', '$categ')
on duplicate key update va_desc='$desc', price='$price', category='$categ'");
Also, a primary key is a unique key, you don't need to specify them both when you create the table.
Trying using the following query as if, else and then statements are not supported in the sql query, for that you can stored procedures.
mysql_query("CREATE TABLE IF NOT EXISTS `test_q` (`code` varchar(30) NOT NULL,
`va_desc` text NOT NULL,
`price` text NOT NULL,
`category` text NOT NULL,
PRIMARY KEY (`code`),
);
mysql_query("insert into `test_q` (code, va_desc, price, category)
values ('$code', '$desc', '$price', '$categ')
on duplicate key update va_desc='$desc', price='$price', category='$categ'");

MySQL - Update a record and maintain referential integrity

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

Unique "Value" Issue with MySQL database

I am having a small and annoying issue with my MySQL database.
I have a field StudentID that is supposed to be unique for each user but is not mandatory.
So when the user registers and doesn't want to add a studentID - he leaves the field blank. However when a 2nd user leaves the field blank - it counts it as a duplicate value.
Is there any way to fix this ?I tried several methods posted below :
Mysql Error : 1062 - Duplicate entry '' for key
'users_studentid_unique'
1st time (works) :
insert into `users` (`username`, `name`, `email`, `studentid`,
`password`, `updated_at`, `created_at`)
values ('aaaaaa263', 'aaaaaa', 'aaaaaa23d#gmail.com','' ,
'yZPeKRV0C0xbr/QCI1w/Y.0Z1qSGnJeivgP71epaHpT139g65hAf2',
'2014-03-20 18:16:54', '2014-03-20 18:16:54')
2nd time (Duplicate value error for studentid) :
insert into `users` (`username`, `name`, `email`, `studentid`,
`password`, `updated_at`, `created_at`)
values ('aaaaaa263', 'aaaaaa', 'aaaaaa23d#gmail.com','' ,
'yZPeKRV0C0xbr/QCI1w/Y.0Z1qSGnJeivgP71epaHpT139g65hAf2',
'2014-03-20 18:16:54', '2014-03-20 18:16:54')
Tried :
Checking the NULL value on the studentid table in the database.
Tried inserting into the db using these values instead of the blank field :
NULL
null
UNDEFINED
Still having the same issue though, - Does anyone have any idea how to fix this problem?
Use a NULL value, that's not considered to be a "duplicate" in a unique index. But the column has to allow NULL values, that is, it cannot be defined as NOT NULL.
To insert a NULL value, use the keyword NULL keyword. Note that this is different than the character string 'NULL'
INSERT INTO mytab (a, b) VALUES (NULL, 'NULL')
Column a is assigned the special NULL value. Column b is assigned a character string.
Also, omitting the column from the INSERT list will cause the default value to be assigned to the column. The default value for a column is NULL, unless you've set the default to be something else.
This statement is equivalent to the statement above, in that column a will be assigned the default value defined for column a, which is
INSERT INTO mytab (b) VALUES ('NULL')
The other option is to use an expression to generate the NULL value for you, in the place of the empty string.
Given a description of your current logic, if the user_id column allows for NULL values, then you could translate the empty string to NULL
insert into `users` (`username`, `name`, `email`, `studentid`,
`password`, `updated_at`, `created_at`)
values ( ?, ?, ?, NULLIF( ? ,''), ?, ?, ?)
The NULLIF(x,y) function is shorthand for IF x = y THEN NULL ELSE x END.
You can set the student id to a timestamp if it's null, then check if its numeric to see if it's really set or not.
<?php
$student_id = is_null($student_id) ? time() : $student_id;
Your request :
insert into `users` (`username`, `name`, `email`, `studentid`,
`password`, `updated_at`, `created_at`)
values ('aaaaaa263', 'aaaaaa', 'aaaaaa23d#gmail.com','$student_id' ,
'yZPeKRV0C0xbr/QCI1w/Y.0Z1qSGnJeivgP71epaHpT139g65hAf2',
'2014-03-20 18:16:54', '2014-03-20 18:16:54')
Then to get the users back :
SELECT *, if(concat('','student_id' * 1) = 'student_id', 0, 1) as is_student_id_valid from ...
Then is_studient_id_valid field will tell you if this id is valid or not.
I have tried to recreate your problem. Alas, it works fine here.
However, i supply all the information so that you can at least check where your setup is different.
Create table statement: Please check all of: the Mysql Version, the table engine, the primary key and the index on the 'studentid' column.
/*
SQLyog Community v10.2
MySQL - 5.5.16 : Database - testmysql
*********************************************************************
*/
/*Table structure for table `users` */
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`username` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`studentid` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
`password` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`username`),
UNIQUE KEY `studentid_uidx` (`studentid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Typical insert with a null studentid...
INSERT INTO `users` (`username`, `name`, `email`, `studentid`,
`password`, `updated_at`, `created_at`)
VALUES ('aaaaaa004', 'aaaaaa', 'aaaaaa23d#gmail.com', NULL,
'yZPeKRV0C0xbr/QCI1w/Y.0Z1qSGnJeivgP71epaHpT139g65hAf2',
'2014-03-20 18:16:54', '2014-03-20 18:16:54')
query result
username name email studentid password created_at updated_at
aaaaaa001 aaaaaa aaaaaa23d#gmail.com (NULL) yZPeKRV0C0xbr/QCI1w/Y.0Z1qSGnJeivgP71epaHpT139g65hAf2 2014-03-20 18:16:54 2014-03-20 18:16:54
aaaaaa002 aaaaaa aaaaaa23d#gmail.com (NULL) yZPeKRV0C0xbr/QCI1w/Y.0Z1qSGnJeivgP71epaHpT139g65hAf2 2014-03-20 18:16:54 2014-03-20 18:16:54
aaaaaa003 aaaaaa aaaaaa23d#gmail.com stid01 yZPeKRV0C0xbr/QCI1w/Y.0Z1qSGnJeivgP71epaHpT139g65hAf2 2014-03-20 18:16:54 2014-03-20 18:16:54
aaaaaa004 aaaaaa aaaaaa23d#gmail.com (NULL) yZPeKRV0C0xbr/QCI1w/Y.0Z1qSGnJeivgP71epaHpT139g65hAf2 2014-03-20 18:16:54 2014-03-20 18:16:54

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.

Categories