暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

postgresql 函数实现-数据类型转换实例

最帅dba工作笔记 2018-12-21
6083

postgresql 函数实现-数据类型转换实例

最近小崔在项目上做迁移遇到了一个很棘手的数据类型转换问题,今天给大家分享下。

一. integer 转 boolean

问题描述:客户使用hibernate自动生成sql语句,其中有一段Sql如下:

select userdepart0_.ID as ID251_, userdepart0_.CREATE_TIME as CREATE2_251_, userdepart0_.MODIFY_TIME as MODIFY3_251_, userdepart0_.DEPARTMENT_ID as DEPARTMENT7_251_, userdepart0_.ORDER_NUMBER as ORDER4_251_, userdepart0_.PLURALITY as PLURALITY251_, userdepart0_.TYPE as TYPE251_, userdepart0_.USER_ID as USER8_251_

from table1 userdepart0_

where userdepart0_.PLURALITY=false and userdepart0_.USER_ID='123123112312';

这个sql 在执行的时候就会报:

ERROR:  错误:  操作符不存在: integer = boolean

LINE 3: where userdepart0_.PLURALITY=false and userdepart0_.USER_ID=...

                                    ^

HINT:  没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.

SQL 状态:42883

字符: 384

查看表中的数据类型:

这里的问题就是查询的数据类型boolean型和对应的数据库中integer类型不匹配。所以需要将数据类型进行转换

具体操作:

 创建转换function:

CREATE OR REPLACE FUNCTION "PUBLIC".integer_eq_boolean(integer, BOOLEAN) RETURNS BOOLEAN

    AS $$

  begin

    select $1 = $2::int;

  end

$$

language pluxsql;

ALTER FUNCTION "PUBLIC".integer_eq_boolean(integer, BOOLEAN) OWNER TO uxdb;

定义运算符:

CREATE OPERATOR "PUBLIC".= (

    PROCEDURE = "integer_eq_boolean",

    LEFTARG = integer,

    RIGHTARG = BOOLEAN

);

ALTER OPERATOR "PUBLIC".= (integer, BOOLEAN) OWNER TO "uxdb";

再次执行sql及正常:

二. 多种类型转换

问题描述:sql第二种情况:

select roleassign0_.ROLE_ID as col_0_0_ from table2 roleassign0_

where roleassign0_.INCLUDE_CHILDREN=1 and (roleassign0_.ORG_TYPE='UNIT' or roleassign0_.ORG_TYPE='DEPARTMENT')

and (roleassign0_.ASSIGN_ID in ('909499817214364035')) and roleassign0_.APPLICATION_ID=1000000000;

错误:  操作符不存在: character varying = integer

第2行where roleassign0_.INCLUDE_CHILDREN=1 and (roleassign0_.ORG_...

                                        ^

提示:  没有匹配指定名称和参数类型的操作符. 您也许需要增加明确的类型转换.

查看表中字段的数据类型:

这个值传入的是1 ,实际的数据库类型是varchar,所以这样的话需要创建一个函数去做转换。

CREATE OR REPLACE FUNCTION "PUBLIC".varying_eq_integer(

    character varying,

    integer)

    RETURNS boolean

    LANGUAGE 'pluxsql'

    COST 100

    VOLATILE

AS $BODY$

  begin

   return $1::int = $2;     --把第一个值转成integer

  end

$BODY$;

ALTER FUNCTION "PUBLIC".varying_eq_integer(character varying, integer) OWNER TO cetc15;

CREATE OPERATOR "PUBLIC".= (

    PROCEDURE = "varying_eq_integer",

    LEFTARG = character varying,

    RIGHTARG = integer

);

ALTER OPERATOR "PUBLIC".= (character varying,integer) OWNER TO "cetc15";

重新跑sql语句

    select roleassign0_.ROLE_ID as col_0_0_ from table2 roleassign0_

    where roleassign0_.INCLUDE_CHILDREN=1 and (roleassign0_.ORG_TYPE='UNIT' or roleassign0_.ORG_TYPE='DEPARTMENT')

    and (roleassign0_.ASSIGN_ID in ('909499817214364035')) and roleassign0_.APPLICATION_ID=1000000000;

错误:  无效的整数类型输入语法: "UNIT"

第2行...n0_.INCLUDE_CHILDREN=1 and (roleassign0_.ORG_TYPE='UNIT' or ...

虽然保证了varchar转换成了integer,但是在第二个地方varchar也跟着转成了integer,但是这个字段是个varchar类型。

为了解决这个问题,需要将varchar对应的转成varchar型。

这里要注意,pg里不支持varchar->varchar,但是可以改成text->text,具体方法如下:

CREATE OR REPLACE FUNCTION "PUBLIC".varchar_eq_varchar(

    character varying,

    character varying)

    RETURNS boolean

    LANGUAGE 'pluxsql'

    COST 100

    VOLATILE

AS $BODY$

  begin

    return $1::text = $2::text;     --这里两次转换都是text

  end

$BODY$;

ALTER FUNCTION "PUBLIC".varchar_eq_varchar(character varying, character varying)

    OWNER TO cetc15;

    

CREATE OPERATOR "PUBLIC".= (

    PROCEDURE = "varchar_eq_varchar",

    LEFTARG = character varying,

    RIGHTARG = character varying

);

ALTER OPERATOR "PUBLIC".= (character varying,character varying) OWNER TO "cetc15";

再次执行sql:

成功

postgresql 可以通过修改数据库内部内置的转换法则将其开启,但是未必好用,一但无法实现,还是需要使用function转换的方法去进行修改。方法连接如下:https://yq.aliyun.com/articles/424712


THAT'S ALL

BY CUI PEACE




本文分享自微信公众号 - 最帅dba工作笔记,如有侵权,请联系 service001@enmotech.com 删除。
文章转载自最帅dba工作笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论