MySQL tải NULL trong các cột số


8

MySQL 5.6,23, InnoDB

Tôi đang tải các bảng từ các tệp văn bản được phân tách bằng ký tự bằng LOAD DATA INFILEcommnd và tôi muốn mọi trường có a \N, là NULLký tự trong cài đặt này, để đặt một NULLtrong bảng. Một số loại số có hành vi này, trong khi những loại khác đặt a 0. Tôi đang sử dụng FIELDS TERMINATED BYmột số cột thực hiện đúng NULLcác giá trị, vì vậy nó không phải là vấn đề định dạng hàng cố định.

Đây là những loại tôi đã quan sát trong khi thử nghiệm:

  • INTchèn NULLs
  • DECIMAL(x,0)chèn NULLs
  • DECIMAL(x,y)chèn 0.0s
  • FLOATchèn 0s
  • DOUBLE(x,y)chèn 0.0s
  • DOUBLEchèn 0s

Tất cả các cột trong câu hỏi được xác định với DEFAULT NULL. Tôi biết rằng các chức năng khác nhau có thể chuyển đổi các 0s thành NULLs. Câu hỏi là liệu có một kiểu dữ liệu có thể xử lý độ chính xác thập phân và cũng sẽ chèn NULLs khi tải.

Ngoài ra, tôi thấy một loạt các câu hỏi liên quan đến sự hiểu lầm về sự khác biệt giữa một chuỗi, một chuỗi rỗng và một giá trị null. ( ví dụ dụ ) Đây không phải là vấn đề, vì các NULLs ở đó và được tải đúng vào cùng một cột khi tôi xác định lại nó là DECIMAL (x, 0), sau đó không chính xác khi được định nghĩa là DECIMAL (x, 3).

Câu trả lời:


5

Câu trả lời rất ngắn: Không có kiểu dữ liệu mới nào được tạo để chứa bạn.

Trong khi chúng ta đang ở trong chủ đề này

Hãy thử SQL đơn giản

USE test
DROP TABLE IF EXISTS numtest;
CREATE TABLE numtest
(
  id int not null auto_increment,
  xx decimal(10,3) default null,
  primary key (id)
);
INSERT INTO numtest (id) values (0),(0),(0),(0),(0);
SELECT * FROM numtest;

Cái này có hoạt động không ???

mysql> USE test
Database changed
mysql> DROP TABLE IF EXISTS numtest;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE numtest
    -> (
    ->   id int not null auto_increment,
    ->   xx decimal(10,3) default null,
    ->   primary key (id)
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO numtest (id) values (0),(0),(0),(0),(0);
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM numtest;
+----+------+
| id | xx   |
+----+------+
|  1 | NULL |
|  2 | NULL |
|  3 | NULL |
|  4 | NULL |
|  5 | NULL |
+----+------+
5 rows in set (0.00 sec)

mysql>

Được rồi Nó hoạt động với SQL. Bạn đang hỏi vềLOAD DATA INFILE

Bạn đã đưa ra một bài đăng tôi đã trả lời: MySQL đang chèn "" là 0 trong các trường thập phân. Làm thế nào để ngăn chặn điều đó?

Hãy xem lỗi đó đã được xử lý từ khi nó được gửi chưa. Tôi sẽ cố gắng sao chép mã trong lỗi đó không hoạt động.

Trước tiên hãy tạo bảng đó từ báo cáo lỗi

mysql> USE test
Database changed
mysql> DROP TABLE IF EXISTS bug_repeat;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE TABLE bug_repeat
    -> (
    ->   name varchar(10),
    ->   price decimal(12,6)
    -> )
    -> ENGINE=MYISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW CREATE TABLE bug_repeat\G
*************************** 1. row ***************************
       Table: bug_repeat
Create Table: CREATE TABLE `bug_repeat` (
  `name` varchar(10) COLLATE ascii_bin DEFAULT NULL,
  `price` decimal(12,6) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin
1 row in set (0.00 sec)

mysql>

Tiếp theo, hãy tạo một số dữ liệu

C:\>type C:\MySQLDBA\bug_test.txt
name,
name,0
,
name,6
name,2
name,
name,0
name,0
name,
name,0

C:\>

Hãy chạy INFILE DỮ LIỆU

mysql> load data local infile 'C:/MySQLDBA/bug_test.txt'
    -> into table test.bug_repeat
    -> fields terminated by ','
    -> lines terminated by '\n';
Query OK, 10 rows affected, 4 warnings (0.00 sec)
Records: 10  Deleted: 0  Skipped: 0  Warnings: 4

Ôi, chuyện gì đã xảy ra

mysql> show warnings\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 1lue: '
*************************** 2. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 3lue: '
*************************** 3. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 6lue: '
*************************** 4. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 9lue: '
4 rows in set (0.00 sec)

mysql> select * from bug_repeat;
+------+----------+
| name | price    |
+------+----------+
| name | 0.000000 |
| name | 0.000000 |
|      | 0.000000 |
| name | 6.000000 |
| name | 2.000000 |
| name | 0.000000 |
| name | 0.000000 |
| name | 0.000000 |
| name | 0.000000 |
| name | 0.000000 |
+------+----------+
10 rows in set (0.00 sec)

mysql>

S sql_mode là gì?

mysql> select @@sql_mode;
+------------------------+
| @@sql_mode             |
+------------------------+
| NO_ENGINE_SUBSTITUTION |
+------------------------+
1 row in set (0.00 sec)

mysql>

Hãy bỏ trống sql_mode, cắt bớt bảng và tải lại

mysql> set sql_mode = '';
Query OK, 0 rows affected (0.00 sec)

mysql> select @@sql_mode;
+------------+
| @@sql_mode |
+------------+
|            |
+------------+
1 row in set (0.00 sec)

mysql> truncate table bug_repeat;
Query OK, 0 rows affected (0.00 sec)

mysql> load data local infile 'C:/MySQLDBA/bug_test.txt'
    -> into table test.bug_repeat
    -> fields terminated by ','
    -> lines terminated by '\n';
Query OK, 10 rows affected, 4 warnings (0.02 sec)
Records: 10  Deleted: 0  Skipped: 0  Warnings: 4

mysql> show warnings\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 1lue: '
*************************** 2. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 3lue: '
*************************** 3. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 6lue: '
*************************** 4. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 9lue: '
4 rows in set (0.00 sec)

mysql>

Hãy để bác sĩ tập tin đầu vào \Ngiống như báo cáo lỗi

C:\>type C:\MySQLDBA\bug_test.txt
name,\N
name,0
\N,\N
name,6
name,2
name,\N
name,0
name,0
name,\N
name,0

C:\>

Hãy lặp lại tất cả những điều này với InnoDB

mysql> USE test
Database changed
mysql> DROP TABLE IF EXISTS bug_repeat;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE bug_repeat
    -> (
    ->   name varchar(10),
    ->   price decimal(12,6)
    -> )
    -> ENGINE=InnoDB;
Query OK, 0 rows affected (0.05 sec)

mysql> truncate table bug_repeat;
Query OK, 0 rows affected (0.05 sec)

mysql> load data local infile 'C:/MySQLDBA/bug_test.txt'
    -> into table test.bug_repeat
    -> fields terminated by ','
    -> lines terminated by '\n';
Query OK, 10 rows affected, 4 warnings (0.00 sec)
Records: 10  Deleted: 0  Skipped: 0  Warnings: 4

mysql> show warnings\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 1lue: 'N
*************************** 2. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 3lue: 'N
*************************** 3. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 6lue: 'N
*************************** 4. row ***************************
  Level: Warning
   Code: 1366
' for column 'price' at row 9lue: 'N
4 rows in set (0.00 sec)

mysql> select * from bug_repeat;
+------+----------+
| name | price    |
+------+----------+
| name | 0.000000 |
| name | 0.000000 |
| NULL | 0.000000 |
| name | 6.000000 |
| name | 2.000000 |
| name | 0.000000 |
| name | 0.000000 |
| name | 0.000000 |
| name | 0.000000 |
| name | 0.000000 |
+------+----------+
10 rows in set (0.00 sec)

mysql>

Tôi đang sử dụng phiên bản MySQL nào ???

mysql> show global variables like 'version%';
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| version                 | 5.6.22                       |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | Win64                        |
+-------------------------+------------------------------+
4 rows in set (0.00 sec)

mysql>

Còn Linux thì sao ???

$ cat /tmp/bug_test.txt
name,\N
name,0
\N,\N
name,6
name,2
name,\N
name,0
name,0
name,\N
name,0

$

Đăng nhập vào mysql và thử ...

mysql> create database test;
Query OK, 1 row affected (0.01 sec)

mysql> USE test
Database changed
mysql> DROP TABLE IF EXISTS bug_repeat;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE TABLE bug_repeat
    -> (
    ->   name varchar(10),
    ->   price decimal(12,6)
    -> )
    -> ENGINE=InnoDB;
Query OK, 0 rows affected (0.09 sec)

mysql> truncate table bug_repeat;
Query OK, 0 rows affected (0.04 sec)

mysql> load data local infile 'C:/MySQLDBA/bug_test.txt'
    -> into table test.bug_repeat
    -> fields terminated by ','
    -> lines terminated by '\n';
ERROR 2 (HY000): File 'C:/MySQLDBA/bug_test.txt' not found (Errcode: 2 - No such file or directory)
mysql> show warnings\G
Empty set (0.00 sec)

mysql> select * from bug_repeat;
Empty set (0.00 sec)

mysql> truncate table bug_repeat;
Query OK, 0 rows affected (0.04 sec)

mysql> load data local infile '/tmp/bug_test.txt'
    -> into table test.bug_repeat
    -> fields terminated by ','
    -> lines terminated by '\n';
Query OK, 10 rows affected (0.00 sec)
Records: 10  Deleted: 0  Skipped: 0  Warnings: 0

mysql> show warnings\G
Empty set (0.00 sec)

mysql> select * from bug_repeat;
+------+----------+
| name | price    |
+------+----------+
| name |     NULL |
| name | 0.000000 |
| NULL |     NULL |
| name | 6.000000 |
| name | 2.000000 |
| name |     NULL |
| name | 0.000000 |
| name | 0.000000 |
| name |     NULL |
| name | 0.000000 |
+------+----------+
10 rows in set (0.00 sec)

mysql> show global variables like 'version%';
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| version                 | 5.6.21-log                   |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | Linux                        |
+-------------------------+------------------------------+
4 rows in set (0.00 sec)

mysql>

Hôm nay là ngày nào ???

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2015-06-25 18:48:10 |
+---------------------+
1 row in set (0.01 sec)

mysql>

Đã một năm và một tuần kể từ khi báo cáo lỗi được gửi và không có gì thay đổi.

Câu trả lời của tôi cho MySQL là chèn "" là 0 trong các trường thập phân. Làm thế nào để ngăn chặn điều đó? vẫn đứng như ngày hôm nay.

Bạn cần thực hiện bài kiểm tra này với MySQL 5.6.23 và xem có gì thay đổi không.


Đối với LOAD DATA INFILE, có, đó là cách duy nhất. Mặt khác, các giá trị số tuân theo định dạng dấu phẩy động của IEEE trở thành 0. Vì tôi đã chỉ ra cách giải quyết ( dba.stackexchange.com/questions/87206/ ,), không tạo ra một kiểu dữ liệu dấu phẩy động IEEE có thể bắt đầu là NULL.
RolandoMySQLDBA

Cảm ơn các bài kiểm tra tái sản xuất chi tiết. Câu trả lời cho hướng dẫn cuối cùng của bạn là dường như không có gì thay đổi. Có một lý do cho hành vi này? Tại sao nó không được coi là một lỗi?
WAF

Ngoài ra, chỉ vì tò mò, tại sao bạn TRUNCATEsau khi CREATEing trong hai ví dụ cuối cùng?
WAF

Tôi đã giữ cấu trúc bảng tương tự để tải lại và thử lại nhưng với \N. Nếu bạn nhìn vào cách giải quyết trong báo cáo lỗi, có một nỗ lực truncate bug_repeat;thứ hai LOAD DATA INFILE. Vì vậy, tôi đã cố gắng sao chép bài kiểm tra của cách giải quyết.
RolandoMySQLDBA
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.