If I have a table like this:
CREATE TABLE Person (id INT AUTO_INCREMENT PRIMARY KEY, age INT);
Is there a simpler method than rewriting the attributes of the column like that ?
INSERT INTO Person (age) VALUES (18);
I know that for the DEFAULT values there is the keyword DEFAULT, but is there a similar one for AUTO_INCREMENT? I work with pretty long tables and I don't want to rewrite all the column names each time I make an INSERT.
Thank you for your help.
https://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html says:
No value was specified for the AUTO_INCREMENT column, so MySQL assigned sequence numbers automatically. You can also explicitly assign 0 to the column to generate sequence numbers, unless the NO_AUTO_VALUE_ON_ZERO SQL mode is enabled. If the column is declared NOT NULL, it is also possible to assign NULL to the column to generate sequence numbers.
So any of the following will work:
INSERT INTO Person VALUES (0, 18);
INSERT INTO Person VALUES (NULL, 18);
INSERT INTO Person VALUES (DEFAULT, 18);
However, it's considered good practice to list all columns explicitly when you write any INSERT statement. If someone changes the order of columns in the table, your VALUES might not get inserted into the right columns unless you list the column names explicitly. Also if someone adds or drops a column.
Related
I have a lists table that has an order field.
When I insert a new record, is it possible to find the order of the previous row and increment the new row?
Or should I go about it myself in PHP by doing an OrderBy('order') query and getting the max() value of that?
When you declare a table with MySQL you can use an auto-increment id so you won't have to deal about its incrementation:
CREATE TABLE people (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
);
As explained in the documentation,
An integer or floating-point column can have the additional attribute
AUTO_INCREMENT. When you insert a value of NULL (recommended) or 0
into an indexed AUTO_INCREMENT column, the column is set to the next
sequence value. Typically this is value+1, where value is the largest
value for the column currently in the table. AUTO_INCREMENT sequences
begin with 1.
I suggest you to ommit the field completly when inserting new records.
You can then retrieve the last id inserted with LAST_INSERT_ID() SQL function (or the mysqli_insert_id function of PHP languagefor example).
But since it's not what you wanted, probably because of one of the reasons quoted from MarioZ's comment:
If you are already using auto-increment for the ID you can use it for
the order (that can be one reason). For auto-increment the column
must be set as primary and unique, can't be repeated values. The auto-increment is from the number in the record, if you inserted 10
rows and you delete 2, the next insert with auto-increment will be
11(if the last now is 8 you'd want it to be 9). Those are posible
reasons not to use it for what #Notflip wants :P
... You'll have to use PHP, with LOCK TABLE and UNLOCK TABLE SQL instructions before and after the retrieving of the last order then the updating of the new order, to avoid having simultaneous records with the same "order".
I have an existing sql table with 3 columns and 100+ entries/rows. There is an id column with autoincrement.
Now, I want to add 10 new rows at the beginning of the table with id from 1 to 10. But I cannot lose any existing row. So, how do I do it?
One idea that just came to my mind is perhaps I can increase the existing id by adding 10, like 1+10 becomes 11, 25+10 becomes 35, and then I can add rows at the beginning. What will be the script for this IF this is possible?
All you need to do for this is to set the auto_increment for that table to whatever number you need to create space for the new records you want to insert.
For example, if you inserted rows with id's 1-100, you might:
Check the next auto_increment value by running:
select auto_increment as val from information_schema.tables where table_schema='myschema' and table_name='mytable';
Let's assume that value would be 101 (the value that would be used if you inserted a new row). You can "advance" the auto_increment value by running:
alter table myschema.mytable auto_increment = 111;
If you insert a new row like this:
insert into mytable (not_the_id_column) values ('test');
It will get the "next" id of 111. But if you specify id values manually, you are ok in this case as long as you use any value less than 111, so you could insert your desired records like this:
insert into mytable (id, not_the_id_column) values (101, 'test101');
insert into mytable (id, not_the_id_column) values (102, 'test102');
... -- more inserts as needed
Now, you still must take proper precautions when updating PK values, or any value that has dependencies on it (Foreign Key or otherwise), but it is completely legitimate to forcibly advance and/or backfill the id values, as long as the resulting auto_increment value doesn't duplicate one that's already in the table.
I agree with juergen d's comment that you should not do this, but I realize there are situations where this kind of thing must be done.
SELECT MAX(id)-MIN(id)+1 INTO #x FROM theTable;
UPDATE theTable SET id = id + #x;
SELECT MIN(id) INTO #x FROM theTable;
UPDATE theTable SET id = 10 + id - #x;
If the id is the primary key, value collisions within an update can cause MySQL to reject the update. (Hence the pair of updates to avoid such a possibility.)
Edit: Factoring N.B.'s strong objection into this, it would also probably be good to verify the table's next auto-increment value is not going to collide with the updated records after the update is completed. I don't have an appropriate database on hand to verify whether UPDATE statements affect it; and even if they do affect it, you may end up wanting to reduce it so as to not create an unnecessary gap (gaps should ideally not be a problem, but if they are or you are just mildly OCD, it is worth looking into).
There is a necessity when inserting into a table of values to change the auto-increment field to another that no two of the same id in these tables. It is necessary for the data output from the third table based on the recording and going to not add to the table a column indicating. Here's my trigger, but it does not work
CREATE TRIGGER `update_id` AFTER INSERT ON `table1`
FOR EACH ROW BEGIN
ALTER TABLE `table2` AUTO_INCREMENT = NEW.id;
END;
It's not entirely clear what problem you are trying to solve.
But it sounds as if you have two tables with an id column, and you want to ensure that the same value of id is not used in both tables. That is, if id value 42 exists in table1, you want to ensure that 42 is not used as an id value in table2.
Unforunately, MySQL does not provide any declarative constraint for this.
It sounds as if you want an Oracle-style SEQUENCE object. And unfortunately, MySQL doesn't provide an equivalent.
But what we can do is emulate that. Create an extra "sequence" table that contains an AUTO_INCREMENT column. The purpose of this table is to be used to generate id values, and to keep track of the highest generated id value:
CREATE TABLE mysequence (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
Then, we'd remove the AUTO_INCREMENT attribute from the id columns of the two tables we want to generate distinct id values for.
For those tables, we'd create BEFORE INSERT triggers that will obtain distinct id values and assign it to the id column. To generate a unique value, we can insert a row to the new mysequence table, and then retrieve the auto_increment value using the LAST_INSERT_ID function.
Something like this:
CREATE TRIGGER table1_bi
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
DECLARE generated_id INT UNSIGNED;
-- do we need to generate a value for id column?
IF NEW.id IS NULL THEN
-- generate unique id value with insert into sequence table
INSERT INTO mysequence (id) VALUES (NULL);
-- retrieve inserted id value
SELECT LAST_INSERT_ID() INTO generated_id;
-- assign the retrieved value to the id columns of the row being inserted
SET NEW.id = generated_id;
END IF
END$$
(That's just a rough outline, likely there's at least one syntax error in there somewhere.)
You'd need to create a BEFORE INSERT trigger for each of the tables.
This is one approach to generating distinct values for the id columns.
Note that it wouldn't be necessary to keep ALL of the rows in the mysequence table, it's only necessary to keep the row with the largest id value.
Also note that this doesn't enforce any constraint on either tables; some session could supply a value for id that is already in the other table. To prevent that, the trigger could raise an error if a non-NULL id value is supplied. It might also be possible to allow non-NULL values, and to perform a query to check if the supplied id value already exists in the other table, and raise an error if it does. But that query would be subject to a race condition... two concurrent sessions doing inserts to the tables, and you'd need to implement some concurrency killing locking mechanisms to prevent concurrent inserts.
i want to insert in a table using columns order not name
insert into tableName(1,2,5) values('val1','val2','val3');
i dont want to use
insert into tableName values('val1','val2','val3');
because the table does not contain just 3 columns
how can i do it
because columns name are encrypted so I can not rely on this
insert into tableX("cCGSvKJVQXnt8A==","aDOlOQrPfg==","qsdcx112")
values('val1','val2','val3');
is there any idea how can i deal with this
thank
You can't use the ordinal number of a column in an insert statement. However, you can accomplish what you're trying to do (insert values into specific columns in a table) using the column names instead.
Presume your table has five columns; I'm going to call them "Alpha", "Bravo", "Charlie", "Delta", and "Echo", since you haven't given us the schema for your table, but replace these names with the names of the columns actually in your table. I'm guessing that your third and fourth column (my "Charlie" and "Delta") are nullable. You can then insert a tuple/row in your table with the other three columns filled using syntax like this:
INSERT INTO TableName(Alpha, Bravo, Echo) VALUES ("val1", "val2", "val3");
If, per your comments above, your column names are unprintable characters (which is a terrible, terrible idea), you can explicitly insert NULLs into the missing columns:
INSERT INTO TableName VALUES ("val1", "val2", NULL, NULL, "val3");
but the weakness here is that, if additional columns are subsequently added to your table's schema, the insert statement will start failing.
You need to put the column names where you have the 1,2,5. You can't use the column number.
insert into tableName(1,2,5) values("val1","val2","val3");
I have a table in which the first column is auto_increment. I want to insert data into the table, but skip the first column as it is updated automatically when a new row is begun.
so:
INSERT INTO table VALUES (NULL,"lady","gaga","rulz");
But NULL cannot be inserted into a column as I specified earlier. What do I need to replace NULL with so that the column doesn't get anything inserted into it?
Just make sure you specify the respective column names
INSERT INTO table (col1, col2, col3) VALUES ("lady","gaga","rulz");
You don't even need to fill all columns (if they are not required), Ie.
INSERT INTO table (col2) VALUES ("gaga");
insert into table(field1, field2, field3) values('lady', 'gaga', 'sucks')
You need to explicitly specify the column names and order. In other words
INSERT INTO table (field2, field3, field4) VALUES ("lady","gaga","rulz");
BTW it is typically a good idea to avoid the implicit insert syntax (but maybe for the simplest / debug time snippets), lest you get surprised when/if the underlying table schema was somehow changed.
Also, so you know, something, will get inserted into the (here) field1 column. When you define or alter the schema of a table, a given field can either be nullable or not, and/or it can have a default value or not. In the SQL provided above, you can only omit the values for fields that are either nullable or have a default value; SQL will otherwise return an error and won't insert any part of the new record.