How do I change all empty strings to NULL in a table?

前端 未结 7 1430
悲哀的现实
悲哀的现实 2020-12-08 20:25

I have a legacy table with about 100 columns (90% nullable). In those 90 columns I want to remove all empty strings and set them to null. I know I can:

updat         


        
相关标签:
7条回答
  • 2020-12-08 20:48
    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
    

    This is still doing it manually, but is slightly less painful than what you have because it doesn't require you to send a query for each and every column. Unless you want to go to the trouble of scripting it, you will have to put up with a certain amount of pain when doing something like this.

    Edit: Added the ENDs

    0 讨论(0)
  • 2020-12-08 20:49

    You could write a simple function and pass your columns to it:

    Usage:

    SELECT
      fn_nullify_if_empty(PotentiallyEmptyString)
    FROM
      table_name
    ;
    

    Implementation:

    DELIMITER $$
    CREATE FUNCTION fn_nullify_if_empty(in_string VARCHAR(255))
      RETURNS VARCHAR(255)
      BEGIN
        IF in_string = ''
          THEN RETURN NULL;
          ELSE RETURN in_string;
        END IF;
      END $$
    DELIMITER ;
    
    0 讨论(0)
  • 2020-12-08 20:52

    For newbies, you may still need more work after seeing the above answers. And it's not realistic to type thousands lines. So here I provide a complete working code to let you avoid syntax errors etc.

    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;
    
    0 讨论(0)
  • 2020-12-08 20:53

    One possible script:

    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 讨论(0)
  • 2020-12-08 20:57

    I think you'll need to pull each row into a language like C#, php, etc.

    Something like:

    rows = get-data()
    foreach row in rows
        foreach col in row.cols
            if col == ''
                col = null
            end if
        next
    next
    save-data()
    
    0 讨论(0)
  • 2020-12-08 20:57

    Hammerite's answer is good but you can also replace CASE statements with IFs.

    UPDATE
        TableName
    SET
        column01 = IF(column01 = '', NULL, column01),
        column02 = IF(column02 = '', NULL, column02),
        column03 = IF(column03 = '', NULL, column03),
        ...,
        column99 = IF(column99 = '', NULL, column99)
    
    0 讨论(0)
提交回复
热议问题