2015-10-18 26 views
0

我正试图在迁移中执行下面的操作。Rails迁移错误:Unicode字符串在“execute >> SQL”中返回空值

  1. 将“Name”拆分为splitted_name数组。
  2. SET first_name as splitted_name [0]。
  3. 如果splitted_name [0]和splitted_name [-1]不同,则将last_name设置为splitted_name [-1]。
  4. 如果splitted_name [0]和splitted_name [1]相同,则将last_name设置为空字符串。

这是代码。

class ConvertNameIntoFirstAndLastName < ActiveRecord::Migration 
    def up 
    execute <<-SQL 
     DO 
     $do$ 
     DECLARE 
     u record; 
     BEGIN 
     FOR u IN SELECT * FROM users LOOP 
     DECLARE 
      splitted_name text[]; 
     BEGIN 
      splitted_name := CASE WHEN u.name IS NULL THEN '{''}' 
           ELSE regexp_split_to_array(u.name, E'\\s+') 
          END; 
      UPDATE users 
      SET 
       first_name = splitted_name[0], 
       last_name = CASE WHEN splitted_name[0] = splitted_name[-1] THEN '' 
           ELSE splitted_name[-1] 
          END, 
       name = splitted_name[0] || ' ' || (CASE WHEN splitted_name[0] = splitted_name[-1] THEN '{''}' 
                 ELSE splitted_name[-1] 
               END) 
      WHERE id = u.id; 
     END; 
     END LOOP; 
     END; 
     $do$; 
    SQL 
    end 

    def down 
    end 
end 

问题是当名称是unicode字符时u.name总是返回null。数据库编码设置为Unicode。

这是错误消息。

PG :: NotNullViolation:错误:列“名称”中的空值违反了非空约束 =>该名称实际上不是空值,而是一些Unicode字符串。

你有什么想法是什么原因造成这个错误以及如何解决这个问题?

回答

0

对不起,我太天真了,我不知道我应该为first_name使用splitted_name [1],并且没有数组[-1]。

此代码起作用。

class ConvertNameIntoFirstAndLastName < ActiveRecord::Migration 
    def up 
    execute <<-SQL 
     DO 
     $do$ 
     DECLARE 
     u record; 
     BEGIN 
     FOR u IN SELECT * FROM users LOOP 
     DECLARE 
      splitted_name text[]; 
     BEGIN 
      splitted_name := regexp_split_to_array(regexp_replace(u.name, ' ', ' '), ' '); 
      UPDATE users 
      SET 
       first_name = splitted_name[1], 
       last_name = CASE WHEN splitted_name[1] = splitted_name[array_upper(splitted_name, 1)] THEN '' 
           ELSE splitted_name[array_upper(splitted_name, 1)] 
          END, 
       name = splitted_name[1] || ' ' || (CASE WHEN splitted_name[1] = splitted_name[array_upper(splitted_name, 1)] THEN '' 
                 ELSE splitted_name[array_upper(splitted_name, 1)] 
               END) 
      WHERE id = u.id; 
     END; 
     END LOOP; 
     END; 
     $do$; 
    SQL 
    end 

    def down 
    end 
end 
相关问题