# 切换流程
postgres相比mysql多了一层模式(Schema)的概念, 一个数据库下可以有多个模式。 这里的模型名等价于以前的mysql的数据库名。如果不指定默认是public。
# 注意事项
1、参数值不能用双引号,需用单引号
2、字段名不能用``包起来,直接去掉就可以
3、json字段处理语法不同:mysql是用 -> '$.xxx'的语法去选取的, 而 postgreSQL 得用 ->>'xx' 语法选择属性
4、postgreSQL没有convert函数,用CAST函数替换
5、mysql可以使用force index强制走索引, postgres没有,建议去掉
6、postgreSQL没有ifnull函数,用COALESCE函数替换
7、postgreSQL没有date_format函数,用to_char函数替换。例子:
to_char(time,'YYYY-MM-DD') => DATE_FORMAT(time,'%Y-%m-%d')
to_char(time,'YYYY-MM') => DATE_FORMAT(time,'%Y-%m')
to_char(time,'YYYYMMDDHH24MISS') => DATE_FORMAT(time,'%Y%m%d%H%i%s')
8、postgreSQL 的 select的字段必须是group by的字段里的 或者使用了聚合函数。mysql则没有这个要求,非聚合列会随机取值
select name, age, count(*)
from user
group by age, score
这时 select name 是错误的, 应为group by里没有这个字段,要么加上,要么变成select min(name)
9、Postgres数据库中,同一事务中如果某次数据库操作中出错的话,那这个事务以后的数据库操作都会出错。如果有人去捕获了事务异常后又去执行数据库操作就会导致这个问题。mysql貌似不会有这个问题,解决方法用if else替代异常
10、mysql是支持自动类型转换的,postgreSQL是强数据类型,字段类型和参数值类型之间必须一样否则就会抛出异常。
解决办法一般有两种:手动修改代码里的字段类型和传参类型保证 或者 postgreSQL表字段类型,反正保证双方一一对应;手动添加自动隐式转换函数,达到类似mysql的效果
不要乱添加隐式转换函数,可能导致 Could not choose a best candidate operator 异常 和 # operator is not unique 异常 就是在操作符比较的时候有多个转换逻辑不知道用哪个了,死循环了
11、postgreSQL辅助脚本
①批量修改timestamptz脚本,修改表字段类型 timestamptz 为 timestamp, 因为我们说过前者无法与LocalDateTime对应上
timestamp without time zone 就是 timestamp;timestamp with time zone 就是 timestamptz
DO $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT table_name, column_name,data_type
FROM information_schema.columns
where table_schema = '要处理的模式名'
AND data_type = 'timestamp with time zone'
LOOP
EXECUTE 'ALTER TABLE ' || rec.table_name || ' ALTER COLUMN ' || rec.column_name || ' TYPE timestamp';
END LOOP;
END $$;
②批量修改模式名下的所有字段类型为timestamp的并且字段名为 create_time 或者 update_time的字段的默认值为 CURRENT_TIMESTAMP-- 注意 || 号拼接的后面的字符串前面要有一个空格
DO $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT table_name, column_name,data_type
FROM information_schema.columns
where table_schema = '要处理的模式名'
AND data_type = 'timestamp without time zone'
and column_name in ('create_time','update_time')
LOOP
EXECUTE 'ALTER TABLE ' || rec.table_name || ' ALTER COLUMN ' || rec.column_name || ' SET DEFAULT CURRENT_TIMESTAMP;';
END LOOP;
END $$;