查询中的字符串连接,将字符串填充到固定长度

时间:2014-02-19 13:26:31

标签: sql string oracle oracle10g

我在Oracle 10g数据库上运行。 该表有一个CODE列,它是主键,是一个varchar。 字段始终采用格式“xx xxx xx”,例如“20 965 04”,第一个和第二个是不相关的数字,最后一个部分是连续数字。

我要做的是,执行一个INSERT,其中前两个部分的密钥保持不变,最后一个部分比这些特定的第一部分的最高连续数字多一个。

所以,我开始玩一个小小的,我的第一个方法是:

SUBSTR('20 031 03', 0, 7)||(TO_CHAR(TO_NUMBER( 
 SUBSTR(
   (SELECT MAX(CODE )
   FROM table tmk
   WHERE tmk.CODE LIKE SUBSTR('20 031 03', 0, 6)||'%')
  , 8,  9) ) + 1
 ))

这种方法已经不是很漂亮了,但在我看来还行。 但后来我意识到,当连续数字低于10时,在TO_NUMBER和TO_CHAR之后,它是cource,例如5而不是05。 所以,如果我有“20 965 04”,我得到的是“20 965 5”,但我需要“20 965 05”!

所以,我能想到的唯一方法是在增加数字后检查字符串长度的case语句,如果是neccecary则添加0:

SELECT
CASE (LENGTH(TO_CHAR(TO_NUMBER( SUBSTR(
   (SELECT MAX(CODE)
   FROM table tmk
   WHERE tmk.CODE LIKE SUBSTR('20 031 03', 0, 6)||'%')
  , 8, 9) ) + 1
 )))
WHEN 1 THEN
SUBSTR('20 031 03', 0, 7)||'0'||(TO_CHAR(TO_NUMBER( 
 SUBSTR(
   (SELECT MAX(CODE)
   FROM table tmk
   WHERE tmk.CODE LIKE SUBSTR('20 031 03', 0, 6)||'%')
  , 8,  9) ) + 1
 ))
ELSE
SUBSTR('20 031 03', 0, 7)||(TO_CHAR(TO_NUMBER( 
 SUBSTR(
   (SELECT MAX(CODE)
   FROM table tmk
   WHERE tmk.CODE LIKE SUBSTR('20 031 03', 0, 6)||'%')
  , 8,  9) ) + 1
 ))
END
FROM dual;

所以这很有效,但它就像我见过的最丑陋的SQL。但由于我目前不知何故坚持下去,有没有人有更好更短的方法来做同样的事情?

2 个答案:

答案 0 :(得分:1)

查看LPAD功能。

例如,SELECT LPAD(1,2,'0') FROM DUAL将返回01

答案 1 :(得分:0)

TO_CHAR函数有一个可以使用的格式参数:

SUBSTR('20 031 03', 1, 7) || 
TO_CHAR(
  TO_NUMBER( 
   SUBSTR(
     (SELECT MAX(CODE) FROM table tmk WHERE tmk.CODE LIKE SUBSTR('20 031 03', 1, 6) || '%')
   , 8,  2) + 1
  )
, 'FM00')

我稍微改变了你的SUBSTR参数。索引从1开始。您想要最后两位数。