I am trying to alter a table which has no primary key nor auto_increment column. I know how to add an primary key column but I was wondering if it's possible to insert data into the primary key column automatically (I already have 500 rows in DB and want to give them id but I don't want to do it manually). Any thoughts? Thanks a lot.
An ALTER TABLE statement adding the PRIMARY KEY column works correctly in my testing:
ALTER TABLE tbl ADD id INT PRIMARY KEY AUTO_INCREMENT;
On a temporary table created for testing purposes, the above statement created the AUTO_INCREMENT id column and inserted auto-increment values for each existing row in the table, starting with 1.
suppose you don't have column for auto increment like id, no, then you can add using following query:
ALTER TABLE table_name ADD id int NOT NULL AUTO_INCREMENT primary key FIRST
If you've column, then alter to auto increment using following query:
ALTER TABLE table_name MODIFY column_name datatype(length) AUTO_INCREMENT PRIMARY KEY
For those like myself getting a Multiple primary key defined error try:
ALTER TABLE `myTable` ADD COLUMN `id` INT AUTO_INCREMENT UNIQUE FIRST NOT NULL;
On MySQL v5.5.31 this set the id column as the primary key for me and populated each row with an incrementing value.
In order to make the existing primary key as auto_increment, you may use:
ALTER TABLE table_name MODIFY id INT AUTO_INCREMENT;
Yes, something like this would do it, it might not be the best though. You might wanna make a backup:
$get_query = mysql_query("SELECT `any_field` FROM `your_table`");
$auto_increment_id = 1;
while($row = mysql_fetch_assoc($get_query))
{
$update_query = mysql_query("UPDATE `your_table` SET `auto_increment_id`=$auto_increment_id WHERE `any_field` = '".$row['any_field']."'");
$auto_increment_id++;
}
Notice that the the any_field you select must be the same when updating.
The easiest and quickest I find is this
ALTER TABLE mydb.mytable
ADD COLUMN mycolumnname INT NOT NULL AUTO_INCREMENT AFTER updated,
ADD UNIQUE INDEX mycolumnname_UNIQUE (mycolumname ASC);
I was able to adapt these instructions take a table with an existing non-increment primary key, and add an incrementing primary key to the table and create a new composite primary key with both the old and new keys as a composite primary key using the following code:
DROP TABLE IF EXISTS SAKAI_USER_ID_MAP;
CREATE TABLE SAKAI_USER_ID_MAP (
USER_ID VARCHAR (99) NOT NULL,
EID VARCHAR (255) NOT NULL,
PRIMARY KEY (USER_ID)
);
INSERT INTO SAKAI_USER_ID_MAP VALUES ('admin', 'admin');
INSERT INTO SAKAI_USER_ID_MAP VALUES ('postmaster', 'postmaster');
ALTER TABLE SAKAI_USER_ID_MAP
DROP PRIMARY KEY,
ADD _USER_ID INT AUTO_INCREMENT NOT NULL FIRST,
ADD PRIMARY KEY ( _USER_ID, USER_ID );
When this is done, the _USER_ID field exists and has all number values for the primary key exactly as you would expect. With the "DROP TABLE" at the top, you can run this over and over to experiment with variations.
What I have not been able to get working is the situation where there are incoming FOREIGN KEYs that already point at the USER_ID field. I get this message when I try to do a more complex example with an incoming foreign key from another table.
#1025 - Error on rename of './zap/#sql-da07_6d' to './zap/SAKAI_USER_ID_MAP' (errno: 150)
I am guessing that I need to tear down all foreign keys before doing the ALTER table and then rebuild them afterwards. But for now I wanted to share this solution to a more challenging version of the original question in case others ran into this situation.
Export your table, then empty your table, then add field as unique INT, then change it to AUTO_INCREMENT, then import your table again that you exported previously.
You can add a new Primary Key column to an existing table, which can have sequence numbers, using command:
ALTER TABLE mydb.mytable ADD pk_columnName INT IDENTITY
I was facing the same problem so what I did I dropped the field for the primary key then I recreated it and made sure that it is auto incremental . That worked for me . I hope it helps others
ALTER TABLE tableName MODIFY tableNameID MEDIUMINT NOT NULL AUTO_INCREMENT;
Here tableName is name of your table,
tableName is your column name which is primary has to be modified
MEDIUMINT is a data type of your existing primary key
AUTO_INCREMENT you have to add just auto_increment after not null
It will make that primary key auto_increment......
Hope this is helpful:)
Well, you have multiple ways to do this:
-if you don't have any data on your table, just drop it and create it again.
Dropping the existing field and creating it again like this
ALTER TABLE test DROP PRIMARY KEY, DROP test_id, ADD test_id int AUTO_INCREMENT NOT NULL FIRST, ADD PRIMARY KEY (test_id);
Or just modify it
ALTER TABLE test MODIFY test_id INT AUTO_INCREMENT NOT NULL, ADD PRIMARY KEY (test_id);
How to write PHP to ALTER the already existing field (name, in this example) to make it a primary key? W/o, of course, adding any additional 'id' fields to the table..
This a table currently created - Number of Records found: 4 name VARCHAR(20) YES
breed VARCHAR(30) YES
color VARCHAR(20) YES
weight SMALLINT(7) YES
This an end result sought (TABLE DESCRIPTION) -
Number of records found: 4
name VARCHAR(20) NO PRI
breed VARCHAR(30) YES
color VARCHAR(20) YES
weight SMALLINT(7) YES
Instead of getting this -
Number of Records found: 5
id int(11) NO PRI
name VARCHAR(20) YES
breed VARCHAR(30) YES
color VARCHAR(20) YES
weight SMALLINT(7) YES
after trying..
$query = "ALTER TABLE racehorses ADD id INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (id)";
how to get this? -
Number of records found: 4
name VARCHAR(20) NO PRI
breed VARCHAR(30) YES
color VARCHAR(20) YES
weight SMALLINT(7) YES
i.e. INSERT/ADD.. etc. the primary key INTO the first field record (w/o adding an additional 'id' field, as stated earlier.
No existing primary key
ALTER TABLE `db`.`table`
ADD COLUMN `id` INT NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (`id`);
;
Table already has an existing primary key'd column
(it will not delete the old primary key column)
ALTER TABLE `db`.`table`
ADD COLUMN `id` INT NOT NULL AUTO_INCREMENT FIRST,
CHANGE COLUMN `prev_column` `prev_column` VARCHAR(2000) NULL ,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
;
Note: column must be first for auto increment which is why the FIRST command.
Related
Is this possible in MySql ?? Can I have an auto-incrementing Primary Key, prefixed with a letter, something like R1234, R1235, R1236... ect ??
What you could do is store the key as two columns. A char prefix and an auto-incrementing int, both of which are grouped for the primary key.
CREATE TABLE myItems (
id INT NOT NULL AUTO_INCREMENT,
prefix CHAR(30) NOT NULL,
PRIMARY KEY (id, prefix),
...
No. But for MyIsam tables you can create a multi-column index and put auto_increment field on secondary column, so you will have pretty much the same you are asking:
CREATE TABLE t1 (prefix CHAR(1) NOT NULL, id INT UNSIGNED AUTO_INCREMENT NOT NULL,
..., PRIMARY KEY(prefix,id)) Engine = MyISAM;
INSERT INTO t1(prefix) VALUES ('a'),('a'),('b'),('b');
SELECT * FROM t1;
a 1
a 2
b 1
b 2
You can get more details from here
Note: it's not going to work for INNODB engine
you can do it with two fields like this. but you can't do it with one field to my knowledge.
create table foo (
code char,
id int unsigned not null auto_increment
primary key(id,code)
);
I used this code however it showed that unrecognized alter operation and also that key is unrecognized.
ALTER TABLE `ecommerce`.`users` (id INT(11) NOT NULL, PRIMARY-KEY AUTO_INCREMENT);
The correct syntax is:
ALTER TABLE ecommerce.users add column id INT AUTO_INCREMENT PRIMARY KEY;
Here is a db<>fiddle.
EDIT:
I realize the OP might already have the column and want to replace the definition. That works with this syntax:
ALTER TABLE users modify column id INT AUTO_INCREMENT PRIMARY KEY;
Here is this db<>fiddle.
you can give primary while creating your table or after create table you can add primary key by alter table
while creating table
create table info(id int primary key,Name varchar(25),dept varchar(25));
create table info(id int,Name varchar(25),dept varchar(25),primary key(id));
after creating table
alter table info add primary key(id);
I am inserting values from a form in a MySql table. The problem is when I leave one input field empty (it is a primary key), the db does not complain that the primary key is empty and the row is added to the table with an empty space in the primary key column.
$this->vendor_name = empty($params['name'])? $params['name']:null;
So in my case name is empty and I am inserting a NULL in the primary key but there is no warning from the db.
you should make the primary key auto_increment and not null
try it
CREATE TABLE vendedor(
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
);
https://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html
Yes inserting a NULL value is the right way, but in the code there is a simple condition error, this is the solution:
!empty($params['name'])?$params['name']:null;
Probably you have multiple primary keys. In this case only your first primary key cannot be null and must be unique, the others not. So if you want to set your column only for unique values, you can add a unique index.
ALTER TABLE `your_table`
ADD UNIQUE INDEX (`column_name`);
ColumnName is Unique (UNIQUE KEY ColumnName).
I just want to make column not unique (must be very simple, but can not understand how).
If in phpMyAdmin check at column name and at bottom click on Unique icon, get #1062 - Duplicate entry '' for key 'RegistrationNumber'. OK, see it is because, clicking on icon it ADD UNIQUE.
There is Unique icon in Structure within row. But the icon is not click-able.
As in phpMyAdmin did not found how to do it, trying with query.
Based on advices tried ALTER TABLE TableName DROP INDEX ColumnName.
Get 1091 Can't DROP 'ColumnName'; check that column/key exists
Here https://stackoverflow.com/a/4414694/2465936 found This error means that you are trying to delete a key which is being used by another table. Possibly the ColumnName is used by another table.
Please advice what need to do to make column not unique.
With SHOW CREATE TABLE get
Array
(
[0] => Array
(
[Table] => 18_6_TransactionPartners
[Create Table] => CREATE TABLE `18_6_TransactionPartners` (
`Number` int(11) NOT NULL AUTO_INCREMENT,
`CompanyName` char(255) COLLATE utf8_unicode_ci NOT NULL,
`RegistrationNumber` char(255) COLLATE utf8_unicode_ci NOT NULL,
.......
PRIMARY KEY (`Number`),
UNIQUE KEY `Number_2` (`Number`),
UNIQUE KEY `CompanyName` (`CompanyName`,`RegistrationNumber`),
KEY `Number` (`Number`)
) ENGINE=InnoDB AUTO_INCREMENT=444 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
)
)
Update
Based on #Bart Friederichs advice tried ALTER TABLE 18_6_TransactionPartners DROP INDEX Number and changed column RegistrationNumber not not unique. Do not understand why (possibly had some mess with unique keys). In any case can change to not unique.
Probably you have a named INDEX. By using SHOW CREATE TABLE tbl you can find out the names of the indices. Then drop them by name (e.g. some test table):
mysql> SHOW CREATE TABLE test;
CREATE TABLE `test` (
`entry_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
UNIQUE KEY `k` (`entry_id`)
)
To drop the index, use this:
ALTER TABLE test DROP INDEX k;
Your key name is RegistrationNumber (as is told by the error message):
ALTER TABLE TableName DROP INDEX RegistrationNumber;
If your column was defined unique using UNIQUE clause, then you can do something like this:
ALTER TABLE mytable DROP INDEX constraint_name
For dropping the index do this:-
ALTER TABLE mytable DROP INDEX index_name;
You have to drop the index using the index name, not the column name.
I would like to have a way of controlling/tracking revisions of rows. I am trying to find the best solution for this problem.
The first thing that comes to mind is to have a table with a id to identify the row and and id for the revision number. The combined ids would be the primary key. so example data might look like this:
1, 0, "original post"
1, 1, "modified post"
1, 2, "modified again post"
How can I create a table with this behavior? or is there a better solution to do this?
I like InnoDB since it supports transactions, foreign keys and full text in MySQL 5.6+.
I know its possible to "force" this behavior by how I insert the data but I'm wondering if there is a way to have the table do this automatically.
Consider table structure:
TABLE posts
post_id INT AUTO_INCREMENT PK
cur_rev_id INT FK(revisions.rev_id)
TABLE revisions
rev_id INT AUTO_INCREMENT PK
orig_post INT FK(posts.post_id)
post_text VARCHAR
Where the posts table tracks non-versioned information about the post and its current revision, and revisions tracks each version of the post text with a link back to the parent post. Because of the circular FK constraints you'd need to enclose new post insertions in a transaction.
With this you should be able to easily add, remove, track, roll back, and preview revisions to your posts.
Edit:
Yeah, enclosing in a transaction won't exactly help since the keys are set to AUTO_INCREMENT, so you need to dip back in to PHP with LAST_INSERT_ID() and some temporarily NULL indexes.
CREATE TABLE `posts` (
`post_id` INT(10) NOT NULL AUTO_INCREMENT,
`cur_rev_id` INT(10) NULL DEFAULT NULL,
`post_title` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`post_id`),
INDEX `FK_posts_revisions` (`cur_rev_id`),
) ENGINE=InnoDB
CREATE TABLE `revisions` (
`rev_id` INT(10) NOT NULL AUTO_INCREMENT,
`orig_post` INT(10) NULL DEFAULT NULL,
`post_text` VARCHAR(32000) NULL DEFAULT NULL,
PRIMARY KEY (`rev_id`),
INDEX `FK_revisions_posts` (`orig_post`),
) ENGINE=InnoDB
ALTER TABLE `posts`
ADD CONSTRAINT `FK_posts_revisions` FOREIGN KEY (`cur_rev_id`) REFERENCES `revisions` (`rev_id`);
ALTER TABLE `revisions`
ADD CONSTRAINT `FK_revisions_posts` FOREIGN KEY (`orig_post`) REFERENCES `posts` (`post_id`);
Then:
$db_engine->query("INSERT INTO posts (cur_rev_id, post_title) VALUES (NULL, 'My post Title!')");
$post_id = $db_engine->last_insert_id();
$db_engine->query("INSERT INTO revisions (orig_post, post_text) VALUES($post_id, 'yadda yadda')");
$rev_id = $db_engine->last_insert_id();
$db_engine->query("UPDATE posts SET cur_rev_id = $rev_id WHERE post_id = $post_id");
If I've understood you correctly and the table doesn't receive large numbers of updates/deletes then you could look at setting a trigger such as:
DELIMITER $$
CREATE TRIGGER t_table_update BEFORE UPDATE ON table_name
FOR EACH ROW
INSERT INTO table_name_revisions (item_id, data, timestamp)
VALUES(OLD.id, OLD.data, NOW());
END$$
DELIMITER ;
See trigger syntax for more information