如果您可以访问服务器,我认为@richyen 解决方案是最好的。
如果您不这样做,您必须以某种方式手动将上次刷新日期存储为元数据。一些选项是:
-- Create table
CREATE TABLE pg_matviews_last_refreshed (
matviewowner NAME NOT NULL,
matviewname NAME NOT NULL,
schemaname NAME NOT NULL,
last_refreshed TIMESTAMP NOT NULL,
CONSTRAINT pk UNIQUE (matviewowner, matviewname, schemaname)
)
CREATE VIEW pg_matviews_extra AS
SELECT *
FROM pg_matviews
NATURAL JOIN pg_matviews_last_refreshed
-- Set initial values
INSERT INTO pg_matviews_last_refreshed (
matviewowner,
matviewname,
schemaname,
last_refreshed
)
SELECT
matviewowner,
matviewname,
schemaname,
CURRENT_TIMESTAMP
FROM pg_matviews;
-- Consult dates
SELECT * FROM pg_matviews_extra
-- Refresh
BEGIN;
REFRESH MATERIALIZED VIEW CONCURRENTLY my_materialized_view;
-- Insert update date into last_refreshed table. Of course, if
-- more complex permissions are into place, the query becomes more
-- complex to discover owner, schema, etc.
INSERT INTO pg_matviews_last_refreshed (matviewname, matviewowner, schemaname, last_refreshed)
SELECT matviewname, matviewowner, schemaname, CURRENT_TIMESTAMP
FROM pg_matviews
WHERE matviewname='my_materialized_view'
ON CONFLICT (matviewname, matviewowner, schemaname)
DO UPDATE SET last_refreshed=EXCLUDED.last_refreshed;
COMMIT;
- 与使用专用表存储上次刷新日期类似,您可以将该信息隐式存储在 MV 注释中:
-- Refresh operation
BEGIN;
REFRESH MATERIALIZED VIEW CONCURRENTLY my_materialized_view;
-- This statement can be wrapped into a function to allow using CURRENT_TIMESTAMP
COMMENT ON MATERIALIZED VIEW my_materialized_view IS '{"last_refreshed": "2021-07-07T09:30:59Z"}'
COMMIT;
-- Retrieve refresh date
SELECT (pg_catalog.obj_description('my_materialized_view'::regclass, 'pg_class')::json->>'last_refreshed')::timestamp;