利用SQL生成自定义长度流水单号
需求:(1)编码规则:DICTZXXQ+年月日+四位流水号,如:DICTZXXQ202112070001
需求:(2)①编号组成规则:单头+日期+流水码,共14位。②单头规则:四位,模块汉语名称的前四个字拼音首字母缩写,如与已有重复,则顺延选择后面的汉字,如只有四个汉字则从第一个汉子拼音的第二个字母命名,依次类推。③日期规则:六位,YYMMDD④流水规则:四位,按天编码,
通用SQL
SELECT NVL(TRIM(TO_CHAR(TO_NUMBER(SUBSTR(MAX(SM_SELECTION_NUMBER),18))+1,'0000')),'0001') FROM SM_SELECTION_REQUIREMENT WHERE SM_SELECTION_NUMBER LIKE ?
SQL函数解析(不想了解可不用看)
SQL所用到的函数(MAX(),SUBSTR(),TO_NUMBER(),TO_CHAR(),TRIM(),NVL())
1.MAX()函数: 获取某个表某一列最大字段 注:字段数据可以是数值、字符串或是日期时间数据类型。
SELECT MAX(SM_SELECTION_NUMBER) FROM SM_SELECTION_REQUIREMENT -- DICTZXXQ202112079999
2.SUBSTR()函数: 字符截取 注:截取规则(左闭右开)
格式1 | 格式2 |
---|---|
substr(string string, int a, int b); | substr(string string, int a) ; |
1、string 需要截取的字符串a 2、截取字符串的开始位置(注:当a等于0或1时,都是从第一位开始截取) 3、b 要截取的字符串的长度 | 1、string 需要截取的字符串 2、a 可以理解为从第a个字符开始截取后面所有的字符串。 |
SELECT SUBSTR(MAX('DICTZXXQ202112071111'), 17) FROM SM_SELECTION_REQUIREMENT -- 1111
TO_NUMBER()函数: 将字符串转换为数值型的格式 注:被转换的字符串必须符合数值类型格式,如果被转换的字符串不符合数值型格式,Oracle将抛出错误提示;
例子:
select to_number('$12345.678', '$999999.99') from SM_SELECTION_REQUIREMENT; -- 抛异常
select to_number('$12345.678', '$999999.999') from SM_SELECTION_REQUIREMENT; -- 12345.678
-- 生成的新值增1
SELECT to_NUMBER( SUBSTR(MAX('DICTZXXQ202112070111'), 17))+1 FROM SM_SELECTION_REQUIREMENT -- 112
TO_CHAR()函数: 将数值型或者日期型转化为字符型
函数 | 返回 | 描述 | 例子 |
---|---|---|---|
to_char(timestamp, text) | text | 把 timestamp 转换成 string | to_char(timestamp ‘now’,‘HH12:MI:SS’) |
to_char(int, text) | text | 把 int4/int8 转换成 string | to_char(125, ‘999’) |
to_char(float, text) | text | 把 float4/float8 转换成 string | to_char(125.8, ‘999D9’) |
to_char(numeric, text) | text | 把 numeric 转换成 string | to_char(numeric ‘-125.8’, ‘999D99S’) |
-- 日期格式
select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from dual; -- 2022-01-25 09:24:35
-- 数字格式
select to_char(88877) from SM_SELECTION_REQUIREMENT; -- 88877
select to_char(1234567890,'099999999999999') from SM_SELECTION_REQUIREMENT; -- 000001234567890
select to_char(12345678,'999,999,999,999') from SM_SELECTION_REQUIREMENT; -- 12,345,678
select to_char(1234567890,'999,999,999,999.9999') from SM_SELECTION_REQUIREMENT; -- 1,234,567,890.0000
-- 需求代码
SELECT to_char(to_NUMBER( SUBSTR(MAX('DICTZXXQ202112070111'), 17))+1,'0000') FROM SM_SELECTION_REQUIREMENT -- 0112
TRIM()函数: 去除空格。
-- 第一种,即大家都比较熟悉的去除空格。
--TRIM去除指定字符的前后空格
SELECT TRIM(' dd df ') FROM dual --(dd df)
--LTRIM去除指定字符的前面空格
SELECT LTRIM(' dd df ') FROM dual --(dd df )
--RTRIM去除指定字符后面后空格
SELECT RTRIM(' dd df ') FROM dual --( dd df)
-- 第二种:去除字符:
-- “109”拆分成字符“1”,“0”,“9”,当有1,0,或者9 的时候就截取掉,一旦下一个字符不是‘1’,‘0’,‘9’就返回结果。
select ltrim('10999910224323109999999','109') from dual; -- 224323109999999
select rtrim('10999910224323109999999','109') from dual; -- 10999910224323
-- 表示字符串string2去除前面|后面|前后面(leading|trailing|both)的字符string1,默认去除方式为both
SELECT TRIM(leading|trailing|both string1 FROM string2) FROM dual;
-- 去掉前面的‘d’
SELECT trim(leading 'd' from 'dfssad') FROM dual; -- fssad
-- 去掉前后面‘1’
SELECT trim(both '1' from '123s1fd111') FROM dual; -- 23s1fd
-- 去掉后面‘2’
SELECT trim(trailing '2' from '213dsq12') FROM dual; -- 213dsq1
-- 需求代码
SELECT trim(to_char(to_NUMBER( SUBSTR(MAX('DICTZXXQ202112070111'), 17))+1,'0000')) FROM SM_SELECTION_REQUIREMENT --0112
NVL()函数: 第一个值不为空返回第一个值否则返回第二个值,都为NULL返回NULL
SELECT NVL(trim(to_char(to_NUMBER( SUBSTR(MAX(null), 17))+1,'0000')),'0001') FROM dual --0001
JAVA代码
/**
* 生成流水号
*
* @return
*/
public String buildNumber() {
//1.流水号前缀 2. 把当前日期去数据比较获取最大数 新数据+1 没有就设置为0001
String pre = NameDefine.SELECTION_DEMAND_SERIAL_NUMBER;
String date = DateFormatUtils.format(new Date(), "yyyyMMdd");
String number = selectionRequirementRepository.generateNumber(date);
return pre + date + number;
}