【问题标题】:Rails migration error: Unicode string return null value inside "execute >> SQL"Rails 迁移错误:Unicode 字符串在“执行 >> SQL”中返回空值
【发布时间】:2015-10-19 01:40:35
【问题描述】:

我正在尝试在迁移中做以下事情。

  1. 将“名称”拆分为 splitted_name 数组。
  2. 将 first_name 设置为 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:错误:“名称”列中的空值违反非空约束 => 这个名字实际上不是 null 而是一些 Unicode 字符串。

您知道这个错误的原因是什么以及如何解决这个问题吗?

【问题讨论】:

    标签: ruby-on-rails postgresql unicode


    【解决方案1】:

    对不起,我太天真了,我不知道我应该使用 splitted_name[1] 作为 first_name 并且没有数组 [-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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-16
      • 1970-01-01
      • 1970-01-01
      • 2019-06-17
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      相关资源
      最近更新 更多