Tình huống gặp phải
Khi thực hiện cập nhật dữ liệu trong ClickHouse, việc cập nhật các cột có kiểu Nullable(Int32) bất kể giá trị mới được cung cấp là gì, kết quả cuối cùng luôn là một giá trị cố định: 93147008.
Các bước tái tạo
1. Tạo bảng kiểm thử
CREATE TABLE product_inventory_test
(
`product_id` Int32,
`category_id` Nullable(String),
`stock_level` Nullable(Int32),
`is_active` Int32,
`min_stock` Int32,
`max_stock` Nullable(Int32),
`reorder_point` Nullable(Int32),
`last_updated` Nullable(DateTime),
`alert_flag` Nullable(Int32)
)
ENGINE = MergeTree
ORDER BY product_id
SETTINGS index_granularity = 8192;
2. Chèn dữ liệu mẫu
INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (101, 'A1', 50, 1, 10, 100, 20, '2023-10-27 10:00:00', 0);
INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (102, 'A2', 75, 1, 15, 150, 30, '2023-10-27 10:05:00', 0);
INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (103, 'B1', 30, 1, 5, 50, 10, '2023-10-27 10:10:00', 0);
INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (104, 'B2', 90, 1, 20, 200, 40, '2023-10-27 10:15:00', 0);
INSERT INTO product_inventory_test(product_id, category_id, stock_level, is_active, min_stock, max_stock, reorder_point, last_updated, alert_flag) VALUES (105, 'C1', 15, 1, 8, 80, 16, '2023-10-27 10:20:00', 0);
3. Truy vấn dữ liệu ban đầu
SELECT *
FROM product_inventory_test;
-- Kết quả truy vấn
┌─product_id─┬─category_id─┬─stock_level─┬─is_active─┬─min_stock─┬─max_stock─┬─reorder_point─┬─last_updated─┬─alert_flag─┐
│ 101 │ A1 │ 50 │ 1 │ 10 │ 100 │ 20 │ 2023-10-27 │ 0 │
│ 102 │ A2 │ 75 │ 1 │ 15 │ 150 │ 30 │ 2023-10-27 │ 0 │
│ 103 │ B1 │ 30 │ 1 │ 5 │ 50 │ 10 │ 2023-10-27 │ 0 │
│ 104 │ B2 │ 90 │ 1 │ 20 │ 200 │ 40 │ 2023-10-27 │ 0 │
│ 105 │ C1 │ 15 │ 1 │ 8 │ 80 │ 16 │ 2023-10-27 │ 0 │
└───────────┴────────────┴─────────────┴───────────┴──────────┴──────────┴──────────────┴──────────────┴───────────┘
4. Cập nhật cột Int32 (hoạt động bình thường)
Cập nhật cột `is_active` để kiểm tra chức năng cập nhật hoạt động đúng.
ALTER TABLE product_inventory_test UPDATE is_active = 0 WHERE product_id = 101;
-- Truy vấn sau khi cập nhật
SELECT *
FROM product_inventory_test
WHERE product_id = 101;
-- Kết quả truy vấn
┌─product_id─┬─category_id─┬─stock_level─┬─is_active─┬─min_stock─┬─max_stock─┬─reorder_point─┬─last_updated─┬─alert_flag─┐
│ 101 │ A1 │ 50 │ 0 │ 10 │ 100 │ 20 │ 2023-10-27 │ 0 │
└───────────┴────────────┴─────────────┴───────────┴──────────┴──────────┴──────────────┴──────────────┴───────────┘
5. Cập nhật cột Nullable(Int32) (lỗi xảy ra)
Bây giờ, hãy thử cập nhật cột `alert_flag` có kiểu `Nullable(Int32)` với giá trị mới là `15`.
ALTER TABLE product_inventory_test UPDATE alert_flag = 15 WHERE product_id = 103;
-- Truy vấn sau khi cập nhật
SELECT *
FROM product_inventory_test
WHERE product_id = 103;
-- Kết quả truy vấn (bất ngờ)
┌─product_id─┬─category_id─┬─stock_level─┬─is_active─┬─min_stock─┬─max_stock─┬─reorder_point─┬─last_updated─┬─alert_flag─┐
│ 103 │ B1 │ 30 │ 1 │ 5 │ 50 │ 10 │ 2023-10-27 │ 93147008 │
└───────────┴────────────┴─────────────┴───────────┴──────────┴──────────┴──────────────┴──────────────┴───────────┘
6. Cập nhật cột Nullable(Int32) khác (lỗi lặp lại)
Hãy thử cập nhật một cột `Nullable(Int32)` khác, ví dụ `reorder_point` với giá trị mới là `25`.
ALTER TABLE product_inventory_test UPDATE reorder_point = 25 WHERE product_id = 103;
-- Truy vấn sau khi cập nhật
SELECT *
FROM product_inventory_test
WHERE product_id = 103;
-- Kết quả truy vấn (lại là 93147008)
┌─product_id─┬─category_id─┬─stock_level─┬─is_active─┬─min_stock─┬─max_stock─┬─reorder_point─┬─last_updated─┬─alert_flag─┐
│ 103 │ B1 │ 30 │ 1 │ 5 │ 50 │ 93147008 │ 2023-10-27 │ 93147008 │
└───────────┴────────────┴─────────────┴───────────┴──────────┴──────────┴──────────────┴──────────────┴───────────┘
Câu hỏi
Tại sao khi cập nhật các cột có kiểu dữ liệu `Nullable(Int32)`, kết quả luôn là giá trị cố định `93147008`, bất kể giá trị mới được cung cấp là gì?