2010-07-04 43 views
16

Tôi muốn cập nhật tất cả các lĩnh vực NULL trong một bảng để 0. Tất nhiêncập nhật tất cả các lĩnh vực NULL MySQL

UPDATE mytable SET firstcol=0 WHERE firstcol IS NULL 

sẽ thực hiện công việc. Nhưng tôi tự hỏi nếu có một giải pháp thông minh hơn chỉ c & p dòng này cho mỗi cột.

+1

Ra khỏi tò mò bao nhiêu cột mà bạn có mà bạn cần thay đổi từ null để 0 hoặc w/e ehhe :) – Prix

+0

Nó ´ chỉ tò mò thôi. Trong trường hợp đặc biệt này, tôi sẽ không cần bất cứ thứ gì vì nó chỉ là 5 hoặc 6 cols. Nhưng các bảng khác tôi làm việc với dễ dàng có 60 cột. Đó là lý do tại sao tôi muốn biết làm thế nào để làm điều đó trong một kịch bản như vậy quá. –

Trả lời

6

Can bạn chỉ ALTER các cột để NOT NULL DEFAULT 0?

Bạn có thể làm điều này trong một tuyên bố duy nhất, theo MySQL documentation:

Bạn có thể phát hành nhiều ADD, ALTER, DROP, và khoản CHANGE về một ALTER TABLE tuyên bố duy nhất, cách nhau bằng dấu phẩy. Đây là một phần mở rộng MySQL cho SQL chuẩn, cho phép chỉ có một mệnh đề cho mỗi câu lệnh ALTER TABLE.

+0

Hmm, bảng được tạo bằng bảng tạo bảng mytable AS SELECT ... câu lệnh có chứa các trường hợp. Bằng cách nào đó tôi đã không thể đặt giá trị mặc định ở đó. Đó là lý do tại sao tôi đã kết thúc với các giá trị NULL. Nếu tôi thay đổi bảng đó, tôi phải làm điều đó cho mỗi cột riêng biệt, đó là chính xác những gì tôi đang cố gắng để ngăn chặn. –

+0

@ ran2: Không phải trong MySQL bạn không - chỉnh sửa để phản ánh điều này. – Piskvor

+0

thx, rõ ràng là tôi không biết về thực tế này. Tuy nhiên, tôi tự hỏi nếu tôi phải liệt kê tất cả các cột trong một câu lệnh ALTER như vậy. Tôi chỉ muốn làm điều đó cho toàn bộ bảng, bởi vì nếu tôi có 60 cột, nó sẽ xấu xí để liệt kê tất cả các em - không có vấn đề nếu trong một hoặc nhiều báo cáo. –

2

Không có công nghệ hoặc con trỏ trung gian. Bạn có thể sử dụng DESCRIBE mytable; để lấy tên cột và lặp lại chúng để tạo các truy vấn UPDATE.

Vì vậy, điều đó là có thể. Nhưng vào thời điểm bạn viết nó, bạn có thể chỉ cần sao chép và dán;)

+0

Tôi phải thừa nhận, hoặc là tôi không nhận được câu trả lời hoặc chỉ đăng tải nặng. Tuy nhiên, những gì Jason nói là những gì tôi cảm thấy. Tôi chỉ tự hỏi nếu có một giải pháp nhưng một vòng lặp. Tôi chỉ không cần vòng lặp trong SQL cho đến nay và do đó không có kinh nghiệm :) –

+0

IMO, đây là một điều tầm thường. Chỉ cần chạy báo cáo của bạn bằng cách sao chép và dán. Tôi đồng ý với những người khác mặc dù. Nếu bạn bắt đầu từ đầu, bạn có thể đã thêm một 'DEFAULT 0' vào các cột của bạn. –

5

Bạn có thể muốn thay đổi các cột của mình thành NOT NULL.

ALTER TABLE your_table MODIFY COLUMN your_field INT NOT NULL; 

Kiểm tra trường hợp:

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

Kết quả:

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

ran2 có thể muốn làm điều đó trong thời gian dài, nhưng điều đó không nên cập nhật các hàng đã tồn tại. Ít nhất, tôi hy vọng nó không cập nhật các hàng đã tồn tại. –

+0

@Brian: Nó có :) ... (Tôi nghĩ rằng trừ khi chạy ở chế độ nghiêm ngặt.) –

+0

Có, công trình này. Lưu ý rằng bạn có thể nhận được cảnh báo 'DATA TRUNCATED' khá chung chung, nhưng không có gì thực sự bị cắt ngắn - nó chỉ là một trong những thông báo lỗi [hơi gây nhầm lẫn] [http://dev.mysql.com/doc/refman/5.1/en /faqs-cjk.html#qandaitem-24-11-1-1). – Mike

0

Tôi không tin là có; bất kỳ câu lệnh nào hoạt động trên các hàng không thỏa mãn mệnh đề where sẽ cập nhật các hàng bạn không có ý định cập nhật. Câu trả lời của Jason là đúng, nhưng, tôi nghĩ, một chút không an toàn, trừ khi bạn thực sự chắc chắn đó là những gì bạn muốn.

14

Bạn có thể làm điều này - lặp lại khi cần thiết cho mỗi cột:

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

Ví dụ:

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

CẬP NHẬT

Nếu bạn muốn thay đổi cấu trúc bảng bằng cách thay đổi cột để họ không còn chấp nhận null, bạn có thể làm điều đó với một thủ tục được lưu trữ. Các thủ tục được lưu trữ sau truy vấn INFORMATION_SCHEMA COLUMNS để biết thông tin về các cột trong một bảng cơ sở dữ liệu đã cho. Từ thông tin đó, nó xây dựng một câu lệnh chuẩn bị sau đó được sử dụng để thay đổi cấu trúc bảng.Bạn có thể cần phải tinh chỉnh nó cho phù hợp với yêu cầu chính xác của bạn - tại thời điểm này, có vẻ cho INT cột mà không có NOT NULL thiết lập:

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 ; 

Ví dụ:

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 

Các dòng sau sẽ hiển thị lệnh đó là để được thực thi, và có thể được gỡ bỏ từ thủ tục lưu trữ nếu cần thiết:

SELECT @alter_cmd; 
+0

tôi chỉ sử dụng 'CÀI ĐẶT kiểm tra SET userID = IFNULL (userId, 1);' và nó đã làm việc –

0

ALTER TABLE 01.. tableName THÊM COLUMN columnX INT (20) NULL DEFAULT 1 SAU columnY;

Nó sau

  1. thêm một cột mới columnX sau columnY.
  2. đặt giá trị của nó để mặc định 1 trong suốt cột columnX

  columnY    columnX 

     | cellValueA  |  1  |   
     | cellValueB  |  1  | 
     | cellValueC  |  1  | 
     | cellValueD  |  1  | 
Các vấn đề liên quan