mysql continue on errors - php

I have a PHP foreach loop and a mysql insert statement inside of it. The loop inserts data into my database. I've never ran into this issue before but what I think is happening is that the insert dies (I do not have an "or die" statement after the insert) when it reaches a duplicate record. Even though there may be duplicate records in the table, I need this to just continue. Is there something that I need to specify to do this?
I'm transferring some records from one table to another. Right now, I have 20 records in table #1 and only 17 in table #2. I'm missing 3 records but only one of those are duplicated which violates the constraint on the table. The other two records should have been added. Can someone give me some advice here?

What's happening is that PHP is throwing a warning when the mysql insert fails and stopping on that warning. The best way to accomplish your goal is:
Create a custom exception handler
Set PHP to use the exception handler for warnings.
Wrap the insert attempt into a try / catch
When you catch the exception / warning, either log or output the mysql error but continue script execution.
This will allow your script to continue without stopping while at the same time explaining to you the problem.

One way around this would be to simply query the database for the record that you're about to insert. This way, your series of queries will not die when attempting to insert a duplicate record.
A slightly more efficient solution would be to query for [i]all[/i] of the records you're about to insert in one query, remove all the duplicates, then insert the new ones.

Do you insert multiple rows with one INSERT statement?
INSERT INTO xyz (x,y,z) VALUES
(1,2,3),
(2,3,5),
(3,4,5),
(4,5,6)
Then you might want to consider prepared statements
...or adding the IGNORE keyword to your INSERT statement
INSERT IGNORE INTO xyz (x,y,z) VALUES
(1,2,3),
(2,3,5),
(3,4,5),
(4,5,6)
http://dev.mysql.com/doc/refman/5.0/en/insert.html says:
If you use the IGNORE keyword, errors that occur while executing the INSERT statement are treated as warnings instead
You can still fetch the warnings but the insertion will not be aborted.

Not a good way cause you should figure out whats wrong, but to just prevent it from dieing try adding # in front of the function
#mysql_query = ...

INSERT INTO FOO
(ID, BAR)
VALUES(1,2),(3,4)
ON DUPLICATE KEY UPDATE BAR=VALUES(BAR)

Related

MySQL MULTIPLE INSERT get rows that fail?

I'm a beginner with PDO and MySQL, so here's my question :
How can I be sure that when performing an INSERT .. SELECT (or MULTIPLE INSERT)
all data will be inserted in database?
I know there is a rowCount() function but the number of rows inserted is dynamic.
The only way I see would be to make a SELECT count(*), and then compare it with the rowCount(), but I'm not sure I'm doing it the right way.
And if not all data were inserted, is it possible to get rows which didn't work?
Also, is it possible that a SELECT query fails and retrieves only a few part of the data? (ex : It must retrieve 1000 rows but due to some failure, it retrieves 700) Or it's all or nothing?
Thanks for the help.
How can I be sure that when performing an INSERT .. SELECT (or MULTIPLE INSERT) all data will be inserted in database?
You should tell PDO to throw an exception in case of error and thus there will be a PHP error in case of a failed query.
I know there is a rowCount() function
Row count has nothing to do in your case.
And if not all data were inserted, is it possible to get rows which didn't work?
It is advised to redo all the successful yet queries instead. To do so you have to wrap your inserts in a transaction.
However, if you want to keep alll the previous inserts in place, you may wrap execute call in a try and catch operator and do whatever workaround inside.
Also, is it possible that a SELECT query fails and retrieves only a few part of the data?
No.

MySQL How to Avoid Duplicate Entries from PHP

I thought the most efficient way was to create a UNIQUE field on the table instead of selecting to check for existing values before doing anything else but this makes use of two queries. Instead with a UNIQUE field only one query is necessary because MySQL checks for you. The problem is that duplicate entry errors cause an internal server error which I cannot recover from in PHP. What do you guys suggest, what is the best way to avoid duplicate entries in a PHP & MySQL application?
Use ON DUPLICATE KEY
INSERT INTO someTable (id, amount) VALUES ($to_uid, $send_amount)
ON DUPLICATE KEY UPDATE amount = amount + $send_amount
https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
2) You can catch the duplicate key exception. PDO example:
try{
$stmt->execute(...);
}
catch(PDOException $e){
if($e->errorInfo[1] == 1062){
// Mysql returned 1062 error code which means a duplicate key
}
}
You could use REPLACE INTO for your query, it will try an insert first and than it will delete the row with the same ID and replace it.
FOUND THE SOLUTION!
CodeIgniter requires the setting
$db['default']['stricton'] = TRUE;
an explicitly calling
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
In order for MySQL to throw exceptions. The exceptions must also be caught.
You can use INSERT IGNORE to prevent updating a row and prevent an exception from being thrown if row already exists.
https://dev.mysql.com/doc/refman/5.5/en/insert.html
If you use the IGNORE keyword, errors that occur while executing the
INSERT statement are ignored. For example, without IGNORE, a row that
duplicates an existing UNIQUE index or PRIMARY KEY value in the table
causes a duplicate-key error and the statement is aborted. With
IGNORE, the row still is not inserted, but no error occurs. Ignored
errors may generate warnings instead, although duplicate-key errors do
not.

pg_prepare: cannot insert multiple commands into a prepared statement

I have 2 tables, TableA and TableB. TableB has a fk field pointing to TableA.
I need to use a DELETE statement for TableA, and when a record in it is deleted I need to delete all records in TableB related to that record in TableA. Pretty basic.
begin;
DELETE FROM TableB
WHERE nu_fornecedor = $1;
DELETE FROM TableA
WHERE nu_fornecedor = $1;
commit;
This string is passed to pg_prepare(), but then I get error
ERROR: cannot insert multiple commands into a prepared statement
Ok, but I need to run both commands in the same transaction, I cant execute 2 separated statements. I tried to use with without begin-commit and got same error.
Any idea how to do it?
To understand what is going on and your options, let me explain what a prepared statement is and what it is not. You can use pg_prepare, but only for the statements individually, not for the transaction as a whole.
A prepared statement is a statement handed to PostgreSQL which is then parsed for and stored as a parse tree for future use. On first execution, the parse tree is planned with the inputs provided, and executed, and the plan cached for future use. Usually it makes little sense to use prepared statements unless you want to reuse the query plan (i.e. executing a bunch of otherwise identical update statements hitting roughly the same number of rows), all in the same transaction.
If you want something that gives you the benefits of separating parameters from parse trees but does not cache plans, see pg_query_param() in the PHP documentation. That is probably what you want.

Insert into Table 1, get incremented value, and insert into table 2

In php, I'm trying to insert a value into one table, return an auto-incremented value, and then insert that value along with other values into a second table.
I'm running into a few problems. First, while there's a lot of ways of doing this in SQL, I have to do this with php's mysql functions. I'm afraid of weird errors if I combine multiple statements together. Second, like I mentioned, I need this to be done in one query, as it'll be used for a web application.
My current query is like this
INSERT INTO TABLE1 VALUES(*);
INSERT INTO TABLE2
SELECT max(AutoIncrementedColumn)
FROM TABLE1;
The problem I'm having is that mysql_query() doesn't support multi queries. Also, I believe mysql_escape_string() removes anything it believes to be a multi query, so even if I could somehow get mysql_query to believe my query is not a multi query, I'm still out of luck unless I write my own escape method.
Does anyone have any ideas on how to deal with this problem?
EDIT: Forgot to mention that I can't use mysql_insert_id because the column that's autoincrementing is of type Bigint.

MySQL Ignore is not working

I am trying to prevent duplicates from occuring using the following query, but it doesnt seem to work. Please could you tell me what the problem is?
INSERT IGNORE INTO Following SET `followingUserID` = '$accountIDToFollow', `followerUserID` = '$accountID'
INSERT IGNORE INTO
Following (`followingUserID`,`followerUserID`)
VALUE
('$accountIDToFollow','$accountID')
You were doing an UPDATE format before
If you are trying to do an update this is how it works
UPDATE followingUserID
SET
followingUserID = '$accountIDToFollow',
WHERE
followerUserID = '$accountID';
Of course you want to replace the were clause with the correct condition you want to do
As per MYSQL documentation,
If you use the IGNORE keyword, errors
that occur while executing the INSERT
statement are treated as warnings
instead. For example, without IGNORE,
a row that duplicates an existing
UNIQUE index or PRIMARY KEY value in
the table causes a duplicate-key error
and the statement is aborted. With
IGNORE, the row still is not inserted,
but no error is issued.
It means, the IGNORE does not prevent any record duplicate. You will have to put Unique constraints on your given fields.

Categories