在违反约束的情况下使用 INSERT INTO for POSTGRESQL 迁移数据
Migrate data with INSERT INTO for POSTGRESQL with constraints violated
假设我有两个 table,oldstatistics 和 statistics,较新的 table 对时间列有不同的约束。
例如,较新的 table 有以下限制,而旧的 table 有违反的数据:
CONSTRAINT check_ts_2013_03 CHECK (statistictime >= '2013-03-01
01:00:00+01'::timestamp with time zone AND statistictime < '2013-04-01
02:00:00+02'::timestamp with time zone)
和违反的数据假设他们有统计时间 '2013-04-01 00:15:00+01'
我用 INSERT OR IGNORE 为 SQLite 找到了一些解决方案(如果发生约束冲突,将跳过这些行,并且它将继续),但不适用于 POSTGRESQL。
你有什么建议吗?
你想用这些数据做什么,想合并它们吗?
- 为了同时使用这两个表,我建议使用视图。
- 如果想在不修改数据的情况下将oldStatisticTime插入statisticTime,可以解除对触发器的约束,不触发触发器,插入数据,然后开启触发器。
您可以使用 plpgsql 函数和异常块(请参阅 documentation)执行此操作:
CREATE or REPLACE FUNCTION insert_or_ignore() RETURNS VOID AS $$
DECLARE _value timestamp;
BEGIN
FOR _value IN SELECT statistictime FROM oldstatistics LOOP
BEGIN
INSERT INTO statistics(statistictime) VALUES (_value);
EXCEPTION when check_violation THEN
-- DO NOTHING
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;
-- run the function
SELECT insert_or_ignore();
您可能还需要插入其他列,而不仅仅是 statistictime
。在这种情况下,您必须在 DECLARE 块中声明它们。
您也可以使用 DO 语句来做同样的事情,而无需先创建函数(参见 documentation:
DO $$
DECLARE _value timestamp;
BEGIN
FOR _value IN SELECT statistictime FROM oldstatistics LOOP
BEGIN
INSERT INTO statistics(statistictime) VALUES (_value);
EXCEPTION when check_violation THEN
-- DO NOTHING
END;
END LOOP;
END$$;
我在这里捕获了 "check_violation" 异常,但也检查了所有 PostgreSQL 错误代码,如果您想捕获其他类型的错误:error codes
假设我有两个 table,oldstatistics 和 statistics,较新的 table 对时间列有不同的约束。
例如,较新的 table 有以下限制,而旧的 table 有违反的数据:
CONSTRAINT check_ts_2013_03 CHECK (statistictime >= '2013-03-01 01:00:00+01'::timestamp with time zone AND statistictime < '2013-04-01 02:00:00+02'::timestamp with time zone)
和违反的数据假设他们有统计时间 '2013-04-01 00:15:00+01'
我用 INSERT OR IGNORE 为 SQLite 找到了一些解决方案(如果发生约束冲突,将跳过这些行,并且它将继续),但不适用于 POSTGRESQL。
你有什么建议吗?
你想用这些数据做什么,想合并它们吗?
- 为了同时使用这两个表,我建议使用视图。
- 如果想在不修改数据的情况下将oldStatisticTime插入statisticTime,可以解除对触发器的约束,不触发触发器,插入数据,然后开启触发器。
您可以使用 plpgsql 函数和异常块(请参阅 documentation)执行此操作:
CREATE or REPLACE FUNCTION insert_or_ignore() RETURNS VOID AS $$
DECLARE _value timestamp;
BEGIN
FOR _value IN SELECT statistictime FROM oldstatistics LOOP
BEGIN
INSERT INTO statistics(statistictime) VALUES (_value);
EXCEPTION when check_violation THEN
-- DO NOTHING
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;
-- run the function
SELECT insert_or_ignore();
您可能还需要插入其他列,而不仅仅是 statistictime
。在这种情况下,您必须在 DECLARE 块中声明它们。
您也可以使用 DO 语句来做同样的事情,而无需先创建函数(参见 documentation:
DO $$
DECLARE _value timestamp;
BEGIN
FOR _value IN SELECT statistictime FROM oldstatistics LOOP
BEGIN
INSERT INTO statistics(statistictime) VALUES (_value);
EXCEPTION when check_violation THEN
-- DO NOTHING
END;
END LOOP;
END$$;
我在这里捕获了 "check_violation" 异常,但也检查了所有 PostgreSQL 错误代码,如果您想捕获其他类型的错误:error codes