我正在尝试在迁移中执行以下操作。
这是代码。
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:ERROR:“name”列中的空值违反了非空约束 =&GT;该名称实际上不是null,而是一些Unicode字符串。
您是否知道此错误的原因是什么以及如何解决此问题?
答案 0 :(得分:0)
抱歉,我太天真了,以至于我不知道我应该使用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