我需要将整个数据库中的所有表格列从数据类型timestamp
without
time zone
更改为timestamp(0)
{{ 1}} with
。
所以我创建了这个函数:
time zone
但是有些视图依赖于受影响的列而我收到了错误:
CREATE OR REPLACE FUNCTION grd_replace_datetime_with_timezone() RETURNS character varying AS $BODY$ DECLARE old_column RECORD; s text; BEGIN FOR old_column IN ( SELECT isc.table_schema as table_schema, isc.table_name as table_name, isc.column_name as column_name FROM information_schema.columns isc INNER JOIN pg_tables pt ON (isc.table_schema = pt.schemaname and isc.table_name = pt.tablename) WHERE isc.column_name like '%date%' and isc.table_schema in ('public') and isc.data_type = 'timestamp without time zone' ORDER BY isc.table_name ASC ) LOOP RAISE NOTICE 'Schema: %',old_column.table_schema; RAISE NOTICE 'Table: %',old_column.table_name; RAISE NOTICE 'Column %',old_column.column_name; EXECUTE 'ALTER TABLE '||old_column.table_schema||'.'||old_column.table_name||' ALTER COLUMN '||old_column.column_name||' TYPE timestamp(0) with time zone'; RAISE NOTICE '-------------------------------------------------------------------------------'; RAISE NOTICE ''; END LOOP; RETURN 'S'; END; $BODY$ LANGUAGE plpgsql VOLATILE;
我也有关于索引的错误。
如何更改所有ERROR: cannot alter type of a column used by a view or rule
列的数据类型?
答案 0 :(得分:1)
据我所知,当数据类型发生变化时,没有内置的方法来自动更改视图 我看到两种可能性:
DROP
在类型更改之前所有依赖视图,之后重新创建。
一种完全不同的方法:转储数据库,更改转储中的表定义并恢复。只要您在同一时区内执行 ,timestamp without time zone
就应该被正确强制转移到timestamptz(0)
。请注意,转化为timestamptz(0)
轮次为完整秒数。
如果您有多个对象,则转储&恢复是可行的方法 - 如果你能负担得起的停机时间。
CREATE TEMP TABLE t (id int, x timestamp);
CREATE TEMP TABLE t1 (id int, x timestamptz(0);
INSERT INTO t VALUES
(1, '2019-05-25 13:23:03.123') -- rounds down
(1, '2019-05-25 13:23:03.987') -- rounds up
,(2, '2019-05-25 23:23:03')
,(3, '2019-05-25 0:0:0');
COPY t TO '/var/lib/postgres/ts_test.sql';
COPY t1 FROM '/var/lib/postgres/ts_test.sql';
SELECT t.x, t.x::timestamptz(0), t1.x
FROM t
JOIN t1 USING (id);
强制自动且正确地发生。
相关:
答案 1 :(得分:1)
您可以尝试使用pg_dump
首先使用--format = plain --schema-only
进行转储更改转储文件中的数据类型,并将其还原到新的数据库中。
比使用--data-only进行转储并在新数据库中恢复它们。