Auto increment stopped in MySQL? - php

I'm working on a script that sadly I inherited - with no commenting or anything. Argh!
For testing purposes I duplicated one of the tables in the database which had an auto-incrementing ID. When the data is saved to the database, though, the ID number just reads "0" -- which is the default for that column. I'm not sure why it's not auto increasing anymore... any thoughts? Thank you!

Are you sure you set the field in the duplicate table to auto-increment? Try running:
ALTER TABLE `duplicate_table` CHANGE `ai_key` `ai_key` INT( key_length ) NOT NULL AUTO_INCREMENT
And see if it is set or not.

Did you create the new table from scratch or as a real copy? If the column is supposed to auto increment it should be a primary (or at least a unique) key, with no default value.

Just to double check use the sql statement to show the show create table syntax for both tables and compare.
show create table <table>

It sounds like your column isn't actually auto_increment any more. This has happened to me a couple of times because there was a bug (?) in phpMyAdmin which I used to create backups: it wouldn't add the auto_increment keyword into the CREATE TABLE statements. That was a massive pain in the butt...

Related

#1062 - Duplicate entry '81057' for key 'PRIMARY'

I am not fluent in using phpmyadmin so please be gentle.
I have transferred wordpress sites in the past but they have small databases. Ive now moved a new clients site to my hosting and it is running with this error:
INSERT INTO `wp_options` VALUES ( 81057,
'_wc_session_6f1ee0a5a9d89e47f7941c9e3b3e1fed',
'a:20:{s:4:"cart";s:309:"a:1:{s:32:"7b1ce3d73b70f1a7246e7b76a35fb552";a:9:{s:10:"product_id";i:2103;s:12:"variation_id";s:0:"";s:9:"variation";s:0:"";s:8:"quantity";i:1;s:10:"line_total";d:23;s:8:"line_tax";i:0;s:13:"line_subtotal";d:23;s:17:"line_subtotal_tax";i:0;s:13:"line_tax_data";a:2:{s:5:"total";a:0:{}s:8:"subtotal";a:0:{}}}}";s:15:"applied_coupons";s:6:"a:0:{}";s:23:"coupon_discount_amounts";s:6:"a:0:{}";s:19:"cart_contents_total";d:23;s:20:"cart_contents_weight";i:0;s:19:"cart_contents_count";i:1;s:17:"cart_contents_tax";i:0;s:5:"total";i:0;s:8:"subtotal";d:23;s:15:"subtotal_ex_tax";d:23;s:9:"tax_total";i:0;s:5:"taxes";s:6:"a:0:{}";s:14:"shipping_taxes";s:6:"a:0:{}";s:13:"discount_cart";i:0;s:14:"discount_total";i:0;s:14:"shipping_total";i:0;s:18:"shipping_tax_total";i:0;s:9:"fee_total";i:0;s:4:"fees";s:6:"a:0:{}";s:10:"wc_notices";N;}',
no' ) ;`
#1062 - Duplicate entry '81057' for key 'PRIMARY'
I genuinely do not have a clue what this means and how to change it. I get that there is a duplicate entry and its to do with the primary key - which is set on option_id.
What i don't get is why it doesn't just add the entries into the database and auto increment them - which it is set to do? Also how can i resolve the issue and add the database?
please help !
AUTO_INCREMENT is a default value. If you specify a value for the field it will be used instead.
You can omit the value in the insert statement or use NULL instead.
It looks like the table in your source database has some inconsistency since you are only trying to copy all records to your new database.
Check if there are multiple records with same option_id in your source table and if there are some try to resolve them and then try the import again.
As i understand you are trying to do the manual transfer of the whole database and in that case AUTO_INCREMENT just wont work since you will break the relations between your model entities.
The way I see it, you have two options.
Omit the primary key value and allow mysql to create a new row and auto increment it. Of course this will require you to specify the columns.
INSERT INTO `wp_options`(column2, column3, etc)
VALUES('_wc_session_6f1ee0a5a9d89e47f7941c9e3b3e1fed', ...);
Notice that I left out the primary key
If the data needs to be added to that specific row, do an UPDATE instead.
UPDATE wp_options SET column2='_wc_session_6f1ee0a5a9d89e47f7941c9e3b3e1fed',
column3='something else', ...
WHERE column1=81057

Merge several mySQL databases with equivalent structure

I would like write a php script that merges several databases, and I would like to be sure of how to go around it before I start anything.
I have 4 databases which have the same structure and almost same data. I want to merge them without any duplicate entry while preserving (or re-linking) the foreign keys.
For example there is a db1.product table which is almost the same as db2.products so I think I would have to use LIKE comparison on name and description columns to be sure that I only insert new rows. But then, when merging the orders table I have to make sure that the productID still indicates the right product.
So I thought of 2 solutions :
Either I use for each table insert into db1.x as select * from db2.x and then make new links and check for duplicate using triggers.
Either I delete duplicate entries and update new foreign keys (after having dropped constraints) and then insert row into the main database.
Just heard of MySQL Data Compare and Toad for mySQL, could they help me to merge tables ?
Could someone indicate to me what should be the right solution ?
sorry for my english and thank you !
First thing is how are you determining whether products are the same? You mentioned LIKE comparison on name and description. You need to establish a rule what says that product is one and the same in your db1, db2 and so on.
However, let's assume that product's name and description are the attributes that define it.
ALTER TABLE products ADD UNIQUE('name', 'description');
Run this on all of your databases.
After you've done that, select one of the databases you wish to import into and run the following query:
INSERT IGNORE INTO db1.products SELECT * FROM db2.products;
Repeat for the remaining databases.
Naturally, this all fails if you can't determine how you're going to compare the products.
Note: never use reserved words for your column names such as word "name".
Firstly, good luck with this - sounds like a tricky job.
Secondly, I wouldn't do this with PHP - I'd write SQL to do the work, assuming this is a one-off migration task and not a recurring task.
As an approach, I would do the following.
Create a database with the schema you want - it sounds like each of your 4 databases have small variations in the schema. Just create the schema for now, don't worry about the data.
Create a "working" database, with the same schema, but with columns for "old" primary keys. For instance:
table ORDER
order_id int primary key auto increment
old_order_id int not null
...other columns...
table ORDER_LINE
order_line_id int primary key auto increment
old_order_line_id int not null
order_id int foreign key
...other columns...
Table by table, Insert into your working database from your first source database. Let the primary keys auto_increment, but put the original primary key into the "old_" column.
For instance:
insert into workingdb.orders
select null, order_id, ....other columns...
from db1.orders
Where you have a foreign key, populate it by finding the record in the old_ column.
For instance:
insert into workingdb.order_line
select null, ol.order_line_id, o.order_id
from db1.order_line ol,
workingdb.order
where ol.order_id = o.old_order_id
Rinse and repeat for the other databases.
Finally, copy the data from your working database into the "proper" database. This is optional - it may help to retain the old IDs for lookups etc.

MySQL: UPDATEing a row with no guaranteed unique field

I am working with an old MySQL table, which serves as a log of sorts. It looks like
CREATE TABLE `queries` (
`Email` char(32) NOT NULL DEFAULT '',
`Query` blob,
`NumRecords` int(5) unsigned DEFAULT NULL,
`Date` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Now, I need to be able to UPDATE the records in this table (don't ask why, I don't know). Normally, I would just do
UPDATE table SET ... WHERE unique_column = value
But in this case, I don't have a unique column to work from.
Is there a workaround for this, or am I just going to have to push to put in a nice, standard INT NOT NULL AUTO_INCREMENT?
UPDATE queries
SET ...
WHERE Email = value1
AND Query = value2
AND NumRecords = value3
AND Date = value4
LIMIT 1;
A unique identifier is the only reliable way of doing this. Just add an auto_increment column and be done with it.
For exhaustive info including some workaround approaches (none of them perfect though!) check this question, where the OP had a table without a unique identifier and no way to change it.
Update: As Doug Currie points out, this is not entirely true: A unique ID is not necessary as such here. I still strongly recommend the practice of always using one. If two users decide to update two different rows that are exact duplicates of each other at the exact same time (e.g. by selecting a row in a GUI), there could be collisions because it's not possible to define which row is targeted by which operation. It's a microscopic possibility and in the case at hand probably totally negligeable, but it's not good design.
There are two different issues here. First, is de-duping the table. That is an entirely different question and solution which might involve adding a auto_increment column. However, if you are not going to de-dup the table, then by definition, two rows with the same data represent the same instance of information and both ought to be updated if they match the filtering criteria. So, either add a unique key, de-dup the table (in which case uniqueness is based on the combination of all columns) or update all matching rows.
In case you didn't know this, it will affect performance, but you don't need to use a primary key in your WHERE clause when updating a record. You can single out a row by specifying the existing values:
UPDATE queries
SET Query = 'whatever'
WHERE Email = 'whatever#whatever.com' AND
Query = 'whatever' AND
NumRecords = 42 AND
Date = '1969-01-01'
If there are duplicate rows, why not update them all, since you can't differentiate anyway?
You just can't do it with a GUI interface in MySQL Query Browser.
If you need to start differentiating the rows, then add an autoincrement integer field, and you'll be able to edit them in MySQL Query Browser too.
Delete the duplicates first. What's the point of having duplicate rows in the table (or any table for that matter)?
Once you've deleted the duplicates you can implement the key and they your problem is solved.

Alter MySQL column with values to auto increment

I had a hard time with the title, so let me explain.
What I'm doing is using the jQuery UI to create sortable list elements on a page. Once the order is submitted, php assigns an incrementing value to the list elements based on their order, drops the existing id column, creates a new id column and inserts each list elements value WHERE title=x. This creates the proper order of ID's, and is working fine.
What I'd like to do now is change the column to auto_increment, such that if I insert a new entry, the id is assigned automatically, one number higher than the greatest number generated by the php script. I'm not using any foreign keys or anything, just this simple table.
Is this possible?
My mistake, I misread your question. You do not want to use the database itself to provide numbering based on your sort order. You can however use the SQL query itself to return an incrementing field. One sec and I'll update with that info...
Ok, here it is:
you need to use a variable like
set #n=0;SELECT
#n:=#n+1 as 'n',
col1,
col2
from table
However, i highly recommend you just create the numbering in your php code if at all possible.
----------------Original Post----------------
This is pretty easy with phpmyadmin. Let me know if your unable to install that and I'll dig up the necessary SQL.
All heck, here is the SQL:
alter table t1 modify f1 int(4) auto_increment
alter TABLE tbl auto_increment = xxx; //change xxx to be the next id it should use
you may need to run these in opposite order depending on your existing data set it will fail to add auto_increment if you don't change the value of auto_increment to be something not already in use.

What's the standard way to determine the number for a primary key?

I'm planning to make a very simple program using php and mySQL. The main page will take information and make a new row in the database with that information. However, I need a number to put in for the primary key. Unfortunately, I have no idea about the normal way to determine what umber to use. Preferably, if I delete a row, that row's key won't ever be reused.
A preliminary search has turned up the AUTOINCREMENT keyword in mySQL. However, I'd still like to know if that will work for what I want and what the common solution to this issue is.
In MySQL that's the standard solution.
CREATE TABLE animals (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
);
Unless you have an overriding reason to generate your own PK then using the autoincrement would be good enough. That way the database manages the keys. When you are inserting a row you have to leave out the primary key column.
Say you have a table table = (a, b, c) where a is the primary key then the insert statement would be
insert into table (b, c) values ('bbb', 'ccc')
and the primary key will be auto inserted by the databse.
AUTOINCREMENT is what you want. As long as you don't change the table's settings, AUTOINCREMENT will continue to grow.
AUTOINCREMENT is the standard way to automatically create a unique key. It will start at 1 (or 0, I can't remember and it doesn't matter) then increment with each new record added to the table. If a record is deleted, its key will not be reused.
Auto increment primary keys are relatively standard depending on which DBA you're talking to which week.
I believe the basic identity integer will hit about 2 billion rows(is this right for mySQL?) before running out of room so you don't have to worry about hitting the cap.
AUTO_INCREMENT is the common choice, it sets a number starting from 1 to every new row you insert. All the work of figuring out which number to use is done by the db, you just ask it back after inserting if you need to ( in php you get it by callin mysql_last_insertid I think )
For something simple auto increment is best. For something more complicated that will ultimately have a lot of entries I generate a GUID and insert that as the key.

Categories