1

我需要将整个数据库中的所有表列从数据类型更改为. 所以我创建了这个函数: timestampwithouttime zonetimestamp(0)withtime 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

我也得到了关于索引的错误。

如何更改所有timestamp without time zone列的数据类型?

4

2 回答 2

1

据我所知,当数据类型发生变化时,没有内置的方法可以根据视图自动更改。
我看到两种可能性:

  1. DROP类型更改之前的所有依赖视图,然后重新创建它们。

  2. 一种完全不同的方法:转储数据库,更改转储中的表定义并恢复它。只要您在同一时区这样做,就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);

强制是自动且正确地发生的。

有关的:

于 2012-05-25T11:18:43.030 回答
1

你可以用 pg_dump 试试

首先使用 --format=plain --schema-only 进行转储

更改转储文件中的数据类型并将其还原到新数据库中。

比您使用 --data-only 进行转储并在新数据库中恢复它们。

于 2012-05-25T11:23:38.303 回答