时间:2024-08-19 点击: 次 来源:网络 作者:佚名 - 小 + 大
1. 数据库和程序的解决方案 1.1. Oracle数据库函数切换pg方案(自定义pg函数与view方式) 1.1.1. 转换sys_guid() pg_sys_guid() CREATE or REPLACE FUNCTION "sys_guid"() RETURNS "pg_catalog"."varchar" AS $BODY$ 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; $BODY$ LANGUAGE plpgsql VOLATILE SECURITY DEFINER; 1.1.2. orcale-decode函数 ---------------------------------字符串decode函数--------------------------------------------------- create or replace function decode(variadic p_decode_list text[]) returns text as $$ declare -- 获取数组长度(即入参个数) v_len integer := array_length(p_decode_list, 1); -- 声明存放返回值的变量 v_ret text; begin /* * 功能说明:模拟Oracle中的DECODE功能(字符串处理, 其它格式可以自行转换返回值) * 参数说明:格式同Oracle相同,至少三个参数 * 实现原理: 1、VARIADIC 允许变参; 2、Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值,否则取最后一位值(最后一位为偶数为,否则为null) */ -- 同Oracle相同当参数不足三个抛出异常 if v_len >= 3 then -- Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值 for i in 2..(v_len - 1) loop v_ret := null; if mod(i, 2) = 0 then if p_decode_list[1] = p_decode_list[i] then v_ret := p_decode_list[i+1]; elsif p_decode_list[1] <> p_decode_list[i] then if v_len = i + 2 and v_len > 3 then v_ret := p_decode_list[v_len]; end if; end if; end if; exit when v_ret is not null; end loop; else raise exception 'UPG-00938: not enough args for function.'; end if; return v_ret; end; $$ language plpgsql; -----------------------------------------------------------数字decode函数-------------------------------------------------------- create or replace function decode(variadic p_decode_list numeric[]) returns numeric as $$ declare -- 获取数组长度(即入参个数) v_len integer := array_length(p_decode_list, 1); -- 声明存放返回值的变量 v_ret numeric; begin /* * 功能说明:模拟Oracle中的DECODE功能(字符串处理, 其它格式可以自行转换返回值) * 参数说明:格式同Oracle相同,至少三个参数 * 实现原理: 1、VARIADIC 允许变参; 2、Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值,否则取最后一位值(最后一位为偶数为,否则为null) */ -- 同Oracle相同当参数不足三个抛出异常 if v_len >= 3 then -- Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值 for i in 2..(v_len - 1) loop v_ret := null; if mod(i, 2) = 0 then if p_decode_list[1] = p_decode_list[i] then v_ret := p_decode_list[i+1]; elsif p_decode_list[1] <> p_decode_list[i] then if v_len = i + 2 and v_len > 3 then v_ret := p_decode_list[v_len]; end if; end if; end if; exit when v_ret is not null; end loop; else raise exception 'UPG-00938: not enough args for function.'; end if; return v_ret; end; $$ language plpgsql; --------------------------------------------------------- create or replace function decode(variadic p_decode_list character[]) returns character as $$ declare -- 获取数组长度(即入参个数) v_len integer := array_length(p_decode_list, 1); -- 声明存放返回值的变量 v_ret character; begin /* * 功能说明:模拟Oracle中的DECODE功能(字符串处理, 其它格式可以自行转换返回值) * 参数说明:格式同Oracle相同,至少三个参数 * 实现原理: 1、VARIADIC 允许变参; 2、Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值,否则取最后一位值(最后一位为偶数为,否则为null) */ -- 同Oracle相同当参数不足三个抛出异常 if v_len >= 3 then -- Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值 for i in 2..(v_len - 1) loop v_ret := null; if mod(i, 2) = 0 then if p_decode_list[1] = p_decode_list[i] then v_ret := p_decode_list[i+1]; elsif p_decode_list[1] <> p_decode_list[i] then if v_len = i + 2 and v_len > 3 then v_ret := p_decode_list[v_len]; end if; end if; end if; exit when v_ret is not null; end loop; else raise exception 'UPG-00938: not enough args for function.'; end if; return v_ret; end; $$ language plpgsql; 1.1.3. oracle dual表pg实现 CREATE OR REPLACE VIEW dual AS SELECT NULL::"unknown" WHERE 1 = 1; -- 开放给用户 ALTER TABLE dual OWNER TO himc; GRANT ALL ON TABLE dual TO himc; GRANT SELECT ON TABLE dual TO public; 1.1.4. oracle-merge into的pg实现 --/*** --*pg实现 --* 实例:插入模型表一条数据,如果id存在,则版本号加1,并且更新更新时间。 --*其中 EXCLUDED.{字段}代表插入字段值,即now() --* --*/ INSERT INTO himc_model ( modelid, modelname, status, CREATEUSER, VERSION, createtime, updatetime, modifyuser ) VALUES ( 'himc_1678696981571', '新建模型2023-03-28 16:08:23', '0', 'admin1', 1, now( ), now( ), 'admin1' ) ON CONFLICT(modelid) DO UPDATE SET version = (SELECT version FROM himc_model WHERE modelid = 'himc_1678696981571') + 1, updatetime = EXCLUDED.updatetime RETURNING *; --/*** --*对应的oracle实现 --* 实例:插入模型表一条数据,如果id存在,则版本号加1,并且更新更新时间。 --*/ MERGE INTO himc_model A USING ( SELECT 'himc_1678696981571' AS modelId FROM dual ) b ON ( A.modelId = b.modelId ) WHEN NOT MATCHED THEN INSERT ( modelid, modelname, status, CREATEUSER, VERSION, createtime, updatetime, modifyuser ) VALUES ( 'himc_1678696981571', '新建模型2023-03-28 16:08:23', '0', 'admin1', 0, sysdate, sysdate, 'admin1' ) WHEN MATCHED THEN UPDATE SET A.VERSION = A.VERSION + 1 SET A.UPDATETIME = SYSDATE WHERE A.modelId = 'himc_1678696981571' AND A.VERSION >= 1 1.2. 程序切换-mybatis方言集成 1.2.1. DatabaseIdProvider 与SqlSessionFactory 注入 /** * 自动识别使用的数据库类型 在mapper.xml中databaseId的值就是跟这里对应, 如果没有databaseId选择则说明该sql适用所有数据库 */ @Bean public DatabaseIdProvider getDatabaseIdProvider() { DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider(); Properties properties = new Properties(); properties.setProperty("Oracle", "oracle"); properties.setProperty("MySQL", "mysql"); properties.setProperty("DB2", "db2"); properties.setProperty("Derby", "derby"); properties.setProperty("H2", "h2"); properties.setProperty("HSQL", "hsql"); properties.setProperty("MS-SQL", "ms-sql"); properties.setProperty("PostgreSQL", "postgresql"); databaseIdProvider.setProperties(properties); return databaseIdProvider; } @Bean(name = "sessionFactory") @Primary public SqlSessionFactory sessionFactory() throws Exception { MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); sqlSessionFactoryBean.setDatabaseIdProvider(getDatabaseIdProvider()); sqlSessionFactoryBean.setDataSource(dataSource()); sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage); PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:sql-mapper/**/*.xml")); sqlSessionFactoryBean.setTypeEnumsPackage("com.hisense.hiatmp.himc.**.enums"); return sqlSessionFactoryBean.getObject(); } 1.2.2. mapper改造(兼容的不需要改造,不添加databaseId即所有的数据源共用) <insert id="insertProcess" databaseId="oracle"> insert into himc_model_process(processId, modelId, processName, calcId, calcParam, calcMapping, processOrder,logic, type, computetype) values( #{processId,jdbcType=VARCHAR}, #{modelId,jdbcType=VARCHAR}, #{processName,jdbcType=NVARCHAR}, #{calcId,jdbcType=VARCHAR}, #{calcParam,jdbcType=VARCHAR}, #{calcMapping,jdbcType=NVARCHAR}, #{processOrder,jdbcType=CHAR}, #{logic,jdbcType=CLOB}, #{type,jdbcType=CHAR}, #{computeType,jdbcType=CHAR}) </insert> <insert id="insertProcess" databaseId="postgresql"> insert into himc_model_process(processId, modelId, processName, calcId, calcParam, calcMapping, processOrder,logic, type, computetype) values( #{processId,jdbcType=VARCHAR}, #{modelId,jdbcType=VARCHAR}, #{processName,jdbcType=VARCHAR}, #{calcId,jdbcType=VARCHAR}, #{calcParam,jdbcType=VARCHAR}, #{calcMapping,jdbcType=VARCHAR}, #{processOrder,jdbcType=CHAR}, #{logic,jdbcType=CLOB}, #{type,jdbcType=CHAR}, #{computeType,jdbcType=CHAR}) </insert> |
下一篇:大数据权限认证Kerberos