Q1.数据库升级到PG 14之后,为什么很多应用软件连接失败?
问题描述
已经遇到过几次客户反馈PG数据库连接失败的问题,为什么只有升级到14,而其他版本没有出现呢?
问题解答
如果我们有关注14的新特性变化可以知道SCRAM-SHA-256现在已经是客户端认证的默认方式了,在此之前一直是MD5。其实从PG 10开始就已经支持SCRAM-SHA-256,只不过默认方式还是MD5,并且伴随PG 10的发布,配套的客户端驱动也有更新支持。
随着PG 15已经发布第二个小版本,越来越多客户开始使用PG 14,升级之后记得首先检查客户端驱动是否已更新支持SCRAM-SHA-256。
Q2.PG里如何自动记录行版本的修改时间?
问题描述
从DB2或MySQL迁移时会遇到ROW CHANGE TIMESTAMP或ON UPDATE CURRENT_TIMESTAMP的问题,在PG里如何实现呢?
问题解答
DB2或MySQL自动记录数据行修改的时间在PG里没有直接对应的特性,一种方式是通过触发器去实现的,另外一种方式是借助存储列的功能:
create table test1(
id int primary key,
info text,
crt_time timestamp not null default now(),
mod_time timestamp GENERATED ALWAYS AS (wrapper_im_now(info)) stored
);
上面wrapper_im_now函数的定义如下:
CREATE OR REPLACE FUNCTION public.wrapper_im_now(text)
RETURNS timestamp with time zone
LANGUAGE sql
IMMUTABLE
AS $function$
select CURRENT_TIMESTAMP;
$function$;
test1表info字段修改会触发自动更新存储列mod_time,如果还有其它字段也希望触发,可以微调修改上面的接口定义。
PG里存储列和生成列示例可扩展阅读这篇文章:
<<PostgreSQL标识列及存储列示例>>
Q3.PSQL如何自适应查询结果集?
问题描述
Oracle的SQL Plus操作都习惯先使用col name for来进行查询预设置,PG里是否有对应的设置呢?
问题解答
SQL Plus对应到PSQL,比较常见的方式是使用扩展模式竖排显示:

另外一种方式,直接用表名单列显示整行数据:

第三种方式,查看\pset相关参数,可以使用下面的两条命令来处理
\pset format wrapped
\pset columns 0
format在wrapped模式下设置columns,columns设置为0,可根据屏幕宽度自动调整,效果如下:

下面的图是拖动窗口之后的自适配效果:

Q4.如何获取序列的当前值?
问题描述
首次获取序列的值需要先调用nextval来获取值,跨session不能使用currval来调用当前值,难道必须使用nextval推进才能正常获取吗?
问题解答
PG 10中添加了pg_sequences视图,便于获取序列的动态信息,可以通过last_value来获取当前值。
postgres=# select last_value from pg_sequences
where sequencename='s2_id_seq';
last_value
------------
1
(1 row)
也可以把序列当成表一样直接查last_value
postgres=# select last_value from s2_id_seq;
last_value
------------
1
(1 row)
还可以使用pg_sequence_last_value函数
postgres=# select pg_sequence_last_value('s2_id_seq');
pg_sequence_last_value
------------------------
1
(1 row)
Q5.根据表名如何定位在哪些数据库的哪些schema下?
问题描述
需要根据表名确认一张表属于哪个database,哪个schema?
问题解答
PG中可以使用多个database,所以需要遍历所有db进行查找,语句如下:
for db in `psql --pset=pager=off -t -A -q -c 'select datname from pg_database where datname not in ($$template0$$, $$template1$$)'`
do
psql -d $db --pset=pager=off -q -c 'select current_database(),schemaname from pg_stat_user_tables where relname=$$mydb_tab1$$;'
done
实际查找时替换表名即可。




