Reputation: 8559
A table in my DB has the following columns: ID, campaign_id, opt_out_day The method that inserts a set of "opt-out-days" - an array of DATETIME values - is as follows:
/**
* @param Integer $campaignId
* @param Array $optOutDays Array of DATETIME values
*/
public function addCampaignOptOutDays($campaignId, $optOutDays) {
$query = "INSERT INTO `".self::$tblOptOutDays."`
(campaign_id, opt_out_day)
VALUES
(:campaign_id, :opt_out_day)";
try {
$this->connection->beginTransaction();
$query = $this->connection->prepare($query);
$query->bindParam(':campaign_id', $campaignId, \PDO::PARAM_INT);
foreach ($optOutDays as $day) {
$query->bindParam(':opt_out_day', $day, \PDO::PARAM_STR);
$query->execute();
}
$this->connection->commit();
} catch (\PDOException $e) {
$this->connection->rollback();
throw new \Models\Database\DatabaseException($e->getMessage());
}
}
How can I modify the query in order to prevent duplicating the same opt-out-day for a campaign? In other words, multiple rows with the same opt-out-day can exist in this table, as long as they have different a 'campaign-id'. Adding a unique key for the (campaign_id, opt_out_day) is not an option though, as I don't want to throw exceptions when such situations occur, I just want to not add the pair again.
Upvotes: 2
Views: 143
Reputation: 53830
As Jakub Kania commented, you could use a unique index and use INSERT IGNORE
:
With IGNORE, the row still is not inserted, but no error occurs. Ignored errors may generate warnings instead, although duplicate-key errors do not.
Then, simply check the affected rows value to see if the insert was successful.
So, other errors can still be detected, as warnings. I think INSERT ... ON DUPLICATE KEY UPDATE
is a better solution, given you add the unique index because checking warnings can be a pain.
Upvotes: 0
Reputation: 93
Try using the INSERT ... ON DUPLICATE KEY UPDATE id=id
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
This will avoid an extra SELECT query but will also avoid an error if you have duplicate keys.
There's also INSERT IGNORE ... but that might ignore other errors as well
Upvotes: 2
Reputation: 7244
Im not familiair with php, but what if you select from the table and check if that returns a value, if not then insert?
Try
$checkquery = "SELECT 1 FROM `".self::$tblOptOutDays."`
WHERE campaign_id=:campaign_id AND opt_out_day=:opt_out_day)";
Then
IF $checkquery <> 1 THEN
// run insert
Upvotes: -1