2012-04-25 20 views
0

我有兩個表,patternpattern_optimizedpattern表中的一些字段被定義爲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問題,所以我希望能夠稍微自動化。

回答

2

您可以使用case語句嗎?喜歡的東西:

INSERT INTO pattern_optimized SELECT CASE version WHEN -1 THEN null ELSE version END CASE AS version FROM pattern

+0

有趣,我不知道!我想做'INSERT ... SELECT *'的原因是這些「SIGNED」字段中有很多,我希望能夠引導一個完整的插入定義。 – sunside 2012-04-25 11:17:16

+0

我想你可以設置你的新表字段的默認值爲一些不在傳入數據範圍內的值,然後運行插入。你會得到警告,-1將被轉換爲這個新的默認值。然後,您更新表以將這些值設置爲空,然後將新表列中的默認值更改爲空。但是,這似乎比轉換臨時表中的數據或使用內聯條件更有用。此外,您必須絕對確定您使用的「臨時默認」確實不在傳入數據的範圍內。 – 2012-04-25 12:05:31

+0

使用IF()版本和視圖。謝謝! – sunside 2012-04-27 14:58:28

1

只需添加小條件SELECT語句,例如 -

INSERT INTO pattern_optimized(version) 
    SELECT IF(version < 0, NULL, version) version FROM pattern 

...添加其他字段。

+0

和@Raj一樣 - 我不知道的一個重點,但是我希望能在每個領域都做到這一點。 (在更改過程中,會在舊錶上插入我希望使用觸發器克隆到新表的插入) – sunside 2012-04-25 11:20:37

+0

我接受了Rajs的答案,因爲他首先回答+基本相同,代表較少。upvoted你的答案雖然。非常感謝! – sunside 2012-04-27 15:00:21

+0

@Markus - 確定;-) – Devart 2012-04-27 15:12:52