编辑
2023-07-18
学习记录
00

前提

在项目中经常会使用到存储过程,来优化sql语句,比如获取两个时间差的日期等,减少sql的复杂性

创建语法

sql
--创建函数 CREATE OR REPLACE FUNCTION 函数名(参数1 模式 参数类型) RETURN 返回值类型 AS 变量1 变量类型; 变量2 变量类型; BEGIN 函数体; END 函数名;

其他语法

sql
--删除函数 DROP FUNCTION 函数名; --确定函数状态 SELECT OBJECT_NAME FROM USER_OBJECTS WHERE STATUS='INVALID' AND OBJECT_TYPE='FUNCTION'; --编译函数 ALTER FUNCTION 函数名 COMPILE; --查看函数代码 SELECT TEXT FROM USER_SOURCE WHERE NAME='函数名';

无参

sql
--创建函数 CREATE OR REPLACE FUNCTION F_CUR_DATETIME RETURN VARCHAR2 IS BEGIN RETURN TO_CHAR(SYSDATE,'YYYY"年"MM"月"DD"日"HH24"时"MI"分"SS"秒"'); END; --调用函数方式1 SELECT F_CUR_DATETIME() FROM DUAL; --调用函数方式2 BEGIN DBMS_OUTPUT.PUT_LINE(F_CUR_DATETIME); END;

有入参

sql
CREATE OR REPLACE FUNCTION GET_SAL(NAME VARCHAR2) RETURN NUMBER AS V_SAL EMP.SAL%TYPE; BEGIN SELECT SAL INTO V_SAL FROM EMP WHERE UPPER(ENAME)=UPPER(NAME); RETURN V_SAL; END; --调用函数 BEGIN DBMS_OUTPUT.PUT_LINE(GET_SAL(NAME => 'SMITH')); END;

有出参

sql
CREATE OR REPLACE FUNCTION GET_NAME(ENO NUMBER,OJOB OUT VARCHAR2) RETURN VARCHAR2 AS NAME EMP.ENAME%TYPE; BEGIN SELECT ENAME,JOB INTO NAME,OJOB FROM EMP WHERE EMPNO=ENO; RETURN NAME; END; --调用函数 DECLARE V_NAME EMP.ENAME%TYPE; V_JOB EMP.JOB%TYPE; BEGIN V_NAME:=GET_NAME(ENO=>7900,OJOB => V_JOB); DBMS_OUTPUT.PUT_LINE('姓名:'||V_NAME||',工作:'||V_JOB); END;

引用自

实际使用

sql
create or replace function GET_OVERDUE_DAYS(patientId in varchar2, visitNo in varchar2) return number is VD_OVERDUE_DAYS number; VD_DISCHARGE_TIME DATE; VD_RECEIVE_TIME DATE; VD_EXSIT_REC number; begin --获取逾期天数 select t.discharge_date_time INTO VD_DISCHARGE_TIME from pat_visit t where t.patient_id= patientId and t.visit_id = visitNo; select count(1) into VD_EXSIT_REC from rec_mr_index t where t.patient_id=patientId and t.visit_no = visitNo; if VD_EXSIT_REC >0 then select t.receive_time into VD_RECEIVE_TIME from rec_mr_index t where t.patient_id=patientId and t.visit_no = visitNo; if VD_RECEIVE_TIME is null then VD_RECEIVE_TIME:=sysdate; end if; else VD_RECEIVE_TIME:=sysdate; end if; SELECT FLOOR(VD_RECEIVE_TIME - VD_DISCHARGE_TIME) - 7 INTO VD_OVERDUE_DAYS FROM DUAL; if VD_OVERDUE_DAYS < 0 then VD_OVERDUE_DAYS:= 0; end if; return(VD_OVERDUE_DAYS); end GET_OVERDUE_DAYS;
编辑
2023-07-14
学习记录
00

前提

由于业务需要,前端传递已经配置好的sql,所以我需要实现一个通用的动态查询方案

实现

controller

java
//contorller @ApiOperation(value = "执行指定sql的脚本") @PostMapping("getSqlScriptExcuteResult") public Result<Object> getSqlScriptExcuteResult(@RequestBody @Validated RecSearchSolutionSqlScriptExcuteResultRequest request) { List<Map<String, Object>> map = iRecSearchSolutionService.getSqlScriptExcuteResult(request); return Result.success(map); }

service层

java
//Service List<Map<String, Object>> getSqlScriptExcuteResult(RecSearchSolutionSqlScriptExcuteResultRequest request);

impl层

java
//impl @Override public List<Map<String, Object>> getSqlScriptExcuteResult(RecSearchSolutionSqlScriptExcuteResultRequest request) { if (request.getPage() != 0 && request.getRows() != 0) { Integer begin= (request.getPage()-1)*request.getRows(); Integer end=request.getPage()*request.getRows(); String newSql = MessageFormat.format("SELECT *\n" + " FROM (SELECT TMP.*, ROWNUM ROW_ID\n" + " FROM (" + "{0}" + ") TMP\n" + " WHERE ROWNUM <= {1})\n" + " WHERE ROW_ID > {2}\n", request.getSql(),end,begin); request.setSql(newSql); } logger.info(request.getSql()); List<Map<String, Object>> map = commonService.queryForMapList(request.getSql()); for (Map<String,Object> m: map) { for (Map.Entry<String, Object> set:m.entrySet()) { if (set.getValue() instanceof Date){ set.setValue(DateUtil.format((Date)set.getValue(),"yyyy-MM-dd HH:mm:ss")); } } } return map; }

commonService

java
package com.lhw.service; import com.lhw.mapper.SqlHelperMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @Service public class CommonService { @Resource private JdbcTemplate jdbcTemplate; @Resource private SqlHelperMapper sqlHelperMapper; public String queryForString(String sql) { List<String> list = jdbcTemplate.queryForList(sql, String.class); if (list.size() == 0) { return ""; } else { return list.get(0); } } public List<String> queryForStringArray(String sql) { List<String> list = jdbcTemplate.queryForList(sql, String.class); return list; } public List<Date> queryForDateArray(String sql) { List<Date> list = jdbcTemplate.queryForList(sql, Date.class); return list; } public Integer queryForInt(String sql) { List<Integer> list = jdbcTemplate.queryForList(sql, Integer.class); if (list.size() == 0) { return 0; } else { return list.get(0); } } public Date queryForDate(String sql) { List<Date> list = jdbcTemplate.queryForList(sql, Date.class); if (list.size() == 0) { return new Date(); } else { return list.get(0); } } public <T> List<T> queryForList(String sql,Class<T> elementType ){ List<T> list= jdbcTemplate.queryForList(sql, elementType); return list; } public <T> List<T> query(String sql,RowMapper<T> rowMapper){ return jdbcTemplate.query(sql,rowMapper); } public List<LinkedHashMap<String, Object>> superSelect(String sql) { return sqlHelperMapper.superSelect(sql); } public Integer superSelectForInt(String sql) { return sqlHelperMapper.superSelectForInt(sql); } public List<Map<String, Object>> queryForMapList(String sql) { return jdbcTemplate.queryForList(sql); } }

可能出现的错误

使用queryForList,会提示Incorrect column count: expected 1, actual 2,因为只支持返回一个list 所以我们就需要在commonService里调整,直接使用query

java
public List<SolutionConditionDictResponse> queryForDictList(String sql) { return jdbcTemplate.query(sql,BeanPropertyRowMapper.newInstance(SolutionConditionDictResponse.class)); }
编辑
2023-07-12
学习记录
00

前提

由于业务要求需要根据list里的时间排序来再次进行排序

实现

在Java中,你可以使用Collections.sort()方法对List中的元素进行排序。如果要按照时间排序,你需要确保每个元素都包含一个对应的时间戳或日期对象,并使用Comparator接口定义的比较方法来比较元素的时间戳或日期。

java
//升序 Collections.sort(emrDocVEntityList, new Comparator<EmrDocVRes>() { @Override public int compare(EmrDocVRes o1, EmrDocVRes o2) { return o1.getDocTime().compareTo(o2.getDocTime()); } });
编辑
2023-07-11
遇到的问题
00

前提

这是因为mybatis默认开启驼峰命名法,按规则数据表中的lastName字段应对应实体类中的last_name属性,而实体类中的lastName属性应对应数据表中的last_name字段。

解决方式1

在application.yml中,关闭驼峰转换,可能会出现问题,影响以前的实体查不到内容

yml
mybatis-plus.configuration.map-underscore-to-camel-case=false

解决方式2

局部解决,写个将驼峰转回下划线命名方式的接口,优点不影响全局配置

java
public String camelToUnderline(String camelCase) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < camelCase.length(); i++) { char c = camelCase.charAt(i); if (Character.isUpperCase(c)) { if (i != 0) { sb.append("_"); } sb.append(Character.toLowerCase(c)); } else { sb.append(c); } } if (sb.charAt(sb.length() - 1) == '_') { sb.deleteCharAt(sb.length() - 1); } return sb.toString().toUpperCase(); }
编辑
2023-07-09
前端
00

原因

问题描述:

报错:Error: error:0308010C

envelope routines::unsupported

报错原因:

因为 node.js V17版本中最近发布的OpenSSL3.0, 而OpenSSL3.0对允许算法和密钥大小增加了严格的限制

解决方法

  1. 卸载该nodejs,安装nodejs17以下版本
  2. idea终端输入 set NODE_OPTIONS=--openssl-legacy-provider