Написание функции номера версии на PL / SQL - PullRequest
0 голосов
/ 03 февраля 2020

Я хочу написать функцию, которая даст мне следующий номер версии для таблицы. В таблице хранится существующая версия для каждой записи. Например, у меня есть таблица cat

cats

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

Ответы [ 2 ]

2 голосов
/ 03 февраля 2020

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

Это швыряет ORA-01722: invalid number. Причина тонкая. Кажется, Oracle применяет оператор конкатенации перед добавлением, так что вы фактически добавляете его в строку '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 <> скрипка за это тоже.

0 голосов
/ 03 февраля 2020

Попробуйте найти маску для TO_NUMBER , чтобы получить десятичное число, этот небольшой пример может помочь:

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;
...