2010-07-13 89 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; 
相关问题