Lets say we have table A with just one column, id(which is the primary key)
How do we insert a new row into the table without specifying an id?
I tried this
INSERT INTO A (`id`) VALUES (NULL)
and it doesn't work
Edit: I forgot to mention that id, the primary key has the auto_increment and NOT NULL attribute.
Edit 2: The exact error when running the query above is
Column 'id' cannot be null
As soon as 'id' as the auto-increment enable (assuming ID is an integer), you can just do:
INSERT INTO A (id) values (null)
and 'id' will keep incrementing each time.
only works if you're using an auto_increment primary key (PK) as every PK must have a unique, non null value.
drop table if exists A;
create table A
(
id int unsigned not null auto_increment primary key
)
engine=innodb;
insert into A (id) values (null),(null);
mysql> select * from A order by id;
+----+
| id |
+----+
| 1 |
| 2 |
+----+
2 rows in set (0.00 sec)
I had a similar issue, then I noticed that I didn't apply the changes when I changed id to primary key + not null + auto incremental.
INSERT INTO `table` () VALUES ();
is working too.
Try it without the ``..
As in:
INSERT INTO A(sid) VALUES(NULL); //i used sid instead of id...
worked fine for me..
Also wwhile creating the table A, specify unique(sid)...
i.e
create table A(sid int(3) not null auto_increment unique(sid));
Related
I want to add a column to a mysql table where its cells will get values like:
newColumn
-----------
log-00001
log-00002
log-00003
....
the values log-0000x will automatically be created by mysql. This is like an "auto incremented" column but with the 'log-' prefix. Is this possible?
Thx
MySQL doesn't auto-increment anything other than integers. You can't auto-increment a string.
You can't use a trigger to populate a string based on the auto-increment value. The reason is that the auto-increment value isn't generated yet at the time "before" triggers execute, and it's too late to change columns in "after" triggers.
See also my answer to https://stackoverflow.com/a/26899091/20860
You can't use a virtual column, probably for the same reason.
mysql> create table t (id int(5) zerofill auto_increment primary key,
virtcolumn char(8) as (concat('log-', id)));
ERROR 3109 (HY000): Generated column 'virtcolumn' cannot refer to auto-increment column.
You'll have to let the integer auto-increment, and then subsequently use UPDATE to populate your "log-nnnnnn" string after the insert is done.
CREATE TABLE `t` (
`id` int(5) unsigned zerofill NOT NULL AUTO_INCREMENT,
`log` char(9) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `t` () VALUES ();
UPDATE `t` SET `log` = CONCAT('log-', `id`) WHERE `id` = LAST_INSERT_ID();
SELECT * FROM `t`;
+-------+-----------+
| id | log |
+-------+-----------+
| 00001 | log-00001 |
+-------+-----------+
I have the following query:
INSERT INTO `user_pen_names` (`uid`,`pnid`,`my_name`) VALUES ('7','200','stink') ON DUPLICATE KEY UPDATE `my_name`=values(`my_name`)
My table has the following columns defined:
id INT primary, auto-increment
uid INT unsigned, unique
pnid INT unsigned, unique
my_name VARCHAR(24)
I have one table entry already:
id(0), uid(7), pnid(100), my_name(test)
When I execute the above query, what I expected to see was two rows:
id(0), uid(7), pnid(100), my_name(test)
id(1), uid(7), pnid(200), my_name(stink)
What's happening, and I am one confused puppy because of it, is that the existing row is being modified...
id(0), uid(7), pnid(100), my_name(stink)
The same thing happens if I modify uid and pnid so they are no longer unique. Can anyone explain to me why this is happening?
EDIT I made the two columns combinationally unique using the following command:
ALTER TABLE `user_pen_names` ADD UNIQUE KEY `upn_unique_id` (`uid`, `pnid`)
I've not done this before, but theoretically, the INSERT command should only shift to its UPDATE sub-command when uid AND pnid match a row already in the table. Nevertheless, this also didn't work.
It works fine for me. I suspect you didn't run the test you thought you were running.
I tested on a Macbook with MySQL 8.0.1:
mysql> CREATE TABLE `user_pen_names` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(10) unsigned DEFAULT NULL,
`pnid` int(10) unsigned DEFAULT NULL,
`my_name` varchar(24) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uid` (`uid`,`pnid`)
);
mysql> INSERT INTO `user_pen_names` (id, `uid`,`pnid`,`my_name`) VALUES (0, '7','100','test');
mysql> INSERT INTO `user_pen_names` (`uid`,`pnid`,`my_name`) VALUES ('7','200','stink')
ON DUPLICATE KEY UPDATE `my_name`=values(`my_name`);
mysql> SELECT * FROM user_pen_names;
+----+------+------+---------+
| id | uid | pnid | my_name |
+----+------+------+---------+
| 1 | 7 | 100 | test |
| 2 | 7 | 200 | stink |
+----+------+------+---------+
Note that when you insert a 0 into an auto-increment column, it generates a new id, starting at 1.
You have uid & pnid set as unique. So because you can't insert another uid=7, it's modifying the 7 row that has uid of 7 already.
I want to add a column to a mysql table where its cells will get values like:
newColumn
-----------
log-00001
log-00002
log-00003
....
the values log-0000x will automatically be created by mysql. This is like an "auto incremented" column but with the 'log-' prefix. Is this possible?
Thx
MySQL doesn't auto-increment anything other than integers. You can't auto-increment a string.
You can't use a trigger to populate a string based on the auto-increment value. The reason is that the auto-increment value isn't generated yet at the time "before" triggers execute, and it's too late to change columns in "after" triggers.
See also my answer to https://stackoverflow.com/a/26899091/20860
You can't use a virtual column, probably for the same reason.
mysql> create table t (id int(5) zerofill auto_increment primary key,
virtcolumn char(8) as (concat('log-', id)));
ERROR 3109 (HY000): Generated column 'virtcolumn' cannot refer to auto-increment column.
You'll have to let the integer auto-increment, and then subsequently use UPDATE to populate your "log-nnnnnn" string after the insert is done.
CREATE TABLE `t` (
`id` int(5) unsigned zerofill NOT NULL AUTO_INCREMENT,
`log` char(9) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `t` () VALUES ();
UPDATE `t` SET `log` = CONCAT('log-', `id`) WHERE `id` = LAST_INSERT_ID();
SELECT * FROM `t`;
+-------+-----------+
| id | log |
+-------+-----------+
| 00001 | log-00001 |
+-------+-----------+
This problem seems easy at first sight, but I simply have not found a solution that is reasonable time wise.
Consider a table with the following characteristics:
ID INTEGER PRIMARY KEY AUTOINCREMENT
name INTEGER
values1 INTEGER
values2 INTEGER
dates DATE
Every day, N amount of new rows are generated, for dates into the future, and with the 'name' coming from a finite list. I would like to insert a new row when there is new data, but if there is already a row with 'name' and 'dates', simply update it.
Please note that a current proposed solution of an SPROC that checks the conditional is not feasible, as this is data being pushed from another language.
that is what insert on duplicate key update is for.
The Manual page for it is here.
The trick is that the table needs to have a unique key (can be a composite) so that the clash of doing an insert can be detected. As such, the update to occur on that row, otherwise an insert. It can be a primary key, of course.
In your case, you could have a composite key such as
unique key(theName,theDate)
If the row is already there, the clash is detected, and the update happens.
Here is a complete example
create table myThing
( id int auto_increment primary key,
name int not null,
values1 int not null,
values2 int not null,
dates date not null,
unique key(name,dates) -- <---- this line here is darn important
);
insert myThing(name,values1,values2,dates) values (777,1,1,'2015-07-11') on duplicate key update values2=values2+1;
insert myThing(name,values1,values2,dates) values (778,1,1,'2015-07-11') on duplicate key update values2=values2+1;
-- do the 1st one a few more times:
insert myThing(name,values1,values2,dates) values (777,1,1,'2015-07-11') on duplicate key update values2=values2+1;
insert myThing(name,values1,values2,dates) values (777,1,1,'2015-07-11') on duplicate key update values2=values2+1;
insert myThing(name,values1,values2,dates) values (777,1,1,'2015-07-11') on duplicate key update values2=values2+1;
show results
select * from myThing;
+----+------+---------+---------+------------+
| id | name | values1 | values2 | dates |
+----+------+---------+---------+------------+
| 1 | 777 | 1 | 4 | 2015-07-11 |
| 2 | 778 | 1 | 1 | 2015-07-11 |
+----+------+---------+---------+------------+
As expected, insert on duplicate key update works, just 2 rows.
This is easy:
Create a unique key on the columns to check
Use the INSERT .. ON DUPLICATE KEY UPDATE construct
I would like to add a new autoincrement column to a pre-existing table. However, I need the ids that are in that column to start at a particular value, ie
alter table MyTable
add column MyColumn int unsigned not null primary key auto_increment=999999;
Is this possible? I tried issuing:
alter table MyTable auto_increment=999999;
before I added the column, but it had no effect. Because adding the column will automatically generate the ids, it is not sufficient to run the second statement after the first.
No, it works to add an AI column with a starting position. But you almost got the syntax right. Here's a demo:
mysql> CREATE TABLE foo (v varchar(10));
mysql> INSERT INTO foo VALUES ('one'), ('two'), ('three');
Then comes the tricky syntax. You have to declare the column as AUTO_INCREMENT, but then also give the table option for the AUTO_INCREMENT starting value. And you need a comma to separate the ADD COLUMN from the table option.
mysql> ALTER TABLE foo ADD COLUMN id INT AUTO_INCREMENT PRIMARY KEY,
AUTO_INCREMENT=999999;
mysql> select * from foo;
+-------+---------+
| v | id |
+-------+---------+
| one | 999999 |
| two | 1000000 |
| three | 1000001 |
+-------+---------+