我有两个表,pattern
和pattern_optimized
。 pattern
表中的一些字段被定义为BIGINT(20) DEFAULT '-1'
,这对于他们保存的数据来说太大了;此外,-1
用作“未设置”(零是有效值) - 否则使用其他否定值。MySQL:在BEFORE INSERT触发器中执行类型转换
pattern_optimized
表为这些行使用新的数据格式,将它们定义为INT(10) UNSIGNED DEFAULT NULL
。我现在想将pattern
中的数据复制到pattern_optimized
表中。
这将使用INSERT INTO pattern_optimized SELECT * FROM pattern
很容易做到,但很明显,所有的负值超出范围了,造成这样的警告:
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
我最初的想法是创建一个BEFORE INSERT
触发如下:
CREATE TRIGGER `negativeValueFix` BEFORE INSERT ON `pattern_optimized`
FOR EACH ROW
BEGIN
IF new.version < 0 THEN
SET new.version = NULL;
END IF;
-- ...
END
但不幸的是这并没有帮助:同样的警告弹出并曾经是-1
原始表中的所有值在新表成为0
(而不是NULL
,这是 - 除了在触发器中实现 - 也是行的默认值)。 似乎MySQL甚至在触发器之前转换了该值。
我知道我可以使用临时表来解决这个问题,但我宁愿不这样做。 pattern
表是令人不快的大,我不想为此做一个存储过程。
有没有其他方法或我错过了一些简单的点?
编辑:原始表格中有很多列遭受SIGNED问题,所以我希望能够稍微自动化。
有趣,我不知道!我想做'INSERT ... SELECT *'的原因是这些“SIGNED”字段中有很多,我希望能够引导一个完整的插入定义。 – sunside 2012-04-25 11:17:16
我想你可以设置你的新表字段的默认值为一些不在传入数据范围内的值,然后运行插入。你会得到警告,-1将被转换为这个新的默认值。然后,您更新表以将这些值设置为空,然后将新表列中的默认值更改为空。但是,这似乎比转换临时表中的数据或使用内联条件更有用。此外,您必须绝对确定您使用的“临时默认”确实不在传入数据的范围内。 – 2012-04-25 12:05:31
使用IF()版本和视图。谢谢! – sunside 2012-04-27 14:58:28