如何计算oracle中从一个字符到另一个字符的子字符串的长度
Posted
技术标签:
【中文标题】如何计算oracle中从一个字符到另一个字符的子字符串的长度【英文标题】:how to count the length of a substring from one character to other in oracle 【发布时间】:2015-04-22 06:03:22 【问题描述】:我必须从 sql (Oracle 11g) 中的字符串更新子字符串的长度
从这里>> #L1313.0000002.CGNMC
到这里>> #L1313.0000000002.CGNMC
我想计算点(。)之间的字符串长度,如果它小于 10,那么我想附加尽可能多的零以使其变为 10
计算字符串的整个长度并没有帮助,因为更改只能在子字符串中完成。
请帮忙
【问题讨论】:
【参考方案1】:select lpad(substr('#L1313.0000002.CGNMC',
instr('#L1313.0000002.CGNMC','.') + 1,
instr('#L1313.0000002.CGNMC','.',1,2) -
instr('#L1313.0000002.CGNMC','.') - 1),
10, '0') from dual;
lpad('x',10,'0')
- 将 char '0' 添加到字符串 'x' 中,最大为 10
substr(string, start, length)
- 返回子字符串
instr(string,substring[,start[,occurence]])
- 返回字符串中子字符串的位置。 start 是搜索的起点,occurrence 表示搜索第 n 次出现的字符串。
参见 oracle 文档https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions.htm#SQLRF006
【讨论】:
您的解决方案不完整。 OP 只想在点之间的 substr 的长度小于 10 时才这样做。 @LalitKumarB 可能是的。该问题未指定点之间是否有超过 10 个字符的数据。在这种情况下,我会添加CASE...WHEN ... ELSE
类似于您的示例
是的,这就是我想要指出的。当字符串已经有超过 10 个字符时,您将其强制为 10。无论如何,希望它有所帮助:-)【参考方案2】:
我用过update、instr和substr
update table set column_name= case
when (instr(column_name,'.',1,2)-instr(column_name,'.',1,1)-1)<10 then substr(column_name,0,instr(column_name,'.',1,1))||lpad(substr(column_name,instr(column_name,'.',1,1)+1,instr(column_name,'.',1,2)-instr(column_name,'.',1,1)-1),10,'0')||substr(column_name,instr(column_name,'.',1,2))
end
;
查看以下查询以获取演示
select substr('L1313.0000002.CGNMC',0,instr('L1313.0000002.CGNMC','.',1,1))||lpad(substr('L1313.0000002.CGNMC',instr('L1313.0000002.CGNMC','.',1,1)+1,instr('L1313.0000002.CGNMC','.',1,2)-instr('L1313.0000002.CGNMC','.',1,1)-1),10,'0')||substr('L1313.0000002.CGNMC',instr('L1313.0000002.CGNMC','.',1,2)) from dual;
【讨论】:
【参考方案3】:你可以通过以下组合来做到这一点:
SUBSTR INSTR 案例 解码以下查询是如何工作的:
SUBSTR 会给我字符串的一部分,INSTR 会给我点的位置。 CASE 是检查点之间子字符串长度的条件,最后 DECODE 会让我做最后的工作来附加所需的零。
测试用例
我正在考虑所有可能的情况。
SQL> WITH DATA AS
2 ( SELECT '#L1313.0000002.CGNMC' str FROM dual UNION ALL
3 SELECT '#L1313.002.CGNMC' str FROM dual UNION ALL
4 SELECT '#L1313.00123.CGNMC' str FROM dual UNION ALL
5 SELECT '#L1313.12345.CGNMC' str FROM dual UNION ALL
6 SELECT '#L1313.12345678910.CGNMC' str FROM dual
7 )
8 SELECT str,
9 CASE
10 WHEN instr(str, '.', 1, 2) - instr(str, '.', 1, 1) -1 < 10
11 THEN DECODE((instr(str, '.', 1, 2) - instr(str, '.', 1, 1) -1),
12 9, (SUBSTR(str, 1, instr(str, '.', 1, 1))
13 ||'0'
14 ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 8, (SUBSTR(str, 1, instr(str, '.', 1, 1))
15 ||'00'
16 ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 7, (SUBSTR(str, 1, instr(str, '.', 1, 1))
17 ||'000'
18 ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 6, (SUBSTR(str, 1, instr(str, '.', 1, 1))
19 ||'0000'
20 ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 5, (SUBSTR(str, 1, instr(str, '.', 1, 1))
21 ||'00000'
22 ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 4, (SUBSTR(str, 1, instr(str, '.', 1, 1))
23 ||'000000'
24 ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 3, (SUBSTR(str, 1, instr(str, '.', 1, 1))
25 ||'0000000'
26 ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 2, (SUBSTR(str, 1, instr(str, '.', 1, 1))
27 ||'00000000'
28 ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 1, (SUBSTR(str, 1, instr(str, '.', 1, 1))
29 ||'000000000'
30 ||SUBSTR(str, instr(str, '.', 1, 1) + 1)) )
31 ELSE
32 str
33 END new_str
34 FROM DATA;
STR NEW_STR
------------------------ ---------------------------------------------
#L1313.0000002.CGNMC #L1313.0000000002.CGNMC
#L1313.002.CGNMC #L1313.0000000002.CGNMC
#L1313.00123.CGNMC #L1313.0000000123.CGNMC
#L1313.12345.CGNMC #L1313.0000012345.CGNMC
#L1313.12345678910.CGNMC #L1313.12345678910.CGNMC
SQL>
【讨论】:
【参考方案4】:我已经编写了一个可以完成工作的函数,请检查它是否适合你。
SQL> create or replace function paddingstr1( inval varchar2) return varchar2 is
2 lval varchar2(100):=inval;
3 final_str varchar2(100);
4 str3 varchar2(100);
5 str2 varchar2(100);
6 str1 varchar2(100);
7 lpad_str varchar2(100);
8 pos1 int;
9 pos2 int;
10 getval int;
11 begin
12 select instr(lval,'.') into pos1 from dual;
13 select instr(lval,'.',1,2) into pos2 from dual;
14 getval:=pos2-pos1-1;
15 pos1:=pos1+1;
16 select substr(lval,pos1,getval) into lpad_str from dual;
17 select lpad(lpad_str,10,'0') into str2 from dual;
18 select substr(lval,1,pos1-1) into str1 from dual;
19 select substr(lval,pos2) into str3 from dual;
20 final_str:= concat (str1,concat (str2,str3));
21 return final_str;
22 end;
23 /
Function created.
SQL> select paddingstr1('#L1313.0000002.CGNMC') from dual;
PADDINGSTR1('#L1313.0000002.CGNMC')
--------------------------------------------------------------------------------
#L1313.0000000002.CGNMC
SQL> select paddingstr1('#LAD313.002.ERGH') from dual;
PADDINGSTR1('#LAD313.002.ERGH')
------------------------------------------------------------
#LAD313.0000000002.ERGH
【讨论】:
以上是关于如何计算oracle中从一个字符到另一个字符的子字符串的长度的主要内容,如果未能解决你的问题,请参考以下文章
40 python 正则表达式 match方法匹配字符串 使用search函数在一个字符串中查找子字
在 Oracle (> 11g) 中从逗号分隔列表创建表 - 输入字符串限制 4000 个字符