更新所有NULL字段MySQL

时间:2010-07-04 15:16:41

标签: mysql sql-update

我想将一个表中的所有NULL字段更新为0.当然

UPDATE mytable SET firstcol=0 WHERE firstcol IS NULL 

会做这个工作。但我想知道是否有一个更聪明的解决方案,而不仅仅是为每一列c& p这条线。

7 个答案:

答案 0 :(得分:14)

您可以这样做 - 根据需要重复每列:

UPDATE `table1`  SET
    `col1` = IFNULL(col1, 0),
    `col2` = IFNULL(col2, 0);

示例:

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 |
+----+------+------+

<强>更新

如果要通过更改列来更改表结构以使它们不再接受空值,则可以使用存储过程来执行此操作。以下存储过程查询INFORMATION_SCHEMA COLUMNS以获取有关给定数据库表中列的信息。根据该信息,它构建一个准备好的语句,然后用于更改表结构。您可能需要调整它以满足您的确切要求 - 目前,它会查找没有设置INT的{​​{1}}列:

NOT NULL

示例:

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 ;

以下行显示要执行的命令,如有必要,可以从存储过程中删除:

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

答案 1 :(得分:6)

您可以ALTERNOT NULL DEFAULT 0吗?

根据MySQL documentation

,您可以在一个语句中执行此操作
  

您可以在单个ALTER TABLE语句中发出多个ADD,ALTER,DROP和CHANGE子句,以逗号分隔。这是标准SQL的MySQL扩展,它只允许每个ALTER TABLE语句中的一个子句。

答案 2 :(得分:5)

您可能希望将列更改为NOT NULL

ALTER TABLE your_table MODIFY COLUMN your_field INT NOT NULL;

测试用例:

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);

结果:

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)

答案 3 :(得分:2)

不是没有中间技术或光标。您可以使用DESCRIBE mytable;获取列名称并循环遍历它们以构建UPDATE个查询。

所以有可能。但是当你写这篇文章时,你可能只能复制和粘贴;)

答案 4 :(得分:0)

我不相信有;任何处理不满足where子句的行的语句都会更新您不想更新的行。杰森的回答是正确的,但我认为,有点不安全,除非你确定这就是你想要的。

答案 5 :(得分:0)

ALTER TABLE dataBaseNametableName 添加列columnX INT(20)NULL {1}}之后的默认值1

执行以下操作

  1. 在columnY后添加新列columnX。
  2. 在整个列columnX
  3. 中将其值设置为默认值1
    columnY

答案 6 :(得分:0)

这对我有用!

UPDATE `results`  SET
    column1  = IFNULL(column1,0),
    column2  = IFNULL(column2,'');

这是迈克的答案,但左边的列没有引号!

注意:如果您尝试将值设置为“ 0”而不是空字符串(如果列的数据类型为 int