I would like to insert a row with only the default values (which I will then update later since I need the ID autoincremented field)
This works in SQL Server (How to insert a record with only default values?)
insert into myTable DEFAULT VALUES;
But how can I accomplish this in MySQL:
I also tried:
insert into myTable;
which fails. I know I can work around with the standard insert syntax, but there are a lot of columns in my table so a simple syntax if it exists would be helpful.
This will do it :
INSERT INTO `myTable` (`id`)
VALUES
(null),
(null);
-- or
INSERT INTO `myTable` ()
VALUES();
SQL Fiddle
MySQL 5.6 Schema Setup:
CREATE TABLE Table1
(`id` int AUTO_INCREMENT PRIMARY KEY, `title` varchar(5) DEFAULT '***')
;
INSERT INTO Table1
(`id`, `title`)
VALUES
(1, 'hi'),
(2, 'hello')
;
INSERT INTO Table1
(`id`)
VALUES
(null),
(null)
;
INSERT INTO Table1 () VALUES();
Query 1:
SELECT * from Table1
Results:
| id | title |
|----|-------|
| 1 | hi |
| 2 | hello |
| 3 | *** |
| 4 | *** |
| 5 | *** |
Related
I'm confused when inserting null data (records with null field) into NOT NULL columns.
The mysql table disables STRICT-SQL-MODE.
According to thess two docs, it was supposed to work but the truth is not.
https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sql-mode-strict
https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html#data-type-defaults-implicit
For data entry into a NOT NULL column that has no explicit DEFAULT clause, if an INSERT or REPLACE statement includes no value for the column, or an UPDATE statement sets the column to NULL, MySQL handles the column according to the SQL mode in effect at the time:
If strict SQL mode is enabled, an error occurs for transactional tables and the statement is rolled back. For nontransactional tables, an error occurs, but if this happens for the second or subsequent row of a multiple-row statement, the preceding rows are inserted.
If strict mode is not enabled, MySQL sets the column to the implicit default value for the column data type.
When I insert a batch of records (with null field), for example 100 records, it works.
But when I insert only one record with null field, it failes with the message: ERROR 1048 (23000): Column 'int_without_default' cannot be null.
My question is how to insert single record with null field into NOT NULL column.
Here is the test case I made:
Create a table with two columns with 'NOT NULL' requirement:
CREATE TABLE `test_table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`int_without_default` int(11) NOT NULL,
`int_with_default` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='for test';
Sql mode of the table
mysql> SELECT ##GLOBAL.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ##GLOBAL.sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select ##SESSION.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ##SESSION.sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
Inserting single record with null caused failure:
-- ERROR 1048 (23000): Column 'int_without_default' cannot be null
insert into `test_table` (`int_without_default`,`int_with_default`)
value (null, 123);
-- ERROR 1048 (23000): Column 'int_with_default' cannot be null
insert into `test_table` (`int_without_default`,`int_with_default`)
value (123, null);
-- ERROR 1048 (23000): Column 'int_without_default' cannot be null
insert into `test_table` (`int_without_default`,`int_with_default`)
values (null, 123);
-- ERROR 1048 (23000): Column 'int_with_default' cannot be null
insert into `test_table` (`int_without_default`,`int_with_default`)
values (123, null);
But inserting multiple records with null worked. (I print the result below)
-- success
insert into `test_table` (`int_without_default`,`int_with_default`)
values
(null, 123),
(null, 456);
-- success
insert into `test_table` (`int_without_default`,`int_with_default`)
values
(123, null),
(456, null);
-- ERROR 1048 (23000): Column 'int_without_default' cannot be null
insert into `test_table` (`int_without_default`,`int_with_default`)
values
(null, null);
-- success
insert into `test_table` (`int_without_default`,`int_with_default`)
values
(null, null),
(null, null);
After executing above sql statement, the content of the table:
mysql> select * from test_table;
+----+---------------------+------------------+
| id | int_without_default | int_with_default |
+----+---------------------+------------------+
| 1 | 0 | 123 |
| 2 | 0 | 456 |
| 3 | 123 | 0 |
| 4 | 456 | 0 |
| 5 | 0 | 0 |
| 6 | 0 | 0 |
+----+---------------------+------------------+
6 rows in set (0.00 sec)
operation screenshot
On the table dotable of MySQL database 8.0.12 version I have set this decimal field
Num_cl decimal(10,5)
The table contains this data
+-------+--------+
| id | Num_cl |
+-------+--------+
| 46777 | 1,00 |
| 46778 | 0,00 |
| 46779 | 1,00 |
| 46780 | 1,00 |
| 46781 | 0,00 |
+-------+--------+
I need select all rows of dotable with Num_cl value is greater than to zero
I have tried this query
SELECT
ID,
Num_cl
FROM
dotable
WHERE
CONVERT (Num_cl, SIGNED INTEGER) > 0;
the return is Empty set
How to do resolve this?
Table structure for dotable
-- ----------------------------
-- Table structure for dotable
-- ----------------------------
DROP TABLE IF EXISTS `dotable`;
CREATE TABLE `dotable` (
`ID` int(10) NOT NULL AUTO_INCREMENT,
`Num_cl` decimal(10, 5) NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = MyISAM;
INSERT INTO `dotable` VALUES (46777, 1.00);
INSERT INTO `dotable` VALUES (46778, 0.00);
INSERT INTO `dotable` VALUES (46779, 1.00);
INSERT INTO `dotable` VALUES (46780, 1.00);
INSERT INTO `dotable` VALUES (46781, 0.00);
update
DROP TABLE IF EXISTS `dotable`;
CREATE TABLE `dotable` (
`ID` int(10) NOT NULL AUTO_INCREMENT,
`Num_cl` decimal(10, 5) NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = MyISAM;
INSERT INTO `dotable` VALUES (46777, 1.00);
INSERT INTO `dotable` VALUES (46778, 0.00);
INSERT INTO `dotable` VALUES (46779, 1.00);
INSERT INTO `dotable` VALUES (46780, 1.00);
INSERT INTO `dotable` VALUES (46781, 0.00);
SELECT
ID,
Num_cl
FROM
dotable
WHERE
CONVERT (Num_cl, SIGNED INTEGER) > 0;
+-------+---------+
| ID | Num_cl |
+-------+---------+
| 46777 | 1.00000 |
| 46779 | 1.00000 |
| 46780 | 1.00000 |
+-------+---------+
3 rows in set (0.02 sec)
Consider following scheme:
CREATE TABLE IF NOT EXISTS `test` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
--
-- Dumping data for table `test`
--
INSERT INTO `test` (`user_id`, `username`) VALUES
(1, 'Jason'),
(2, 'OOO'),
(3, 'Stack'),
(4, 'Overflow');
And this query:
SELECT * FROM TEST WHERE username = 0
It Shows:
| USER_ID | USERNAME |
----------|----------|--
| 1 | Jason |
| 2 | OOO |
| 3 | Stack |
| 4 | Overflow |
But not when username = '0' or when username = 1
Here is SQLFIDDLE DEMO
Since the username is String and you have compared it to a Number, MySQL silently cast the column name into number. See Here.
When the string is cast into a number and it starts with a letter, the value will be zero, that's why all the records are shown.
The adding a username of 5, like this demo, you'll see all the records except with this username since 5 <> 0.
so I have two tables linked by the key 'skillid':
skills
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| skillid | int(11) | NO | PRI | NULL | auto_increment |
| skillname | varchar(30) | NO | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
students_skills
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| ssid | int(11) | NO | PRI | NULL | auto_increment |
| studentid | int(11) | NO | MUL | NULL | |
| skillid | int(11) | NO | MUL | NULL | |
+-----------+---------+------+-----+---------+----------------+
I'm trying to insert multiple rows into the table skills, and then insert these into student_skills based on the ID that was created. I've been looking into using the LAST_INSERT_ID() function:
INSERT INTO skills (skillid , skillname)
VALUES(NULL,'being grateful for help'); # generate ID by inserting NULL
INSERT INTO students_skills (ssid, studentid, skillid)
VALUES(LAST_INSERT_ID(),'1', '2'); # use ID in second table
But I couldn't figure out how to do this for multiple rows at once in one mysql table. I get an error when i simply duplicate the above 4 lines for every row.
ERROR: #1452 - Cannot add or update a child row: a foreign key
constraint fails (empology.students_skills, CONSTRAINT
students_skills_ibfk_2 FOREIGN KEY (skillid) REFERENCES skills
(skillid))
Am I on the right lines or not? I looked into joins also but this method made more sense to me.
Thanks for any help or useful links.
You have to make sure to use multiple-row insert syntax so that the LAST_INSERT_ID() stays consistent even though you're auto-incrementing another column:
INSERT INTO skills VALUES (NULL, 'test');
Say the skillid generated was 1, you can then do:
INSERT INTO student_skills VALUES
(NULL, 1, LAST_INSERT_ID()),
(NULL, 2, LAST_INSERT_ID()),
(NULL, 3, LAST_INSERT_ID()),
(NULL, 4, LAST_INSERT_ID());
The value returned by LAST_INSERT_ID() will consistently stay the same (1) throughout all four rows.
However, if you execute multiple inserts as standalone statements, LAST_INSERT_ID() will change as it will instead contain the generated auto-incremented value of each insert:
INSERT INTO student_skills VALUES (NULL, 1, LAST_INSERT_ID());
INSERT INTO student_skills VALUES (NULL, 2, LAST_INSERT_ID());
INSERT INTO student_skills VALUES (NULL, 3, LAST_INSERT_ID());
INSERT INTO student_skills VALUES (NULL, 4, LAST_INSERT_ID());
Where LAST_INSERT_ID() is the generated id of the immediate previous insert.
Take a look at this SQLFiddle Demo
Since students_skills.ssid is an AUTO_INCREMENT column, your second insert looks wrong. It seems you want the following:
INSERT INTO skills (skillid , skillname)
VALUES(NULL,'being grateful for help'); # generate ID by inserting NULL
INSERT INTO students_skills (ssid, studentid, skillid)
VALUES(NULL,'1', LAST_INSERT_ID()); # use ID in second table
It would be helpful to see the output of
SHOW CREATE TABLE skills;
SHOW CREATE TABLE students_skills;
to see the FOREIGN KEYs.
UPDATE TO SHOW OUTPUTS
+--------+------------------------------------------------------------------------------
| Table | Create Table
+--------+------------------------------------------------------------------------------
| skills | CREATE TABLE `skills` (
`skillid` int(11) NOT NULL AUTO_INCREMENT,
`skillname` varchar(30) NOT NULL,
PRIMARY KEY (`skillid`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1 |
+--------+------------------------------------------------------------------------------
+-----------------+---------------------------------------------------------------------
| Table | Create Table
+-----------------+---------------------------------------------------------------------
| students_skills | CREATE TABLE `students_skills` (
`ssid` int(11) NOT NULL AUTO_INCREMENT,
`studentid` int(11) NOT NULL,
`skillid` int(11) NOT NULL,
PRIMARY KEY (`ssid`),
KEY `studentid` (`studentid`),
KEY `skillid` (`skillid`),
CONSTRAINT `students_skills_ibfk_1` FOREIGN KEY (`studentid`) REFERENCES `students` (`studentid`),
CONSTRAINT `students_skills_ibfk_2` FOREIGN KEY (`skillid`) REFERENCES `skills` (`skillid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 |
+-----------------+--------------------------------------------------------------------
I'd like to update all NULL fields in one table to 0. Of course
UPDATE mytable SET firstcol=0 WHERE firstcol IS NULL
would do the job. But I wonder if thereĀ“s a smarter solution than just c&p this line for every column.
You could do this - repeat as necessary for each column:
UPDATE `table1` SET
`col1` = IFNULL(col1, 0),
`col2` = IFNULL(col2, 0);
Example:
DROP TABLE IF EXISTS `table1`;
CREATE TABLE `table1` (
`id` int(10) unsigned NOT NULL auto_increment,
`col1` int(10) unsigned,
`col2` int(10) unsigned,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `table1` VALUES
(1, 1, NULL),
(2, NULL, NULL),
(3, 2, NULL),
(4, NULL, NULL),
(5, 3, 4),
(6, 5, 6),
(7, 7, NULL);
UPDATE `table1` SET
`col1` = IFNULL(col1, 0),
`col2` = IFNULL(col2, 0);
SELECT * FROM `table1`;
+----+------+------+
| id | col1 | col2 |
+----+------+------+
| 1 | 1 | 0 |
| 2 | 0 | 0 |
| 3 | 2 | 0 |
| 4 | 0 | 0 |
| 5 | 3 | 4 |
| 6 | 5 | 6 |
| 7 | 7 | 0 |
+----+------+------+
UPDATE
If you want to alter the table structure by changing columns so that they no longer accept nulls, you could do it with a stored procedure. The following stored procedure queries the INFORMATION_SCHEMA COLUMNS for information about columns in a given database table. From that information, it builds up a prepared statement which is then used to alter the table structure. You may need to tweak it to suit your exact requirements - at the moment, it looks for INT columns which do not have NOT NULL set:
delimiter //
DROP PROCEDURE IF EXISTS no_nulls//
CREATE PROCEDURE `no_nulls` (IN param_schema CHAR(255), IN param_table CHAR(255))
BEGIN
SET #alter_cmd = (SELECT CONCAT(
'ALTER TABLE ',
param_table,
GROUP_CONCAT(
' MODIFY COLUMN ',
`column_name`, ' ',
`column_type`,
' NOT NULL'
SEPARATOR ', ')
) AS `sql_cmd`
FROM INFORMATION_SCHEMA.COLUMNS
WHERE `table_schema` = param_schema
AND `table_name` = param_table
AND LCASE(`data_type`) = 'int'
AND LCASE(`is_nullable`) = 'yes');
IF NOT ISNULL(#alter_cmd) THEN
SELECT #alter_cmd;
PREPARE stmt FROM #alter_cmd;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END//
delimiter ;
Example:
CREATE TABLE `test`.`table1` (
`id` int(10) unsigned NOT NULL auto_increment,
`col1` int(10) unsigned,
`col2` int(10) unsigned,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CALL no_nulls('test', 'table1');
+----------------------------------------------------------------------------------------------------------------+
| #alter_cmd |
+----------------------------------------------------------------------------------------------------------------+
| ALTER TABLE table1 MODIFY COLUMN col1 int(10) unsigned NOT NULL, MODIFY COLUMN col2 int(10) unsigned NOT NULL |
+----------------------------------------------------------------------------------------------------------------+
SHOW CREATE TABLE `test`.`table1`;
CREATE TABLE `table1` (
`id` int(10) unsigned NOT NULL auto_increment,
`col1` int(10) unsigned NOT NULL,
`col2` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
The following line displays the command that is to be executed, and may be removed from the stored procedure if necessary:
SELECT #alter_cmd;
Can you just ALTER the columns to NOT NULL DEFAULT 0?
You can do this in a single statement, as per MySQL documentation:
You can issue multiple ADD, ALTER, DROP, and CHANGE clauses in a single ALTER TABLE statement, separated by commas. This is a MySQL extension to standard SQL, which allows only one of each clause per ALTER TABLE statement.
You may want to alter your columns to NOT NULL.
ALTER TABLE your_table MODIFY COLUMN your_field INT NOT NULL;
Test case:
CREATE TABLE nulltable (id INT);
INSERT INTO nulltable VALUES (1);
INSERT INTO nulltable VALUES (2);
INSERT INTO nulltable VALUES (3);
INSERT INTO nulltable VALUES (NULL);
INSERT INTO nulltable VALUES (NULL);
INSERT INTO nulltable VALUES (NULL);
INSERT INTO nulltable VALUES (5);
Result:
mysql> SELECT * FROM nulltable;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| NULL |
| NULL |
| NULL |
| 5 |
+------+
7 rows in set (0.00 sec)
mysql> ALTER TABLE nulltable MODIFY COLUMN id INT NOT NULL;
Query OK, 7 rows affected, 3 warnings (0.08 sec)
Records: 7 Duplicates: 0 Warnings: 3
mysql> SELECT * FROM nulltable;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 0 |
| 0 |
| 0 |
| 5 |
+----+
7 rows in set (0.00 sec)
Not without an intermediate technology or cursor. You could use DESCRIBE mytable; to get the column names and loop over them to build your UPDATE queries.
So it is possible. But by the time it took you to write that, you probably just could have copy and pasted ;)
This worked for me!
UPDATE `results` SET
column1 = IFNULL(column1,0),
column2 = IFNULL(column2,'');
This is mike's answer but without the quotes for columns on the left !
Note: If you are trying to set your values '0' instead of an empty string if a column's datatype is int
I don't believe there is; any statement that worked on rows that didn't satisfy the where clause would update rows you didn't intent to update. Jason's answer is correct, but, I think, a bit unsafe, unless you are really sure that's what you want.
ALTER TABLE dataBaseName.tableName
ADD COLUMN columnX INT(20) NULL DEFAULT 1 AFTER columnY;
It does the following
adds a new column columnX after columnY.
sets its value to default 1 throughout the column columnX
columnY columnX
| cellValueA | 1 |
| cellValueB | 1 |
| cellValueC | 1 |
| cellValueD | 1 |