1、PostgreSQL数据转换
字符串转double类型
to_number(#{lat},9999.99)
数字转字符
to_char(#{state},'fm9')
备注:to_char函数会在前面多一个空格,解决方法可以是在第二个格式参数前加fm
2、PostgreSQL 取查询结果的第一行(分页方式)
pg
select ... from ... where ... limit 1
oracle
select ... from ... where ... and rownum=1
3、PostgreSQL中类似oracle的nvl()函数
SELECT coalesce(column,0) as alias FROM table
4、PostgreSQL支持sys_guid()
Oracle 使用sys_guid()用来产生UUID值。
在PostgreSQL中有类似的函数,需要安装uuid-ossp插件。
如果用户不想修改代码,还是需要使用sys_guid()函数的话,可以自己写一个
DECLARE
v_seed_value varchar(32);
BEGIN
select
md5(
inet_client_addr()::varchar ||
timeofday() ||
inet_server_addr()::varchar ||
to_hex(inet_client_port())
)
into v_seed_value;
return (substr(v_seed_value,1,8) ||
substr(v_seed_value,9,4) ||
substr(v_seed_value,13,4) ||
substr(v_seed_value,17,4) ||
substr(v_seed_value,21,12));
END;
5、PostgreSQL对add_months()函数的支持
Oracle中add_months()函数如果当前日期是月末,或者目标月没有当前日期的,取最后一天。
CREATE FUNCTION agcloud.add_months()
RETURNS timestamp with time zone
LANGUAGE 'plpgsql'
AS $BODY$declare
i interval := ($2 || 'month');
d1 date := date(to_timestamp($1::text,'yyyy-mm') + interval '1 month' - interval '1 day');
d2 date := date($1);
res timestamp;
begin
select case when d1=d2 then ((to_char($1+i+interval '1 month', 'yyyy-mm')||'-01')::date - 1) + $1::time else $1+i end into res;
return res;
end;
$BODY$;
ALTER FUNCTION agcloud.add_months()
OWNER TO postgres;
6、PostgreSQL的update语句起别名报错
--错误写法
UPDATE [TABLE] AS T SET T.TID=1,T.TNAME='Name',T.TClass=1 WHERE T.ID=10
--规范写法
UPDATE TABLE SET TID=1,TNAME='Name',TClass=1 WHERE ID=10;
UPDATE SWG_DRI_TRACK_PROBLEM t SET SZWZ = ?, jdmc = ?, jjcd = ?, wtms = ?, x = ?, y = ?, FILE_GROUP_IDS = ? WHERE t.id = ?
7、PostgreSQL的序列生成方式不同
注意:使用nextval()函数时,可能会识别不了序列,需要加模式和单引号
<insert id="addUnitWell" parameterType="map">
<selectKey keyProperty="id" resultType="int" order="BEFORE" databaseId="oracle">
select SEQ_SWG_DRI_UNIT_WELL.Nextval from dual
</selectKey>
<selectKey keyProperty="id" resultType="int" order="BEFORE" databaseId="pg">
select nextval('SEQ_SWG_DRI_UNIT_WELL')
</selectKey>
...
</insert>
8、递归函数查找:
oracle:start with … connect by prior 递归算法
postgresql: with recursive 递归函数
管线表中设计的时候用两个字段来标识起始点和终止点,形成了类似树状的结构
使用oracle的递归函数查找:
start with … connect by prior 递归算法
语法:
select * from table
where 条件3
start with 条件1
connect by 条件2
条件1:是根节点的限定语句,若不写start with 指定根节点查询时,是以每条记录的connect by的字段当根全查一遍
条件2:是连接条件,当中用prior表示上一条记录的字段
条件3:是过滤条件,用于对返回结果集的过滤
SELECT t.*, substr(sys_connect_by_path(t.objectid, '->'), 3) chainsNode
FROM swg_sma_pipe t
START WITH t.end_usid = '060208-28420315-000001'
CONNECT BY PRIOR t.start_usid = t.end_usid and t.sort != '雨水'--遇到雨水就不继续递归
ORA-01436: 用户数据中的 CONNECT BY 循环,死循环导致,解决方法:使用nocycle剔除导致死循环的记录
SELECT t.*, substr(sys_connect_by_path(t.objectid, '->'), 3) chainsNode
FROM swg_sma_pipe t
START WITH t.end_usid = '060208-28420315-000001'
CONNECT BY nocycle PRIOR t.start_usid = t.end_usid and t.sort != '雨水'--遇到雨水就不继续递归
PostgreSQL的with语句的用法:
详细内容:http://www.jasongj.com/sql/cte/
WITH RECURSIVE 执行过程:
WITH RECURSIVE语句包含了两个部分
* non-recursive term(非递归部分),即上例中的union all前面部分
* recursive term(递归部分),即上例中union all后面部分
执行步骤如下:
1. 执行non-recursive term。(如果使用的是union而非union all,则需对结果去重)其结果作为recursive term中对result的引用,
同时将这部分结果放入临时的working table中
2. 重复执行如下步骤,直到working table为空:用working table的内容替换递归的自引用,执行recursive term,
(如果使用union而非union all,去除重复数据),并用该结果(如果使用union而非union all,则是去重后的结果)替换working table
--添加层级level,在根节点定义一个level,再union all递归子节点时,使用rec上一条记录进行计算
WITH RECURSIVE rec AS
(
SELECT p.gid OBJECTID,1 as level,p.USID,p.SORT,p.end_usid,p.start_usid,p.DISTRICT,sde.st_astext(p.shape) PATHS,
p.LENGTH,p.D_S D_SIZE, cast(p.gid as varchar(20480)) chain_node FROM sde.ps_pipe_zy_new p WHERE p.start_usid = '060209-32302010-000014'
union ALL
SELECT t.gid OBJECTID,r.level+1,t.USID,t.SORT,t.end_usid,t.start_usid,t.DISTRICT,sde.st_astext(t.shape) PATHS,
t.LENGTH,t.D_S D_SIZE, cast(r. chain_node||'>'||t.gid as varchar(20480)) chain_node FROM sde.ps_pipe_zy_new t , rec r where r.start_usid = t.end_usid
)
SELECT * FROM rec;