2010-07-13 57 views
13

我有一個約100列(90%可空)的遺留表。在這90列中,我想刪除所有空字符串並將它們設置爲空。我知道我可以:如何在表中將所有空字符串更改爲NULL?

update table set column = NULL where column = ''; 
update table set column2 = NULL where column2 = ''; 

但是,這是乏味和容易出錯。在整個桌子上必須有一種方法可以做到這一點?

+1

這是一次性的事情還是將需要存起來? – 2010-07-13 14:57:12

+0

一次性,將prob。儘管運行它一些其他的時間。 – 2010-07-13 15:40:00

+0

我打算建議,如果再次出現零長度字符串進入表格的危險,您可以創建一個視圖,其中零長度字符串被轉換爲NULL值。這樣你的應用程序永遠不用擔心它們。 – 2010-07-13 16:06:03

回答

30
UPDATE 
    TableName 
SET 
    column01 = CASE column01 WHEN '' THEN NULL ELSE column01 END, 
    column02 = CASE column02 WHEN '' THEN NULL ELSE column02 END, 
    column03 = CASE column03 WHEN '' THEN NULL ELSE column03 END, 
    ..., 
    column99 = CASE column99 WHEN '' THEN NULL ELSE column99 END 

這仍然是做手工,但比你所擁有的,因爲它不要求你發送一個查詢每個柱略有減少痛苦。除非你想要爲腳本編寫腳本,否則在做這樣的事情時你必須承受一定的痛苦。

編輯:增加了END小號

+0

@OMG:爲什麼?據推測,您所指的是ELSE columnXX END列名,但爲什麼要使用TRIM呢? – 2010-07-13 16:16:39

+0

@Jonathan Leffler:這就是我的意思:'CASE TRIM(column01)''...'我應該更清楚我的意思是比較,對不起。 – 2010-07-13 16:18:10

+0

@OMG:好的 - 我現在知道你的意思了,但我重申了我的問題:爲什麼?與簡單比較空白字符串相比,修整有什麼好處?數據庫管理系統很可能最終會對修剪後的字符串進行空白填充,因爲修剪後的值可能會與未修改的值一樣長,所以您只是將它做成空洞的工作,它可能會或可能不會發現空洞。 – 2010-07-13 22:55:52

0

我想你會需要每一行拉進如C#,PHP等語言

喜歡的東西:

rows = get-data() 
foreach row in rows 
    foreach col in row.cols 
     if col == '' 
      col = null 
     end if 
    next 
next 
save-data() 
+0

這會起作用,但是在T-SQL中使用循環(例如使用遊標)遍歷列列表是可行的。不過,對於一次性任務,我認爲這並不重要。 – Brian 2010-07-13 14:53:27

+0

我傾向於將SQL從這種類型的維護中吸取出來,因爲在大多數情況下,我最終需要隨着時間的推移添加更多的功能,並且最終我會將其完全拉入到完整的OO語言中。但那是一個個人的偏見...;) – Nate 2010-07-13 15:09:14

1

沒有一個標準的方式 - 但你可以詢問系統目錄獲取相關表的相關列名並生成SQL來執行此操作。您也可以使用CASE表達式來處理單個傳遞中的所有列 - 一個更大的SQL語句。一旦你已經產生了很大的UPDATE語句

UPDATE Table 
    SET Column1 = CASE Column1 = ' ' THEN NULL ELSE Column1 END, 
     ... 

注意,所有的工作都在服務器做下來。這比將數據選擇到客戶端應用程序,將其更改並將結果寫回數據庫要有效得多。

10

一個可能的腳本:

for col in $(echo "select column_name from information_schema.columns 
where table_name='$TABLE'"|mysql --skip-column-names $DB) 
do 
echo update $TABLE set $col = NULL where $col = \'\'\; 
done|mysql $DB 
+0

+1現在,這真的很棒! :) – 2010-07-13 15:01:57

+1

是的,不要做任何事情,你可以說服你的電腦爲你做... :) – GalacticCowboy 2010-07-13 15:55:53

+1

不安全。 where子句也需要'和table_schema ='$ SCHEMA''。 – 2017-04-06 18:14:06

5

對於新手,你可能仍然需要看到上面的答案後,更多的工作。輸入數千行是不現實的。 所以在這裏我提供一個完整的工作代碼來讓你避免語法錯誤等

DROP PROCEDURE IF EXISTS processallcolumns; 

DELIMITER $$ 

CREATE PROCEDURE processallcolumns() 
BEGIN 

    DECLARE i,num_rows INT ; 
    DECLARE col_name char(250); 

    DECLARE col_names CURSOR FOR 
    SELECT column_name 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_name = 'PROCESSINGTABLE' 
    ORDER BY ordinal_position; 

    OPEN col_names ; 
    select FOUND_ROWS() into num_rows; 

    SET i = 1; 
    the_loop: LOOP 

    IF i > num_rows THEN 
      CLOSE col_names; 
      LEAVE the_loop; 
     END IF; 


     FETCH col_names 
     INTO col_name;  


     SET @command_text = CONCAT('UPDATE `PROCESSINGTABLE` SET ', col_name, '= IF(LENGTH(', col_name, ')=0, NULL,', col_name, ') WHERE 1 ;') ; 

--  UPDATE `PROCESSINGTABLE` SET col_name=IF(LENGTH(col_name)=0,NULL,col_name) WHERE 1; 
--  This won't work, because MySQL doesn't take varibles as column name. 

     PREPARE stmt FROM @command_text ; 
     EXECUTE stmt ; 

     SET i = i + 1; 
    END LOOP the_loop ; 



END$$ 
DELIMITER ; 

call processallcolumns(); 
DROP PROCEDURE processallcolumns; 
相關問題