Oracle 11g: как генерировать числа, как в плане счетов

#oracle #oracle11g #numbers #account #generate

#Oracle #oracle11g #числа #Учетная запись #генерировать

Вопрос:

В oracle 11g (SQL или PL / SQL) для плана счетов я хочу генерировать такие числа, как: начните с уровня 2: (номер кондиционера уровня 1. равны 1,2,3,4,5)

если он находится в заголовке 1, который является активом, тогда он будет генерировать первое число как 101, если он находится в заголовке 2, который является пассивом, тогда он будет генерировать первое число как 201

для уровня 3;

если родительский выбран 101, то он сгенерирует первый номер a / c как 10101, если родительский выбран 102, то он сгенерирует первый номер a / c как 10201

и так далее….

для уровня 4:

если родительский элемент выбран 10101, он сгенерирует первый номер a / c как 10101001, если родительский элемент выбран 10201, он сгенерирует первый номер a / c как 10201001

и так далее…

и то же самое для всех остальных основных счетов (2 = Обязательства, 3 = Расходы, 4 = Доход, 5 = Капитал)

Пожалуйста, помогите.

Комментарии:

1. обновлено, чтобы проиллюстрировать как можно более четко.

Ответ №1:

Приведенный ниже запрос генерирует почти 4000 учетных записей, используя определенную вами структуру учетных записей. Вы можете настроить количество создаваемых счетов, изменив CONNECT BY LEVEL <= 5 и изменив 5 на меньшее или большее число в num_accts_to_generate .

Запрос

 WITH
    num_accts_to_generate
    AS
        (    SELECT LEVEL     AS gen_num
               FROM DUAL
         CONNECT BY LEVEL <= 5),
    level_1_accts
    AS
        (SELECT 1 AS account_level, 'Asset' AS account_type, TO_CHAR (gen_num) AS account_number
           FROM num_accts_to_generate),
    level_2_accts
    AS
        (SELECT 2                AS account_level,
                'Liability'      AS account_type,
                   l1.account_number
                || LPAD (ROW_NUMBER () OVER (PARTITION BY l1.account_number ORDER BY ROWNUM),
                         2,
                         '0')    AS account_number
           FROM level_1_accts l1, num_accts_to_generate),
    level_3_accts
    AS
        (SELECT 3                AS account_level,
                'Expense'        AS account_type,
                   l2.account_number
                || LPAD (ROW_NUMBER () OVER (PARTITION BY l2.account_number ORDER BY ROWNUM),
                         2,
                         '0')    AS account_number
           FROM level_2_accts l2, num_accts_to_generate),
    level_4_accts
    AS
        (SELECT 4                AS account_level,
                'Revenue'        AS account_type,
                   l3.account_number
                || LPAD (ROW_NUMBER () OVER (PARTITION BY l3.account_number ORDER BY ROWNUM),
                         3,
                         '0')    AS account_number
           FROM level_3_accts l3, num_accts_to_generate),
    level_5_accts
    AS
        (SELECT 5                AS account_level,
                'Capital'        AS account_type,
                   l4.account_number
                || LPAD (ROW_NUMBER () OVER (PARTITION BY l4.account_number ORDER BY ROWNUM),
                         3,
                         '0')    AS account_number
           FROM level_4_accts l4, num_accts_to_generate)
SELECT * FROM level_1_accts
UNION ALL
SELECT * FROM level_2_accts
UNION ALL
SELECT * FROM level_3_accts
UNION ALL
SELECT * FROM level_4_accts
UNION ALL
SELECT * FROM level_5_accts
ORDER BY 3;
  

Результат

    ACCOUNT_LEVEL    ACCOUNT_TYPE    ACCOUNT_NUMBER
________________ _______________ _________________
               1 Asset           1
               2 Liability       101
               3 Expense         10101
               4 Revenue         10101001
               5 Capital         10101001001
               5 Capital         10101001002
               5 Capital         10101001003
               5 Capital         10101001004
               5 Capital         10101001005
               4 Revenue         10101002
               5 Capital         10101002001
               5 Capital         10101002002
               5 Capital         10101002003
               5 Capital         10101002004
...

3,905 rows selected.
  

Ответ №2:

большое спасибо EJ Egyed за проявленный интерес к помощи, я написал ниже функцию, которая отлично работает для меня.

 create or replace function get_value_no( v_value_level in number,
                                         v_value_abbreviation in varchar2,
                                         v_value_parent in number)
 return number is
 --
 -- create trigger or function, in case of function pass following columns as parameters
 -- value_leve, value_abbreviation, value_parent_acct
 v_value_level number := 3;
 v_value_abbreviation char(1) := 'L'; -- (A)sset (L)iability (E)xpense (R)evenue (C)apital
 v_valno number;
 v_parent number := 203; -- parent account which user will select 
 v_char  varchar2(20);
begin

 -- ======================
 if v_value_level in (2, 3) then
   select max(nvl(value_no,0))
    into v_valno
    from value_set
   where value_level = v_value_level
    and value_abbreviation = v_value_abbreviation
    and value_type = 'NA'
    and value_parent_acct = v_value_parent;
   if v_valno is null or v_valno <= 0 then
    v_char := to_char(v_value_parent)||'01';
    v_valno := v_char;
   else
    v_valno := v_valno 1;
   end if;
 end if;
 -- ======================
 if v_value_level = 4 then
   select max(nvl(value_no,0))
    into v_valno
    from value_set
   where value_level = v_value_level
    and value_abbreviation = v_value_abbreviation
    and value_type = 'NA'
    and value_parent_acct = v_value_parent;
   if v_valno is null or v_valno <= 0 then
    v_char := to_char(v_value_parent)||'001';
    v_valno := v_char;
   else
    v_valno := v_valno 1;
   end if;
 end if;
 -- ======================
return v_valno;
-- 
end;