Oracle 在PL/SQL中编写版本号函数
我想写一个函数,它将给我一个表的下一个版本号。该表在每条记录上存储现有版本。例如 我有猫桌 猫Oracle 在PL/SQL中编写版本号函数,oracle,plsql,Oracle,Plsql,我想写一个函数,它将给我一个表的下一个版本号。该表在每条记录上存储现有版本。例如 我有猫桌 猫 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
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
尝试搜索掩码以获得十进制数,此小示例可能会有所帮助:
CREATE TABLE tmp_table (version varchar2(100));
INSERT INTO tmp_table(version) VALUES ('1.2b.3.4');
DECLARE
mainVersion NUMBER;
subVersion NUMBER;
currentVersion VARCHAR2(100);
BEGIN
SELECT version INTO currentVersion FROM tmp_table;
mainVersion := TO_NUMBER(SUBSTR(currentVersion,1,3),'9.9') + 0.1;
subVersion := TO_NUMBER(SUBSTR(currentVersion,6,3),'9.9') + 1.1;
UPDATE tmp_table SET version = (mainVersion||'b.'||subVersion);
END;
尝试搜索掩码以获取十进制数,此小示例可能会有所帮助:
CREATE TABLE tmp_table (version varchar2(100));
INSERT INTO tmp_table(version) VALUES ('1.2b.3.4');
DECLARE
mainVersion NUMBER;
subVersion NUMBER;
currentVersion VARCHAR2(100);
BEGIN
SELECT version INTO currentVersion FROM tmp_table;
mainVersion := TO_NUMBER(SUBSTR(currentVersion,1,3),'9.9') + 0.1;
subVersion := TO_NUMBER(SUBSTR(currentVersion,6,3),'9.9') + 1.1;
UPDATE tmp_table SET version = (mainVersion||'b.'||subVersion);
END;
substr(v_cur_nbr,1,7)| to_number(substr(v_cur_nbr,8,1))+1
这会抛出ORA-01722:无效号码
。原因很微妙。Oracle似乎在添加之前应用了连接运算符,因此实际上是在字符串'1.2b.3.4'
中添加一个
一种解决方案是在将结果与第一个子字符串连接之前,使用TO_CHAR函数将加法与第二个子字符串括起来:
substr(v_cur_nbr,1,7)| to_char(to_number)(substr(v_cur_nbr,8,1))+1)
正在进行演示
顺便说一句,像这样的关键是一个糟糕的数据建模。智能钥匙是哑的。它们总是导致可怕的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';
这也有一个很好的解释
substr(v_cur_nbr,1,7)| to_number(substr(v_cur_nbr,8,1))+1
这会抛出ORA-01722:无效号码
。原因很微妙。Oracle似乎在添加之前应用了连接运算符,因此实际上是在字符串'1.2b.3.4'
中添加一个
一种解决方案是在将结果与第一个子字符串连接之前,使用TO_CHAR函数将加法与第二个子字符串括起来:
substr(v_cur_nbr,1,7)| to_char(to_number)(substr(v_cur_nbr,8,1))+1)
正在进行演示
顺便说一句,像这样的关键是一个糟糕的数据建模。智能钥匙是哑的。它们总是导致可怕的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';
这也有一个建议。提示:谷歌序列。@AnkitBajpai-你真的认为这是一个有用的建议吗?特别是当搜索者可能希望为每一类保持一个单调递增的版本号时?我将在Oracle数据库中执行此操作。@pryorlaughs如果您可以控制此表的设计,我会将复杂的版本号字符串拆分为其组成部分的单独列。这种方式更新(现在很简单)版本号的特定部分很容易。使用虚拟列或视图可以很容易地从组件重构版本号。提示:Google Sequences@AnkitBajpai-你真的认为这是一个有用的建议吗?特别是当搜索者可能希望为每一类保持一个单调递增的版本号时?我将在Oracle数据库中执行此操作。@pryorlaughs如果您可以控制此表的设计,我会将复杂的版本号字符串拆分为其组成部分的单独列。这种方式更新(现在很简单)版本号的特定部分很容易。使用虚拟列或视图可以轻松地从组件重构版本号。感谢您提供此信息!谢谢你的信息!