首页 > 解决方案 > 在 PL/SQL 中编写版本号函数

问题描述

我想编写一个函数,它会给我一个表格的下一个版本号。该表将现有版本存储在每条记录上。例如,我有 cat 表

seqid    1
name     Mr Smith
version number  1.2b.3.4

如何编写一个能够根据各种条件增加这些值的程序?

这是我的第一次尝试

if v_username is not null
then v_new_nbr = substr(v_cur_nbr, 1,7)||to_number(substr(v_cur_nbr, 8,1))+1

应该1.2b.3.5

标签: oracleplsql

解决方案


substr(v_cur_nbr, 1,7)||to_number(substr(v_cur_nbr, 8,1))+1

这投掷ORA-01722: invalid number。原因很微妙。似乎 Oracle 在添加之前应用了连接运算符,因此有效地将一个添加到 string '1.2b.3.4'

一种解决方案是在将结果与第一个子字符串连接之前,使用 TO_CHAR 函数将加法与第二个子字符串括起来:

substr(v_cur_nbr, 1,7) || to_char(to_number(substr(v_cur_nbr, 8,1))+1)

db<>fiddle上的工作演示。


顺便说一句,像这样的键是一个糟糕的数据建模。智能钥匙很笨。它们总是会导致可怕的 SQL(如您所见)并有数据损坏的风险。一个合适的模型将为版本号的每个元素提供单独的列。我们可以使用虚拟列来连接显示环境的版本号。

create table cats(
seqid    number
,name     varchar2(32)
,major_ver_no1 number
,major_ver_no2 number
,variant varchar2(1)
,minor_ver_no1 number
,minor_ver_no2 number
,v_cur_nbr  varchar2(16) generated always as (to_char(major_ver_no1,'FM9') ||'.'||
                                              to_char(major_ver_no2,'FM9')  ||'.'||
                                              variant  ||'.'||
                                              to_char(minor_ver_no1,'FM9')  ||'.'||
                                              to_char(minor_ver_no2,'FM9') ) );

所以设置有点令人作呕,但增加版本号是小菜一碟。

update cats
set major_ver_no1 = major_ver_no1 +1 
    , major_ver_no2 = 0
    , variant = 'a';

也有一个db<>fiddle


推荐阅读