I have two tables, pattern and pattern_optimized. Some of the fields in the pattern table are defined as BIGINT(20) DEFAULT '-1', which is way too big for the data they hold; Additionally, -1 is used as “not set” (zero is a valid value) – no other negative values are used otherwise.
The pattern_optimized table uses a new data format for these rows, defining them as INT(10) UNSIGNED DEFAULT NULL. I would now like to copy the data from pattern to the pattern_optimized table.
This would be easily done using INSERT INTO pattern_optimized SELECT * FROM pattern, but obviously all negative values are out of range now, resulting in warnings like this:
100 row(s) affected, 64 warning(s):
1264 Out of range value for column 'version' at row 1
1264 Out of range value for column 'triggered' at row 1
...
Records: 100 Duplicates: 0 Warnings: 357
My first idea was to create a BEFORE INSERT trigger as follows:
CREATE TRIGGER `negativeValueFix` BEFORE INSERT ON `pattern_optimized`
FOR EACH ROW
BEGIN
IF new.version < 0 THEN
SET new.version = NULL;
END IF;
-- ...
END
but unfortunately this doesn’t help either: The same warning pops up and all values that used to be -1 in the original table become 0 in the new table (instead of NULL, which is – apart from being implemented in the trigger – also the default for the row).
It seems that MySQL converts the value even before the trigger.
I know that I can solve this problem using a temporary table but I’d rather not do that. The pattern table is unpleasantly large and I don’t want to do a stored procedure just for that.
Is there any other way or am I missing some simple point?
EDIT: There are quite alot columns in the original table that suffer from the SIGNED problem, so I was hoping to somewhat automate that.
Could you use a case statement? Something like:
INSERT INTO pattern_optimized
SELECT
CASE version
WHEN -1 THEN null
ELSE version
END CASE AS version
FROM pattern