如何从GS1-128条码字符串中提取指定CODE对应的数据?
可以实现该函数,以下是具体实现方案
背景信息
包装盒上的GS1-128条码为(01)18777777777777(15)241129(10)L3333333(90)02,设备扫描后得到字符串:01187777777777771524112910L3333333F9002。
数据库中存在barcode_settings表,表结构及配置如下:
| CODE | NAME | SIZE |
|---|---|---|
| 01 | GTIN | 14 |
| 10 | LOT | -1 为可变长度,以字符F结尾 |
| 15 | 最佳食用日期(YYMMDD) | 6 |
| 90 | 总计 | 2 |
需求是实现一个包含P_STRING(扫描后的条码字符串)和P_CODE(目标字段编码)两个参数的my_func函数,满足以下调用结果:
select my_func('01187777777777771524112910L3333333F9002','01') from dual;→ 返回18777777777777select my_func('01187777777777771524112910L3333333F9002','10') from dual;→ 返回L3333333select my_func('01187777777777771524112910L3333333F9002','15') from dual;→ 返回241129
实现思路
- 定位
P_CODE在P_STRING中的起始位置; - 查询
barcode_settings表获取该编码对应的长度规则:- 若为正整数:从编码后截取对应长度的字符;
- 若为
-1:从编码后开始截取,直到遇到终止符F,排除F本身;
- 处理编码不存在的异常情况,返回空值。
Oracle PL/SQL函数实现
CREATE OR REPLACE FUNCTION my_func(P_STRING IN VARCHAR2, P_CODE IN VARCHAR2) RETURN VARCHAR2 IS v_size VARCHAR2(20); v_start_pos NUMBER; v_result VARCHAR2(200); BEGIN -- 获取当前编码的长度配置 SELECT SIZE INTO v_size FROM barcode_settings WHERE CODE = P_CODE; -- 定位目标编码的起始位置 v_start_pos := INSTR(P_STRING, P_CODE); IF v_start_pos = 0 THEN RETURN NULL; END IF; -- 根据长度规则提取内容 IF v_size = '-1' THEN v_result := SUBSTR(P_STRING, v_start_pos + 2, INSTR(P_STRING, 'F', v_start_pos) - (v_start_pos + 2)); ELSE v_result := SUBSTR(P_STRING, v_start_pos + 2, TO_NUMBER(v_size)); END IF; RETURN v_result; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN NULL; -- 配置表无对应编码时返回空 END; /
验证结果
执行题目中的示例查询,可得到预期的返回结果,完全符合需求。
内容的提问来源于stack exchange,提问作者Pointer
相关产品推荐
相关产品推荐

