Do I have to know the name of the column so to be able to insert data ? because I need to insert data using column number (first column is 1...)
Instead of using this :
insert into my_table (column1, column2)
values (value1, value2)
Just use that :
insert into my_table values (value1, value2)
i.e. don't specify the list of columns.
Of course, this will only work if you pass data for the columns in the order they are defined in the table, though.
if you have a table like (for example) :
CREATE TABLE test (
id INT(10),
field1 VARCHAR(16),
field2 TINYINT(1)
);
you can execute the query
INSERT INTO test VALUES (1, 'field1 value', 0);
The insert values must be in the same order as the declared columns. And as Galz mentioned it, you must set all fields, even the nullable or the auto incrementing ones. In fact, for the latter, you have to pass a null value.
For example, if id were to be a primary key set to "auto_increment", this query
INSERT INTO test VALUES (null, 'foo', 1);
SELECT * FROM test;
Would return
+----+--------------+--------+
| id | field1 | field2 |
+----+--------------+--------+
| 1 | field1 value | 0 |
| 2 | foo | 1 |
+----+--------------+--------+
On another subject, if you don't know beforehand what is the order of the fields, you can execute this query :
show columns from <table name>;
which, in this case would return
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(10) | YES | | NULL | |
| field1 | varchar(16) | YES | | NULL | |
| field2 | tinyint(1) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
Thus telling you that id is the first field, field1 is the second, and field2 is third.
Related
I have table with data on old game characters. I'd like to add a gender column.
If I do
ALTER TABLE characters
ADD gender ENUM('m','f') AFTER char_name
then I get a column full of NULLs. How do I get the values in?
Using an INSERT statement tries to tag them all into new rows, instead of replacing the NULLs.
Using an UPDATE statement requires a new statement for every single entry.
Is there any way to just drop a "VALUES ('m'),('f'),('f'),('m'),('f') etc" into the ALTER statement or anything else and update them all efficiently?
There is no way to fill in specific values during ALTER TABLE. The value will be NULL or else a default value you define for the column.
You may find INSERT...ON DUPLICATE KEY UPDATE is a convenient way to fill in the values.
Example:
CREATE TABLE characters (
id serial primary key,
char_name TEXT NOT NULL
);
INSERT INTO characters (char_name) VALUES
('Harry'), ('Ron'), ('Hermione');
SELECT * FROM characters;
+----+-----------+
| id | char_name |
+----+-----------+
| 1 | Harry |
| 2 | Ron |
| 3 | Hermione |
+----+-----------+
Now we add the gender column. It will add the new column with NULLs.
ALTER TABLE characters
ADD gender ENUM('m','f') AFTER char_name;
SELECT * FROM characters;
+----+-----------+--------+
| id | char_name | gender |
+----+-----------+--------+
| 1 | Harry | NULL |
| 2 | Ron | NULL |
| 3 | Hermione | NULL |
+----+-----------+--------+
Now we update the rows:
INSERT INTO characters (id, char_name, gender) VALUES
(1, '', 'm'), (2, '', 'm'), (3, '', 'f')
ON DUPLICATE KEY UPDATE gender = VALUES(gender);
It looks strange to use '' for the char_name, but it will be ignored anyway, because we don't set it in the ON DUPLICATE KEY clause. The original char_name is preserved. Specifying the value in the INSERT is necessary only because the column is defined NOT NULL and has no DEFAULT value.
SELECT * FROM characters;
+----+-----------+--------+
| id | char_name | gender |
+----+-----------+--------+
| 1 | Harry | m |
| 2 | Ron | m |
| 3 | Hermione | f |
+----+-----------+--------+
DBFiddle
I have one table. For example, we can call it mytable. This table for example has one column and this column is a boolean type, let's call this column mybool. When i want to create view like this: CREATE VIEW union_mytable AS SELECT * FROM mytable UNION ALL SELECT * FROM mytable; then type has changed tinyint where previously was
tinyint(1)
mytable:
mysql> DESCRIBE mytable;
+--------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------+------+-----+---------+-------+
| mybool | tinyint(1) | NO | | 0 | |
+--------+------------+------+-----+---------+-------+
union_mytable:
mysql> DESCRIBE union_mytable;
+--------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+-------+
| mybool | tinyint | NO | | 0 | |
+--------+---------+------+-----+---------+-------+
steps to recreate DB:
create table mytable (
mybool boolean not null default 0
);
insert into mytable () values ();
insert into mytable () values ();
describe mytable;
create view union_mytable select * from mytable union all select * from mytable;
describe union_mytable;
Database is MYSQL
It is possible to set this somehow to not cast this type manually to boolean?
Why this type is changing when union tables columns are the same?
Insert into the App.settings table the following values:
(99, DEFAULT, "horizontal", "2015-09-15 04:01:04")
I have a DATABASE called App with a settings table. I am trying to insert into the table but I can not seem to get it right.
My statement:
INSERT INTO App.settings
VALUES(99, DEFAULT, "horizontal", "2015-09-15 04:01:04");
Am I doing it right? It says my answer is wrong.
mysql> DESC App.settings;
+-----------------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+-------+
| user_id | int(7) | NO | | NULL | |
| email_frequency | tinyint(2) unsigned | YES | | NULL | |
| layout | varchar(70) | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+-----------------+---------------------+------+-----+---------+-------+
4 rows in set (0.01 sec)
When you use insert, always list the columns in the table. Second, the default string delimiter is the single quote in SQL rather than the double quote.
So I would expect to see:
INSERT INTO App.settings (col1, col3, col4) -- your real column names here
VALUES (99, 'horizontal', '2015-09-15 04:01:04');
Note that col2 was removed from the INSERT and the VALUES because you seem to want a DEFAULT value. Not all databases support that syntax.
you are sure that all the fields of the tuple are there and if so, they are in the correct order if you are not entering all the fields of the tuple you should use the following form: INSERT INTO App.settings(value, config, position, date ) VALUES(99, "DEFAULT", "horizontal", "2015-09-15 04:01:04");
In the same order
this is only an example i dont know the fields names you must be change for the you are using
Like #GordonLinoff said, you should include the columns in your query. That way, you can also skip entering the DEFAULT value for email_frequency.
As for the mistake, it's most likely the double quotes that you're currently using instead of single quotes.
Try the following:
INSERT INTO App.settings (user_id, layout, updated_at)
VALUES (99, 'horizontal', '2015-09-15 04:01:04');
My database has,
mysql> describe students;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
And I'd like to insert 2 students - but I want to know thier IDs immediately
mysql> insert into students values (null, 'tom'), (null, 'larry');
I'd like it if insert actually returned a result set of the IDs... aka...
mysql> select id from (insert into students values (null, 'tom'), (null, 'larry'));
Humm?
You can use the LAST_INSERT_ID() function to get the first AUTO INCREMENT value of the batch and then MAX to get the greatest value.
LAST_INSERT_ID() (with no argument) returns a BIGINT (64-bit) value representing the first automatically generated value that was set for an AUTO_INCREMENT column by the most recently executed INSERT statement to affect such a column.
Reference
> INSERT INTO students VALUES (NULL, 'tom'), (NULL, 'larry');
> SELECT LAST_INSERT_ID() FROM students LIMI 1
| LAST_INSERT_ID() |
--------------------
| 1 |
> SELECT MAX(id) FROM students
| MAX(ID) |
-----------
| 2 |
> INSERT INTO students VALUES (NULL, 'billy'), (NULL, 'jane'), (NULL, 'fred');
> SELECT LAST_INSERT_ID() FROM students LIMIT 1
| LAST_INSERT_ID() |
--------------------
| 3 |
> SELECT MAX(id) FROM students
| MAX(ID) |
-----------
| 5 |
I'm looking for a simple upsert (Update/Insert). The tables looks like this
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| email | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
There is no key here. The idea is to insert if email is different, else update. The Insert on duplicate key in mysql doesn't suit the purpose.
Is there an elegant way to do this?
If you cannot add a unique key on the email column, you'll check to see if the record exists first (preferably in a transaction):
SELECT id FROM mytable WHERE email = 'my#example.com' FOR UPDATE
then update the record if it exists:
UPDATE mytable SET name = 'my name' WHERE id = ?
otherwise insert it:
INSERT INTO mytable (name, email) VALUES ('my name', 'my#example.com')
what about:
REPLACE INTO table VALUES(1,'hello', 'world#example.com');