2015-10-18 23 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 
相關問題